PHP 8.0: ::class magic constant is now supported on objects

Version8.0
TypeNew Feature

PHP has a magic constant ::class that resolves a class name to its fully-qualified class name. When used with a class name, use and use as statements will be resolved, or the current namespace will be prefixed which makes it a fully-qualified class name.

Example:


namespace App\Demos;

use Foo\Bar;
use Bar\Baz as BBaz;

class Demo {}

// `use` statement is resolved:
echo Bar::class; // "Foo\Bar"

// `use` X `as` Y is resolved:
echo BBaz::class; // "Bar\Baz"

// Current namespace is resolved:
echo Demo::class; // "App\Demos\Demo"

Until PHP 8.0, the ::class magic constant was not allowed on objects.

$object = new Foo\Bar();
echo $object::class;

// Fatal error: Cannot use ::class with dynamic class name.

With PHP 8.0, now you can use ::class constant on objects, and it will be correctly resolved at run time:

$object = new Foo\Bar();
echo $object::class;

// PHP 8.0+:
// "Foo\Bar"

Same result as get_class()

The ::class constant on an instantiated object will return the exact same return value as a get_class() call.

get_class($object) === $object::class;

Non-objects are not allowed

Using ::class on a non-object is not allowed:

$object = array();
$object::class;

// Fatal error: Uncaught TypeError: Cannot use ::class on value of type array in ...:...

If you need to get the type of any variable, PHP 8.0 comes with a new get_debug_type() function that you can call to get the class name, scalar types, resource type, etc all from one handy function.

Backwards compatibility impact

In PHP versions prior to 8.0, using ::class on an object triggers a fatal error. Because PHP 8.0 is relaxing this error, this should not create any new BC issues. However, this will make your code require PHP 8.0 to run without a way to polyfill this functionality to older versions.


RFC Externals.io discussion Implementation