Recently igorw wrote a blog post on how to traverse nested array structures with potentially non-existing keys without throwing notices. The current “idiomatic” way to do something like this, is to use isset()
together with a ternary operator:
$age = (isset($data['people'][0]['age'])) ? $data['people'][0]['age'] : null;
The suggested alternative is a get_in
function, which is used as follows:
$age = get_in($data, ['people', 0, 'age'], $someDefault);
Someone on /r/PHP pointed out that there is an alternative approach to this problem, namely the use of an ifsetor
function:
function ifsetor(&$value, $default = null) {
return isset($value) ? $value : $default;
}
The use of this function is very elegant:
$age = ifsetor($data['people'][0]['age'], $someDefault);
Note that this function will not throw a notice if $data['people'][0]['age']
(or any index in between) does not exist, because the $value
is passed by-reference.
By-reference argument passing
This seems to come as a surprise to most people, because the code definitely looks like it accesses an undefined index and ought to throw a notice. Here the magic of references comes in: If you perform a by-reference argument pass (or assign) PHP will be using a different fetch type for retrieving the array offsets. In this particular case it would issue a number of “dim w” (dimension write) fetches.
A write-fetch obviously doesn’t throw a notice if the assigned index doesn’t exist yet (otherwise you wouldn’t be able to create indexes without throwing notices). What’s interesting is that the whole thing also work recursively, so none of the indices in the chain have to exist:
$array[0][1][2] = 'foobar';
The above example will not throw a notice if $array[0][1]
doesn’t exist, it won’t throw a notice if $array[0]
doesn’t exist and it even won’t throw a notice if the $array
variable itself doesn’t exist.
PHP implements write-fetches by creating the respective offset and initializing it to null
(if it doesn’t yet exist). This is compatible with nested ind
Truncated by Planet PHP, read more at the original (another 20867 bytes)
more
{ 0 comments... » The case against the ifsetor function read them below or add one }
Post a Comment