Types7 min readExamples run on PHP 8.5.10

get_debug_type()

Learn how PHP 8.4 get_debug_type() returns a type name suited to debugging and error messages, including class names, anonymous classes and how it differs from gettype().

Signature

get_debug_type(mixed $value): string

Purpose

get_debug_type() answers the question "what kind of value is this?" with a string you can put straight into a log line or an exception message. Its names match the ones you write in type declarations: int, float, bool, string, array and null. For objects it gives the class name instead of the vague word object.

It is a diagnostic helper. It tells you the type of a value at the moment you call it, and it is meant for people reading messages, not for driving program logic.

Signature

Parameters and defaults

  • $value: any value at all. There is only this one parameter and it has no default, so you must pass something. Because the type is mixed, no value is rejected.

Return value and failure cases

The function always returns a string. It does not return false, and the manual documents no error for ordinary values. The possible results are:

Value Result
null null
true or false bool
integer int
float float
string string
array array
open resource resource (name), for example resource (stream)
closed resource resource (closed)
object of a named class the full class name including namespace, such as Foo\Bar
object of an anonymous class class@anonymous, or ParentOrInterface@anonymous

For an anonymous class that extends a class or implements an interface, the name is based on the parent class or the first interface. A plain anonymous class with neither gives class@anonymous.

Example 1: Scalars, null and arrays

The names are the same ones you would use in a parameter type.

Example
<?php
$values = [null, true, 42, 3.14, "text", [1, 2]];
foreach ($values as $value) {
    echo get_debug_type($value), PHP_EOL;
}
Output
null
bool
int
float
string
array

Every value maps to a short, predictable name. Note that the array result carries no information about its contents, only the word array.

Example 2: Named and anonymous classes

Objects are reported by class name, which is the main advantage over gettype().

Example
<?php
interface Shape {}
class Circle implements Shape {}

$anonymousShape = new class implements Shape {};
$anonymousPlain = new class {};

echo get_debug_type(new Circle), PHP_EOL;
echo get_debug_type(new stdClass), PHP_EOL;
echo get_debug_type($anonymousShape), PHP_EOL;
echo get_debug_type($anonymousPlain), PHP_EOL;
Output
Circle
stdClass
Shape@anonymous
class@anonymous

The anonymous class that implements Shape is reported as Shape@anonymous, so you still get a hint about what it is. If a class lives in a namespace, the result includes the namespace prefix, such as Foo\Bar.

Example 3: Comparing with gettype()

The older gettype() returns historical names. Putting both side by side shows the difference.

Example
<?php
$values = [1, 1.5, false, null, new ArrayObject()];
$pairs = [];
foreach ($values as $value) {
    $pairs[] = [gettype($value), get_debug_type($value)];
}
echo json_encode($pairs), PHP_EOL;
Output
[["integer","int"],["double","float"],["boolean","bool"],["NULL","null"],["object","ArrayObject"]]

gettype() says integer, double, boolean and NULL, and it says object for every object. get_debug_type() says int, float, bool, null and the real class name.

Edge cases

  • Resources: an open stream reports resource (stream). After it is closed with fclose(), the same variable reports resource (closed). These examples are not run here because they need a stream.
  • Closures and enums: these are objects, so you get their class name (a closure gives Closure, an enum case gives the enum's name).
  • Numeric strings: the string "42" is still a string. The function looks at the actual type and never converts.
  • Anonymous classes: the @anonymous suffix is part of the result, so do not compare against a bare parent class name.

Common mistakes

  1. Using the result for branching. Prefer is_int(), instanceof and similar checks. Strings such as Shape@anonymous make poor conditions.
  2. Expecting gettype() names. Code that compares against "integer" or "double" will never match, because this function returns int and float.
  3. Expecting the inner type of an array. array is all you get. Inspect the elements yourself if you need more.
  4. Assuming anonymous classes are unique. Two different anonymous classes with the same parent produce the same string.
  5. Forgetting the namespace. For a class in a namespace, comparing the result against a short name fails. Use Foo\Bar::class for the comparison.

Practical use

The most common use is building error text such as "expected string, got int". Calling get_debug_type($value) inside such a message gives a precise, readable description without extra code for each type.

  • gettype() returns the older, historical type name.
  • get_class() returns the class name of an object, but is only meant for objects.
  • is_int(), is_string() and the other is_* functions test for one specific type.

Recap

get_debug_type() takes one mixed value and returns a string that uses the same names as type declarations. Objects are reported by their class name, anonymous classes get an @anonymous suffix, and resources show their resource type or closed. Use it for messages and logs, and use the is_* functions or instanceof for real decisions.

Tested examples

Scalars, null and arrays
<?php
$values = [null, true, 42, 3.14, "text", [1, 2]];
foreach ($values as $value) {
    echo get_debug_type($value), PHP_EOL;
}
Output
null
bool
int
float
string
array
Named and anonymous classes
<?php
interface Shape {}
class Circle implements Shape {}

$anonymousShape = new class implements Shape {};
$anonymousPlain = new class {};

echo get_debug_type(new Circle), PHP_EOL;
echo get_debug_type(new stdClass), PHP_EOL;
echo get_debug_type($anonymousShape), PHP_EOL;
echo get_debug_type($anonymousPlain), PHP_EOL;
Output
Circle
stdClass
Shape@anonymous
class@anonymous
Comparing with gettype()
<?php
$values = [1, 1.5, false, null, new ArrayObject()];
$pairs = [];
foreach ($values as $value) {
    $pairs[] = [gettype($value), get_debug_type($value)];
}
echo json_encode($pairs), PHP_EOL;
Output
[["integer","int"],["double","float"],["boolean","bool"],["NULL","null"],["object","ArrayObject"]]