Q:

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?

A:

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']);    

