
Despite its name, isset() not only returns false if an item does not exist, but also returns false for null values.This behaviour is more problematic than it might appear at first and is a common source of problems.
Consider the following example:
$data = fetchCategoryFromTable($storage, $identifier);
if (!isset($data[‘keyShouldBeSet’]) {
// do something here if ‘keyShouldBeSet’ is not set
}
The developer of this code presumably wanted to check if keyShouldBeSet was set in $data. But, as discussed, isset($data[‘keyShouldBeSet’]) will also return false if $data[‘keyShouldBeSet’]was set, but was set to null. So the above logic is flawed.
Here’s another example:
if ($_POST[‘active’]) {
$postData = extractSomething($_POST);
}if (!isset($postData)) {
echo ‘post not active’;
}
The above code assumes that if $_POST[‘active’] returns true, then postData will necessarily be set, and therefore isset($postData) will return true. So conversely, the above code assumes that the only way that isset($postData) will return false is if $_POST[‘active’] returned false as well.
Note.
As explained, isset($postData) will also return false if $postData was set to null. It therefore is possible for isset($postData) to return false even if $_POST[‘active’] returned true. So again, the above logic is flawed.
And by the way, as a side point, if the intent in the above code really was to again check if $_POST[‘active’] returned true, relying on isset() for this was a poor coding decision in any case. Instead, it would have been better to just recheck $_POST[‘active’]; i.e.:
if ($_POST[‘active’]) {
$postData = extractSomething($_POST);
}if ($_POST[‘active’]) {
echo ‘post not active’;
}
For cases, though, where it is important to check if a variable was really set (i.e., to distinguish between a variable that wasn’t set and a variable that was set to null), the array_key_exists() method is a much more robust solution.
For example, we could rewrite the first of the above two examples as follows:
$data = fetchCategoryFromTable($storage, $identifier);
if (! array_key_exists(‘keyShouldBeSet’, $data)) {
// do this if ‘keyShouldBeSet’ isn’t set
}
Moreover, by combining array_key_exists() with get_defined_vars(), we can reliably check whether a variable within the current scope has been set or not:
if (array_key_exists(‘varShouldBeSet’, get_defined_vars())) {
// variable $varShouldBeSet exists in current scope
}