Search code examples
phpnulldereference

Why is there no error in PHP if you try to use brackets to get the value of a key on a NULL?


I tried the following code in both facebook's phpsh and the standard crappy php -a abomination for a repl:

$a = NULL;
echo $a['foobar'];

To my regret (I wouldn't call it surprise or disappointment when it concerns PHP) I don't get any errors or warnings or exceptions or anything.

Smarter languages like Ruby and Python both complain when trying to dereference a key from eg None or nil. How is PHP interpreting this situation? Is the only cure inserting is_null checks everywhere? Should I blame Smarty for not doing it for me?


Solution

  • According to PHP source code (Zend/zend_execute.c), only strings, arrays and objects can trigger errors when accessing an offset/index. The rest is more-or-less ignored:

    $a = true;
    $b = false;
    $c = null;
    $d = 1;
    $e = 1.234;
    $f = '';
    $g = array();
    $h = new stdClass;
    
    echo $a[0]; // NULL
    echo $b[0]; // NULL
    echo $c[0]; // NULL
    echo $d[0]; // NULL
    echo $e[0]; // NULL
    echo $f[0]; // E_NOTICE: Uninitialized string offset
    echo $g[0]; // E_NOTICE: Undefined offset
    echo $h[0]; // E_FATAL:  Cannot use object as array
    

    None of $a,$b,$c,$d or $e actually spit an error. Most of the times in the code I just see return; or return 0;, which means NULL, instead of a returned zval* (pointer) or zend_error() call. Hence the results above.

    Whatever the reason why it has been done like this, it doesn't really matter. You should always check a variable for existence and/or nullity in such cases. The safest ways (slightly different behaviours) are isset and empty:

    isset($a['foo']);
    !empty($a['foo']);