动态确定完全限定的类名


PHP Dynamically determine fully qualified class name

我发现,通过使用::class,我可以获得名称空间类的完全限定类名:

namespace NameSpace {
    class Foo { }
    echo Foo::class;
}
// echoes 'NameSpace'Foo'

但是我不能想出一个方法来做这个变量类名。试图将class关键字视为静态属性似乎不起作用:

namespace NameSpace {
    class Foo { }
    $className = 'Foo';
    echo $className::class;
}
// Parse error: syntax error, unexpected 'class'

有没有人知道是否有可能像我一样动态地获得完全合格的类名?


我希望能够从当前命名空间之外的类做到这一点:

namespace ReallyLongHardToWriteNameSpace {
    class Foo { }
}
namespace NameSpace {
    use ReallyLongHardToWriteNameSpace'Foo;
    class Bar { }
    echo Foo::class; // echoes 'ReallyLongHardToWriteNameSpace'Foo'
    echo Bar::class; // echoes 'NameSpace'Bar'
    foreach (['Foo', 'Bar'] as $className) {
        echo $className::class; // Parse error: syntax error, unexpected 'class'
    }
}

可以将get_class与该类的实例一起使用:

<?php
namespace NS {
    class Foo { }
    $className = "''NS''Foo";
    echo get_class(new $className);
}
// prints NS'Foo

请注意,要创建类的实例,我必须在字符串中使用FQN,所以它可能根本没有用。

好吧,我想到了另一个解决方案。尽管这有点不同。

namespace NameSpace;
class Foo {
    public static function getFullName() {
        return __CLASS__;
    }
}
print Foo::getFullName(); // Prints NameSpace'Foo

只要创建一个抽象类,它有getFullName()作为方法,并从它继承所有的类,你想要能够返回全名。


最简单的方法(我差点忘了)是使用get_class()
$className = get_class($yourClassObject); // returns NameSpace'Foo

你也可以尝试使用eval()。

$className = 'NameSpace'Foo::class';
eval('$fullName = ' . $className);
print $fullName; // returns NameSpace'Foo

尽管,这可能不是你想要的,但你应该看看反射库。

// Lets say you have an object of your class
$object = new ReflectionObject($yourObject);
$name = $object->getName(); // will return NameSpace'Foo
// You can also give the class name to it
$class = new ReflectionClass('Foo');
$name = $class->getName(); // also returns NameSpace'Foo

点击这里查看更多信息还有用于方法、属性等的类

您可以使用__NAMESPACE__来获取当前名称空间,然后将其添加到包含类名的字符串中。

namespace NS {
    class Foo {
    }
    $className = 'Foo';
    echo __NAMESPACE__ . '''' . $className;
}