我无法从使用字符串变量和 PHP 5.3 定义的类中获取常量。命名空间。示例:
use \Some\Foo\Bar;
$class = 'Bar';
echo $class::LOCATION;
其中 LOCATION 是一个正确定义的常量。我收到的错误表明类 Bar 未定义。
如果我这样做
$class = "\Some\Foo\Bar";
一切正常。
有什么办法可以让第一个例子起作用吗?
使用
$class::CONST
获取类常量,要求 $class
包含独立于当前命名空间的完全限定类名。
use
语句在这里没有帮助,即使您位于命名空间\Some\Foo
中,以下内容也不起作用:
namespace \Some\Foo;
$class = 'Bar';
echo $class::LOCATION;
正如您在问题中所写的那样,您通过提供完全限定的类名找到了“解决方案”:
use \Some\Foo\Bar;
$class = "\Some\Foo\Bar";
echo $class::LOCATION;
但是,你不喜欢这个。我不知道你的具体问题,但总的来说看起来不错。如果您想在当前命名空间内解析
Bar
的完全限定类名,您只需实例化它的一个对象并访问常量即可:
use \Some\Foo\Bar;
$class = new Bar;
echo $class::LOCATION;
在这个阶段,你甚至不需要关心你在哪个命名空间中。
但是,如果您出于某种原因需要在全局命名空间中拥有一个名为
Bar
的类,则可以使用 class_alias
来使其工作。使用它代替 use \Some\Foo\Bar
以获得您想要的行为:
class_alias('\Some\Foo\Bar', 'Bar');
$class = 'Bar';
echo $class::LOCATION;
但无论如何,我可能不会明白你的问题,因为你已经拥有的解决方案对我来说看起来不错。也许你可以写下你的具体问题是什么。
当您使用变量引用类名(如
$class::MYCONSTANT
或 $class::myStaticMethod()
中所示)时,PHP 假定您已给出完全限定名称,即类的绝对路径。就你而言,它是\Bar::LOCATION
。 (这里开头的反斜杠是可选的,实际上它已被弃用。)由 use
关键字定义的别名将被忽略。因此,您会得到 \Bar
类未定义的错误。
::class
表示法(在 PHP 5.5 中引入)会将别名解析为完全限定名称,因此 Bar::class
将解析为 Some\Foo\Bar
,包括命名空间:
use Some\Foo\Bar;
$class = "Some\Foo\Bar";
// is the same as
$class = Bar::class;
echo $class::LOCATION;
::class
表示法不仅适用于类名。短语 static::class
代表由 get_called_class()
给出的“后期静态绑定”类名。此外,如果类名在编译时不存在,它会默默地解析为当前命名空间:static::NonExistent
与__NAMESPACE__ . '\NonExistent'
相同(或者当不在命名空间中时简单地为'NonExistent'
)。后者也可能被误用来定义当前命名空间内的常量:
namespace Foo;
define (ANGLE_10_PERCENT::class, 180*asin(0.1)/M_PI);
// is the same as
define ('Foo\ANGLE_10_PERCENT', 180*asin(0.1)/M_PI);
// which is approximately
const ANGLE_10_PERCENT= 11.5;