PHP:如何从别名获取完全限定的类名?

11

在PHP中,如果我想获得使用use语句包含的类的完全限定类名,我该怎么做?例如,

<?php
namespace MyNamespace;

use Namespace\To\Class as MyClass;

function getNamespaceOfMyClass() {
    // Return ??
}

echo getNamespaceOfMyClass();

我知道一种方法是通过 get_class(new MyClass()) 来实现,但如果我不能或不想创建一个 MyClass 的实例,应该怎么办?谢谢!


你为什么要这样做? - AlexP
@AlexP:这样做有完全合理的原因。其中一个原因是当您想指示 DI 容器如何解析特定类型时。 - Jon
@Jon,我并没有说这个例子是无效的。我想了解更多信息,因为它是一个人为制造的例子。 - AlexP
@AlexP 我的具体用例在Zend Framework 2中,我们有一个EventManager,其事件附加到类的完全限定名称。我正在重构的代码看起来不太好——它使用诸如:use Account\Document\Profile; 然后: get_class(new Profile()); 来完成此工作,这不是理想的方式。我希望有一种普通的方法来做到这一点,最好不需要PHP 5.5。 - osdiab
@OmarDiab 我理解你的困境,当我尝试从 ObjectManager()->getEntityRepository($className) 调用实体时,我也遇到了同样的问题,因为我不想硬编码类名。我倾向于在实体服务层中定义一些静态变量(例如 static::ENTITY_CLASS_NAME_PROFILE = 'Namespace/entity/Profile';),然后使用它们。 - AlexP
2个回答

24

自PHP 5.5版本以后,您可以使用::class来实现这一点:

echo MyClass::class;

很遗憾,在早期版本中这是完全不可能的,您必须要么硬编码类名,要么先创建一个实例并在其上使用get_class


太棒了,我不知道这个!很遗憾早期版本没有这种方法,我会再等一段时间看看是否有其他诀窍。 - osdiab
如果我的类名是一个变量(字符串),我该怎么办?例如,($prefix . 'Class')::class 不起作用!感谢您的帮助。 - Roubi
@Roubi 如果你已经有一个类名字符串,那么它必须是完全限定的,否则你无法对其进行任何有用的操作。这个用例是什么? - Jon
这是用Symfony3动态创建表单的代码,但你让我意识到正确的方法可能是在字符串中“手动”添加命名空间。我只是好奇是否有一种懒惰的方式,但这是没有意义的。感谢您的时间。 - Roubi
@myol 第一行中的 ::class 是指链接,还是您在寻找其他内容? - Jon

5

在早期的PHP版本(即PHP < 5.5),您可以通过 Reflection API 获取类名,如下所示:

namespace App\Core;

use Symfony\Component\Form\Extension\Core\Type;

class MyClass {}

$refclass = new \ReflectionClass(new Type\DateType);
print $refclass->getName();
$refclass = new \ReflectionClass(new MyClass());
print $refclass->getName();

当然,如果这对您来说不算昂贵的话。
注意: 自 PHP 5.4 起:
$classname = (new \ReflectionClass(new Type\DateType))->getName();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接