PHP动态确定完全限定的类名

时间:2016-11-03 19:07:25

标签: php namespaces

我发现通过使用::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'
    }
}

3 个答案:

答案 0 :(得分:0)

好的,我提出了另一个解决方案。即使这有些不同。

namespace NameSpace;
class Foo {
    public static function getFullName() {
        return __CLASS__;
    }
}

print Foo::getFullName(); // Prints NameSpace\Foo

只需创建一个抽象类,其中getFullName()作为方法,并在您希望能够返回全名的所有类上继承它。

最简单的approch(我差点忘了)是使用get_class()

$className = get_class($yourClassObject); // returns NameSpace\Foo

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

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

即便如此,这可能不是您想要的,但您应该查看Reflection库。它非常方便用于此类事物。

// 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

查看here了解更多信息 还有方法,属性等类。

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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