isset() vs. array_key_exists()
For most of my PHP career, I’ve used isset()
to determine if an array has a certain key.
$foo = array();
echo isset($foo['bar']) ? 'set' : 'not set'; // Prints: not set
isset()
is nice because you can also use it on regular variables and object properties.
unset($foo);
echo isset($foo) ? 'set' : 'not set'; // Prints: not set
$foo = new StdClass();
echo isset($foo->bar) ? 'set' : 'not set'; // Prints: not set
Somewhere along the way I learned that there was an array_key_exists()
function, but by that time typing isset()
was already muscle memory. I never bothered with array_key_exists()
until recently when I ran across a situation where I actually needed it. I wanted to build a REST service with the following PUT (edit/update) behavior:
- If you include a key and set it to a value, the key is updated with the value.
- If you include a key and set it to null, the key is updated and its value is set to null.
- If you PUT some JSON and you omit a key, that key is ignored and no update is made to that key.
The first two points are pretty obvious, but the third one is not. You could argue that this behavior isn’t very RESTful, but it prevents sending chunks of redundant data over a mobile link.
Anyway, back to isset()
and array_key_exists()
. Despite its name, isset()
actually checks to see if the argument is set and is not null. So if you have an array with a key whose value is null, calling isset()
on that key will return false
.
$foo = array(
'bar' => null,
);
// Prints: "not set" because $foo['bar'] is null
echo isset($foo['bar']) ? 'set' : 'not set';
In my service, I couldn’t tell the difference between the second and third use cases — the client setting a key to null vs. omitting the key entirely. The solution was to use array_key_exists()
which only checks to see if the array has the key.
$foo = array(
'bar' => null,
);
// Prints: "exists" because $foo['bar'] exists, even if it is null
echo array_key_exists('bar', $foo) ? 'exists' : 'does not exist';
Performance Considerations
I came across a blog post this morning talking about the performance of isset()
vs. array_key_exists()
. (That’s what reminded me to write this blog post, actually.) The takeaway is that isset()
is actually faster than array_key_exists()
because isset()
is actually a language construct, not a function, so it doesn’t incur the function call overhead. But both are quite fast, so you probably shouldn’t choose one over the other for performance reasons.