PHP 5.5: New Class Constant
Last week, the first stable version of PHP 5.5
was released. It introduced a class-level constant, aptly named
CLASS
, that is automatically available on all classes and holds the
fully-qualified name of that class.
1
2
3
4
5
6
7
8
9
|
<?php
namespace vendor\package ; class Foo { // ... } var_dump ( Foo :: CLASS ) ; |
The output of the script above is
string(18) "vendor\package\Foo"
.
Why would you need that?
So why would you need such a constant? Well, certainly not for what is
shown in the example above as you can achieve the same result using the
__NAMESPACE__
constant:
1
2
3
4
5
6
7
8
9
|
<?php
namespace vendor\package ; class Foo { // ... } var_dump ( __NAMESPACE__ . '\Foo' ) ; |
However, when you need the fully qualified name of a namespaced class that is referenced by a namespace alias ... then it gets interesting. A good use case is the usage of test doubles – stubs and mocks – in unit testing. A stub is an object that replaces another object for testing purposes. Methods can be configured to return certain values. A mock object also allows the definition of expectations.
In the example below we replace the dependency on the Bar
class
while testing the Foo
class. Thanks to the use
statement,
we can simply use Foo
(which is a namespace alias for
vendor\package\Foo
) to create an instance of the class we want to
test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
use vendor\package\Foo ; class FooTest extends PHPUnit_Framework_TestCase { public function testBarCanBeProcessed ( ) { $bar = $this -> getMock ( 'vendor\package\Bar' ) ; $foo = new Foo ; $foo -> process ( $bar ) ; // ... } } |
The stubbing and mocking functionality of PHPUnit uses PHP's
Reflection API internally. The
Reflection API's methods require fully-qualified class names and so we need
to pass 'vendor\package\Bar'
as an argument to PHPUnit's
getMock()
method. This is inconvenient and prone to errors.
Namespaced Classes: Convenient to Stub With PHP 5.5
Thanks to the constant that holds the fully-qualified name of a class, we
can now also leverage namespace aliases when using PHPUnit's
getMock()
method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
use vendor\package\Foo ; use vendor\package\Bar ; class FooTest extends PHPUnit_Framework_TestCase { public function testBarCanBeProcessed ( ) { $bar = $this -> getMock ( Bar :: CLASS ) ; $foo = new Foo ; $foo -> process ( $bar ) ; // ... } } |
This makes stubbing and mocking namespaced classes more convenient and less prone to errors.