Hi folks,
Currently, it's not possible to use the ::class special constant with the
constant()
function. This doesn't work:
var_dump(
constant('\DateTime::class')
);
For instance, Twig's constant()
helper internally uses this PHP function,
consequently the following Twig template doesn't work:
myObject
contains a random object, retrieve its class:
{{ constant('class', myObject) }}
I wrote a patch adding support for ::class:
https://github.com/php/php-src/pull/6763
As this probably qualifies as a new feature, should I write an RFC too?
Cheers,
Hi Kévin,
My opinion is that you should write an RFC. I have to admit I was a little
confused when I initially read your email, because I never considered
::class to be a constant. It is a special constant, which is described as a
keyword in the manual. If I understand it correctly the value is obtained
either at compile-time or at runtime. I would certainly want to see more
explanation for your proposal with all edge cases listed out. Sounds
interesting and I am looking forward to more information.
Regards,
Kamil
Hi folks,
Currently, it's not possible to use the ::class special constant with
the
constant() function. This doesn't work:var_dump(
constant('\DateTime::class')
);
While this looks logical at first glance, I'm not sure this can actually work, because you are asking at runtime for information which only exists at compile time. This is similar to other "magic" constants such as LINE.
The only cases where ::class is calculated at runtime are self::class, and the recently added $obj::class, where $obj is an object instance. All other uses are expanded by the compiler based on the namespace and use statements in effect at that point in the code. If you try to calculate it at runtime, it would end up being evaluated where the call to constant()
happens, which wouldn't actually have those namespace and use directives in effect.
Consider this example:
namespace Acme\Foo {
use Some\Other\Baz;
function test(string $class) {
echo constant($class . '::class');
}
}
namespace Acme\Different {
use Acme\Bar\Baz as BarBaz;
echo Baz::class, PHP_EOL;
echo BarBaz::class, PHP_EOL;
echo test('Baz');
echo test('BarBaz');
}
Logically, the calls to test() should result in the same output as the direct use of "::class", but the call to constant()
is in a different namespace, with different use statements. I'm not sure if use statements are even available at runtime, but if they were, there would be no way of knowing that the context of the call to test() should be used, not the context where it's defined.
Regards,
Hi Kevin,
--
Rowan Tommins
[IMSoP]
Hi folks,
Currently, it's not possible to use the ::class special constant with the
constant()
function. This doesn't work:var_dump(
constant('\DateTime::class')
);For instance, Twig's
constant()
helper internally uses this PHP function,
consequently the following Twig template doesn't work:
myObject
contains a random object, retrieve its class:
{{ constant('class', myObject) }}I wrote a patch adding support for ::class:
https://github.com/php/php-src/pull/6763
As this probably qualifies as a new feature, should I write an RFC too?
I'm not a fan of this change. X::class is not a constant, it just happens
to share the same syntax. I think that
https://github.com/php/php-src/pull/6763#issuecomment-795046502 makes the
key point that if this is treated as a proper class constant in constant()
,
then it should also be treated as such everywhere else, including
reflection. And I really don't think we want to do that.
Regards,
Nikita