| aharvey | Yes | 2012-09-12 03:38 |
| hradtke | Yes | 2012-09-11 18:42 |
| ircmaxell | Yes | 2012-09-11 14:37 |
| kriscraig | Yes | 2012-09-11 20:31 |
| levim | Yes | 2012-09-11 21:25 |
| lstrojny | Yes | 2012-09-11 17:17 |
| pajoye | Yes | 2012-09-13 07:39 |
| patrickallaert | No | 2012-09-11 15:40 |
| reeze | Yes | 2012-09-13 08:01 |
| sebastian | Yes | 2012-09-12 07:13 |
| seld | Yes | 2012-09-12 12:29 |
Copied from wiki.php.net, last synchronized Oct 13, 2026 11:52 UTC
This RFC proposes to add a new ClassName::class syntax, which provides the fully qualified class name as a string.
Class names in strings have to be fully qualified in PHP. It is not possible to utilize aliases registered through use statements:
use A\Namespaced\ClassName;
// this will try to create a mock of the global class ClassName, not
// of the aliased class A\Namespaced\ClassName
$mock = $this->getMock('ClassName');
ClassName::class allows the programmer to easily obtain the fully qualified class name from an aliased name:
use A\Namespaced\ClassName;
// ClassName::class resolves to 'A\Namespaced\ClassName'
$mock = $this->getMock(ClassName::class);
1. PHPUnit's Mocking
use MyVendor\SomeComponent\TargetSubNs;
// inside a test case
$this->getMock(TargetSubNs\Foo::class);
// as opposed to
$this->getMock('MyVendor\SomeComponent\TargetSubNs\Foo');
2. Doctrine
use MyVendor\SomeComponent\TargetEntityNs as Entity;
// inside a test case
$entityManager->find(Entity\User::class, 5);
// as opposed to
$entityManager->find('MyVendor\SomeComponent\TargetEntityNs\User', 5);
3. Any Real (auto-wiring || auto-instantiating) Dependency Injection Container
use MyVendor\SomeComponent\TargetNs as T;
// inside a test case
$dic->newInstance(T\Foo::class);
// as opposed to
$dic->newInstance('MyVendor\SomeComponent\TargetEntityNs\Foo');
4. General PHP Usage:
use MyVendor\SomeComponent\TargetNs as T;
// reflection
$r = new ReflectionClass(T\Foo::class); // instead of new ReflectionClass('MyVendor\SomeComponent\TargetNs\Foo');
// class_exists, also applies to any php function that takes a class name (is_subclass_of, get_class_methods, etc)
if (class_exists(T\Foo::class, true)) {} // instead of class_exists('MyVendor\SomeComponent\TargetNs\Foo')
The ClassName::class syntax was chosen because it can not clash with existing constants (as class is a keyword). The feature addition thus is fully backwards compatible.
Furthermore the syntax resembles the semantically equivalent Java syntax ClassName.class.
Note: since this feature reuses T_CLASS/class keyword, it is case-insensitive. Therefore, Foo::class is semantically equivalent to Foo::Class, Foo::CLASS and the like.
From the test for the feature:
--TEST--
class name as scalar from ::class keyword
--FILE--
<?php
namespace Foo\Bar {
class One {
// compile time constants
const A = self::class;
const B = Two::class;
}
class Two extends One {
public static function run() {
var_dump(self::class); // self compile time lookup
var_dump(static::class); // runtime lookup
var_dump(parent::class); // runtime lookup
var_dump(Baz::class); // default compile time lookup
}
}
class Three extends Two {
// compile time static lookups
public static function checkCompileTime(
$one = self::class,
$two = Baz::class,
$three = One::A,
$four = self::B
) {
var_dump($one, $two, $three, $four);
}
}
echo "In NS\n";
var_dump(Moo::CLASS); // resolve in namespace
}
namespace {
use Bee\Bop as Moo,
Foo\Bar\One;
echo "Top\n";
var_dump(One::class); // resolve from use
var_dump(Boo::class); // resolve in global namespace
var_dump(Moo::CLASS); // resolve from use as
var_dump(\Moo::Class); // resolve fully qualified
$class = One::class; // assign class as scalar to var
$x = new $class; // create new class from original scalar assignment
var_dump($x);
Foo\Bar\Two::run(); // resolve runtime lookups
echo "Parent\n";
Foo\Bar\Three::run(); // resolve runtime lookups with inheritance
echo "Compile Check\n";
Foo\Bar\Three::checkCompileTime();
}
?>
--EXPECTF--
In NS
string(11) "Foo\Bar\Moo"
Top
string(11) "Foo\Bar\One"
string(3) "Boo"
string(7) "Bee\Bop"
string(3) "Moo"
object(Foo\Bar\One)#1 (0) {
}
string(11) "Foo\Bar\Two"
string(11) "Foo\Bar\Two"
string(11) "Foo\Bar\One"
string(11) "Foo\Bar\Baz"
Parent
string(11) "Foo\Bar\Two"
string(13) "Foo\Bar\Three"
string(11) "Foo\Bar\One"
string(11) "Foo\Bar\Baz"
Compile Check
string(13) "Foo\Bar\Three"
string(11) "Foo\Bar\Baz"
string(11) "Foo\Bar\One"
string(11) "Foo\Bar\Two"
One situation in need of a solution is what to do with self::class, static::class, and parent::class
Do we:
Note: (as of 1/18/13)
In the current patch, the following resolutions take place:
* Pull Request located here: https://github.com/php/php-src/pull/187/files
Vote: Should the ::class feature be merged to master? — Yes: 10 · No: 1 (closed)
Note: This Vote has been closed as the RFC will be moved back to discussion at the time being while the RFC and associated patch become more mature.