Nefunkční array_key_exists nad ArrayHash
- Oli
- Člen | 1215
Narazil jsem na zajímavou chybu (?) se kterou jsem se asi 30 minut pral. Pokud mám ArrayHash a chci se zeptat jestli tam je nějaký klíč, tak to vrátí vždy FALSE.
$test = [
0 => 'Tohle',
1 => 'je',
2 => 'zoufalost'
];
dump(array_key_exists(1, $test)); // return TRUE
dump(array_key_exists(1, ArrayHash::from($test))); // return FALSE
dump(array_key_exists(1, (array) ArrayHash::from($test))); // return FALSE
Je to tak správně? Případně proč? A proč, když to přemapuju na pole, tak to stejně vrací FALSE? Díky.
- Michal Hlávka
- Člen | 190
Použíj isset()
nebo metodu v ArrayHash
offsetExists()
var_dump(ArrayHash::from($test)->offsetExists(1));
Editoval emptywall (1. 9. 2016 16:51)
- Oli
- Člen | 1215
CZechBoY napsal(a):
Ty totiz nepretypujes objekt na pole ale vlozis objekt do pole jako jediny prvek.
Pokud to je tak, tak potom Tracy to nevrací správně. Protože, když si to dumptu, tak to vrátí normálně pole. Správně by to teda mělo vrátit pole v poli, ne?
emptywall napsal(a):
Použíj
isset()
nebo metodu v ArrayHashoffsetExists()
var_dump(ArrayHash::from($test)->offsetExists(1));
Je možný, že to někde napsaný je, jen o tom nevím, ale přišlo mě to
právě zvláštní, protože to normálně můžeš iterovat ve foreach,
můžeš k prvku přistoupit jako $test[1];
, ale
array_key_exists
to nenajde :-)
Šlo o data z formuláře, takže jsem to nakonec vyřešil jednoduše (jak
jsem zjistil v čem je problém). Prostě jsem si předal pole
$form->getValues(TRUE);
.
Díky, offsetExists
jsem neznal.
- artemevsin
- Člen | 61
Celkem mě to zaujalo, tak jsem zkusil malý test a vypadá to, že array_key_exists nefunguje jen s číselným klíčem. Pokud je klíč stringem, tak to funguje správně. Platí však toto:
Additionally the following key casts will occur:
Strings containing valid integers will be cast to the integer type. E.g. the key „8“ will >actually be stored under 8. On the other hand „08“ will not be cast, as it isn't a valid >decimal integer.
Floats are also cast to integers, which means that the fractional part will be truncated. E.g. >the key 8.7 will actually be stored under 8.
Bools are cast to integers, too, i.e. the key true will actually be stored under 1 and the key >false under 0.
Null will be cast to the empty string, i.e. the key null will actually be stored under "".
Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset >type.
<?php
$test = [
0 => 'Tohle',
1 => 'je',
'c' => 'zoufalost',
'2' => 'velká'
];
$objA = new ArrayHash();
$objB = new \stdClass();
foreach ($test as $key => $value) {
$objA->$key = $value;
$objB->$key = $value;
}
$resA1 = array_key_exists(0, $objA); // return FALSE
$resA2 = array_key_exists(1, $objA); // return FALSE
$resA3 = array_key_exists('c', $objA); // return TRUE
$resA4 = array_key_exists('2', $objA); // return FALSE
$resA5 = array_key_exists(2, $objA); // return FALSE
$resB1 = array_key_exists(0, $objB); // return FALSE
$resB2 = array_key_exists(1, $objB); // return FALSE
$resB3 = array_key_exists('c', $objB); // return TRUE
$resB4 = array_key_exists('2', $objB); // return FALSE
$resB5 = array_key_exists(2, $objB); // return FALSE
$resC1 = array_key_exists(0, ArrayHash::from($test)); // return FALSE
$resC2 = array_key_exists(1, ArrayHash::from($test)); // return FALSE
$resC3 = array_key_exists('c', ArrayHash::from($test)); // return TRUE
$resC4 = array_key_exists('2', ArrayHash::from($test)); // return FALSE
$resC5 = array_key_exists(2, ArrayHash::from($test)); // return FALSE
?>
- David Grudl
- Nette Core | 8239
To je bohužel problém přímo v jádru PHP, pokud klíče pole obsahují čísla, je lepší se vyhnout přetypovávání na objekty, jako je stdClass nebo ArrayHash.