从类引用中获取类命名空间和名称,而不更改我的类

Posted

技术标签:

【中文标题】从类引用中获取类命名空间和名称,而不更改我的类【英文标题】:Get class namespace and name from class reference, without changing my classes 【发布时间】:2014-11-06 09:08:30 【问题描述】:

php 中你经常检查你得到的对象是否是正确的类型。如果不是,您会抛出异常并显示如下消息:

use My\Class\MyClass

...

if (!$object instanceof MyClass) 
    throw new Exception(
        sprintf(
            "object must be of type '%s'", 
            'My\Class\MyClass'
        )
    );

现在我将完整的命名空间和类名以字符串形式传递给sprintf

我怎样才能从类参考中得到这个,以便我可以做这样的事情

sprintf("object must be of type '%s'", MyClass::getName())

编辑:

我想在不添加新方法的情况下为所有类实现这一点。所以它应该是使用一些现有方法或 php __ MAGIC__ 方法之一的解决方案。

【问题讨论】:

从 php5.6 开始,您可以简单地使用 MyClass::class @Maerlyn 如果您将其作为答案发布,您将获得奖励:P 【参考方案1】:

从 php 5.5 开始,有一个魔术常量可以为您提供任何类的 FQCN。你可以这样使用它:

namespace My\Long\Namespace\Foo\Bar;

MyClass::class;
// will return "My\Long\Namespace\Foo\Bar\MyClass"

它记录在new features 页面上。

【讨论】:

酷。我的 phpstorm 也知道这个特性,它识别了变量:) 不过要小心:5.6 仍然非常新,几乎没有在野外使用。除非您推出自己的服务器,否则您能否使用它的新功能是值得怀疑的。【参考方案2】:
namespace test;

class a 

    public function getname()
    
        return __CLASS__;
    

还有:

$a = new a();
echo $a->getname(); // 

输出

test\a

静态方法的工作方式相同:

public static function getname()

    return __CLASS__;


...

a::getname(); // test\a

您也可以仅使用__NAMESPACE__ 获取命名空间

更新: 你可以ReflectionClass 做同样的事情:

$a = new a();

$r = new \ReflectionClass($a);
echo $r->getName(); // test\a

您可以创建ClassHelper 类,以便在您需要的任何地方轻松使用它:

class ClassHelper

    public static function getFullQualifiedName($object)
    
        $rc = new \ReflectionClass($object);
        return $rc->getName();
    

并使用它:

echo ClassHelper::getFullQualifiedName($a); // test\a

Finnaly:如果您使用 php 5.6 及更高版本(未来),您可以使用class 常量

echo a::class; // test\a

【讨论】:

是的,可以,但我不想在我的所有课程中添加 getName 方法。 感谢您的宝贵时间,但这些解决方案并不是我想要的。如果您看到@Maerlyn 他的评论,您会发现有一种更简单的方法。他给了我我想要的东西。 我也打算发布它,但是,首先发布我的答案,因为MyClass::class 仅适用于 php 5.6 及更高版本,但无论如何我也会包含它

以上是关于从类引用中获取类命名空间和名称,而不更改我的类的主要内容,如果未能解决你的问题,请参考以下文章

在C#中获取命名空间中的类列表[重复]

如何获取对象的非限定(短)类名?

TypeScript 从类 + 命名空间拆分接口

获取命名空间内的所有类[重复]

为啥我不能从不同命名空间中的朋友类更改类的私有成员?

实体框架生成的类不在我需要的命名空间中,有没有办法在不重新生成的情况下更改它使用的命名空间?