PHP 5.5 Classname Resolution

2020-03-15 06:13发布

问题:

PHP 5.5 has implemented as a new feature a new way to retrieve the classname through the syntax ::class:

<?php

namespace Testing;

class Test{}

echo Test::class; // Testing\Test;

This works perfectly, alright? BUt what me and some other friends wanted to know is why this syntax also returns a classname when used alongside an undeclared class. E.g.:

<?php

echo UndeclaredClass::class; // UndeclaredClass

In several other cases an error is raised, but not here. Anyone know, with concrete basis if possible, why does this happen?

Does it have anything to Late Static Bindings or it's just a (temporary) limitation/bug of this brand new feature?

回答1:

Finally an official answer... relatively speaking. It was presented to me by someone identified by requinix@php.net in a bu report i created today. The only exception is about how involved with PHP development this person is.

TL;DR

PHP doesn't need ot know the definition of a class to get its fully-qualified name. All the required informations are available in compile-time so it doesn't need to load it.

Director's Cut

Namespaces like the uses are resolved in compile-time, i.e., when the file is compiled before its execution. That's why there are strict requirements in order to use them.

Because of all of those requirements, when PHP encounters a class name it can immediately know its fully-qualified name. Thinking of it as a filesystem the namespace would be a directory for relative locations and the use would be symlinks.

The class name is either absolute ("\Testing\Test") or relative ("Test"), and if relative it could be a normal name. [more context required]

namespace Testing {
    echo Test::class; // \Testing + Test = \Testing\Test
}

Or an alias:

use Testing\Test as AliasedTest;
echo AliasedTest::class; // AliasedTest + use = \Testing\Test

Without all of this autoloading wouldn't work!

::class is just a new tool to expose information PHP has always known.

This "extended answer" is pretty much the same of what I received as bug report. The reason of so much apparent copy & paste is because, originally, I built up this answer for another Stack Overflow Community



回答2:

You can use get_class function get the class name with the namespace. It will be the good to use it. Here is the code which you can try this code:

<?php
namespace Testing;

class Test{
    public function abc()
    {
        echo "This is the ABC.";
    }
}

namespace Testing1;

class Test{
    public function abc()
    {
        echo "This is the ABC.";
    }
}
// echo Test::class; // Testing\Test;
$test =  new Test();

print_r(get_class($test));
// echo "<br>";
// echo UndeclaredClass::class;
?>