Для меня фрагмент # 1 скорее разбит, а не № 2. Вы получаете доступ к элементу, который не существует, и код # 2 дает вам именно то, что можно ожидать: предупреждение. Причина, по которой # 1 вроде "работает", заключается в причуде или двух причудах php. Во-первых, когда вы применяете оператор [] = для нуля, этот нуль «волшебным образом» превращается в массив - без единого слова предупреждения от интерпретатора.
$a = null;
$a[1] = 'foo'; // "works"
print_r($a);
Во-вторых, это (умышленно или нет) не относится к пустым значениям, возвращаемым из __get или offsetGet.
class foo {
function __get($s) { return null; }
}
$a = new foo;
$a->x[1] = 'foo'; // error
print_r($a);
в сообщении об ошибке написано «Косвенное изменение перегруженного свойства», и, что бы это ни значило, это хорошая вещь - вам не разрешено изменять нулевое значение любым способом.