I’m cleaning up a lot of PHP code and always program with PHP error_reporting set to E_ALL and display_errors turned on so that I make sure to catch any PHP messages that come up. Since starting on this site, I have fixed literally hundreds (maybe thousands) of PHP Notices about using uninitialized variables and non-existent array indexes.
I have been fixing problems like this where $somevar is sometimes undefined:
by changing it to:
if (isset($somevar) && $somevar)
This successfully gets rid of the NOTICEs, but adds some overhead because PHP has to perform two checks. After fixing a lot of this in this manner, I’ve noticed that the pages seem to be generated a little slower.
So, to provide some conclusive results to myself, I wrote up a quick benchmarking script – available at php_empty_benchmark.php. It goes through 1,000,000 tests using each of these methods:
- if ($a) – This generates a notice if $a is not set
- if (isset($a)) – A simple clean way to check if the variable is set (note that it is not equivalent to the one above)
- if (isset($a) && ($a) – The one that I have been using which is equivalent to if($a), but doesn’t generate a notice.
- if (!empty($a)) – This is functionally equivalent to if($a), but doesn’t generate a notice.
It measures the time to perform 1 million tests using a defined percentage of values that are set. It then computes the difference as a percentage of the time taken for the original test (the one that generates the notices). A ‘diff’ of 100 means that the execution time is the same, greater than 100 means that it is faster, and less than 100 means that it is slower. A typical test produced these results:
With NOTICE: 0.19779300689697 With isset: 0.19768500328064 / Diff: 100.05463419811 With both: 0.21704912185669 / Diff: 91.128222590815 with !empty: 0.19779801368713 / Diff: 99.997468735875
In summary, using the if (isset($a) && $a) syntax is about 8-10% slower than generating the PHP Notice. Using !empty() should be a drop-in replacement that doesn’t generate the notice and has virtually no performance impact. Using ifset() also has no performance impact, but is not exactly the same as ‘if($a)’ since isset() will return true if the variable is set to a false value. I included it here, because it often make the code a little more readable than the !empty($a) syntax. For example:
$myvalue = !empty($_REQUEST['myvalue']) ? $_REQUEST['myvalue'] : '';
$myvalue = isset($_REQUEST['myvalue']) ? $_REQUEST['myvalue'] : '';