Signature
is_object(mixed $value): boolPurpose
is_object() answers one question: does this value hold an object? It returns a boolean and never changes its argument. Use it when a value may come from loosely typed input, such as decoded JSON, a mixed-type array, or a legacy API, and your next step depends on it being an object.
Signature
Parameters and defaults
$valueis the only parameter. It accepts any PHP value and has no default. You must pass exactly one argument.
Because the parameter is mixed, the function does not throw a TypeError for unexpected types. Passing null, an integer, an array or a string simply gives false.
Return value and failure cases
The function returns true when the value is an object and false for every other type. It has no error return, emits no warnings, and does not check what class the object belongs to. An instance of a built-in class, a user class, a closure, an enum case or a generator all count as objects.
The manual's changelog notes one historical detail: since PHP 7.2.0, an unserialized object whose class definition is missing (class __PHP_Incomplete_Class) gives true. Before that it gave false.
Example 1: Comparing common types
This loop checks several kinds of value. Only the stdClass instance and the arrow function are objects, because an arrow function is a Closure instance.
$values = [
'null' => null,
'int' => 42,
'array' => ['a' => 1],
'string' => 'hello',
'stdClass' => new stdClass(),
'closure' => fn(int $x): int => $x + 1,
];
$result = [];
foreach ($values as $label => $value) {
$result[$label] = is_object($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"null":false,"int":false,"array":false,"string":false,"stdClass":true,"closure":true}
Example 2: Guarding property access
A common use is a guard before reading a property. The helper below returns -1 when it receives something other than an object, and otherwise counts the students on it.
function studentCount(mixed $value): int
{
if (!is_object($value)) {
return -1;
}
return count($value->students ?? []);
}
$team = new stdClass();
$team->students = ['Kalle', 'Ross', 'Felipe'];
echo json_encode([studentCount(null), studentCount(['students' => [1]]), studentCount($team)]), PHP_EOL;[-1,-1,3]
Note that an array with a students key is rejected. Array keys and object properties are different things, even though they look similar in data.
Example 3: Edge cases
Some results surprise newcomers. Enum cases and generators are objects. JSON decoded without the associative flag yields an object, while the flag yields an array. A string that happens to be a class name is only a string. Casting changes the type, so (array) removes objectness and (object) adds it.
enum Suit { case Hearts; }
function gen() { yield 1; }
$decoded = json_decode('{"name":"Ada"}');
$assoc = json_decode('{"name":"Ada"}', true);
$incomplete = unserialize('O:7:"Missing":0:{}');
$checks = [
'enum case' => is_object(Suit::Hearts),
'generator' => is_object(gen()),
'json object' => is_object($decoded),
'json assoc' => is_object($assoc),
'class name string' => is_object('stdClass'),
'cast array' => is_object((array) $decoded),
'cast object' => is_object((object) ['a' => 1]),
'incomplete' => is_object($incomplete),
];
echo json_encode($checks), PHP_EOL;{"enum case":true,"generator":true,"json object":true,"json assoc":false,"class name string":false,"cast array":false,"cast object":true,"incomplete":true}
The last entry shows the incomplete-class case: the class Missing is not defined, yet the value is still an object.
Edge cases to remember
is_object()says nothing about the class. If you need a specific type, useinstanceof, which also covers parent classes and interfaces.- Closures, enum cases, generators and
DateTimeinstances all returntrue. - A class name stored in a string returns
false. Useclass_exists()to ask about a class name, not an instance. - Objects that implement
ArrayAccessorTraversableare still objects, not arrays, sois_array()returnsfalsefor them.
Common mistakes
- Treating a class name as an object.
is_object('Foo')isfalse, because the value is a string. - Assuming decoded JSON is always an object. The second argument of
json_decode()controls whether you get arrays or objects. Check the shape you actually have. - Using it instead of
instanceof. A bareis_object()check does not prove that a method or property exists. It only proves some object is present. - Forgetting that null is not an object. A missing optional dependency is
null, so anis_object()check handles it, but anullproperty access without a check will raise a warning. - Expecting casts to preserve type. After
(array) $objyou have an array, so object checks fail.
Related functions
is_array()tests for arrays.is_string()tests for strings, which is what class names are.is_bool(),is_int()andis_float()test the other scalar types.get_debug_type()returns a readable type name when you need more than a yes or no answer.instanceofchecks a specific class or interface.
Recap
is_object(mixed $value): bool returns true for any object instance, including closures, enum cases, generators and incomplete classes, and false for everything else. It never throws, and it does not identify the class. Pair it with instanceof when you need a specific type, and remember that class-name strings and arrays are not objects.
Tested examples
$values = [
'null' => null,
'int' => 42,
'array' => ['a' => 1],
'string' => 'hello',
'stdClass' => new stdClass(),
'closure' => fn(int $x): int => $x + 1,
];
$result = [];
foreach ($values as $label => $value) {
$result[$label] = is_object($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"null":false,"int":false,"array":false,"string":false,"stdClass":true,"closure":true}
function studentCount(mixed $value): int
{
if (!is_object($value)) {
return -1;
}
return count($value->students ?? []);
}
$team = new stdClass();
$team->students = ['Kalle', 'Ross', 'Felipe'];
echo json_encode([studentCount(null), studentCount(['students' => [1]]), studentCount($team)]), PHP_EOL;[-1,-1,3]
enum Suit { case Hearts; }
function gen() { yield 1; }
$decoded = json_decode('{"name":"Ada"}');
$assoc = json_decode('{"name":"Ada"}', true);
$incomplete = unserialize('O:7:"Missing":0:{}');
$checks = [
'enum case' => is_object(Suit::Hearts),
'generator' => is_object(gen()),
'json object' => is_object($decoded),
'json assoc' => is_object($assoc),
'class name string' => is_object('stdClass'),
'cast array' => is_object((array) $decoded),
'cast object' => is_object((object) ['a' => 1]),
'incomplete' => is_object($incomplete),
];
echo json_encode($checks), PHP_EOL;{"enum case":true,"generator":true,"json object":true,"json assoc":false,"class name string":false,"cast array":false,"cast object":true,"incomplete":true}