isset() And The Fatal Error

<?php

$a = [];
$a['b']['c']['d'] = 1;
$a['b']['c']['d2'] = new stdclass();
$a['b']['c']['d3'] = [];

var_dump(isset($a['b']['c']['d'])); // as expected, and within type
var_dump(isset($a['b']['c']['f'])); // as expected, and within type

var_dump(isset($a['b']['c']['d']['g']));   // as expected, because 'd' is 1
var_dump(isset($a['b']['c']['d']->g));     // as expected, because 'd' is 1

var_dump(isset($a['b']['c']['d3']->f));    // as expected, because 'd' is an array
var_dump(isset($a['b']['c']['d3']['f']));  // as expected, because 'd' is an array

var_dump(isset($a['b']['c']['d2']->f));   // as expected, because 'd' is an object
var_dump(isset($a['b']['c']['d2']['f']));   // fatal error!!

var_dump(isset($a['b']['c']['D']['g']->f));   // as expected, because 'D' is actually null
var_dump(isset($a['b']['c']['D']['g']['f'])); // as expected, because 'D' is actually null

// isset($a['b']['c']['d']) is set so following are true and within type
var_dump(isset($a['b']['c']));
var_dump(isset($a['b']));

$i = 1;
echo $i[3]; // error,

isset() checks if a variable exists. By extension, it also checks array elements, object properties etc. As the check is performed, any attempt to access an undefined part of the expression is muted: this makes total sense.

For example, if one of the intermediate expression is an integer, it is not possible to access it with an array syntax, unlike an array or a string. Such access is a warning when used outside isset(), but is silent inside the isset().

This leads to a nice optimisation, where checking isset($a[1][2][3][4]) is sufficient to check isset($a), then isset($a[1]), isset($a[1][2]), isset($a[1][2][3]), and isset($a[1][2][3][4]). Nice.

The catch is when of the element inside the actual array is an object. PHP reports a fatal error when using an object with an array syntax (except may be for ArrayAccess objects). Then, isset() stops.

The reverse is not true: accessing an array with a object syntax yields a null and no warning. As it should be.

All this also applies to empty().

A change of behavior was suggested for PHP 8.5, but was down voted. May be in PHP 8.6?

See Also

PHP Error Messages

PHP Features

Last updated: 14 July 2026