命名空间用作变量时不起作用?

时间:2019-01-29 18:37:47

标签: php namespaces

<?php

namespace Vendor\Package;

$test1 = new Foo\Bar(); // works as usual

$test2 = 'Foo\Bar';
$test2 = new $test2(); // does not work

$test3 = 'Vendor\Package\Foo\Bar';
$test3 = new $test3(); // but this works

我原本打算使用$test2,但即使看起来应该使用它也没有用,因为它与工作的$test3几乎一样。

这是预期的吗?test2是否需要使用某些语法?

3 个答案:

答案 0 :(得分:5)

使用动态类名时,它必须完全合格。 documentation说:

  

必须使用标准名称(带有名称空间前缀的类名称)。请注意,由于动态类名称,函数名称或常量名称中的合格名称与完全限定名称之间没有区别,因此不需要使用反斜杠。

Foo\Bar并不完全合格,它与您在前面的Vendor\Package语句中选择的namespace相关。

答案 1 :(得分:2)

您可以使用__NAMESPACE__

作为前缀
Vendor\Package\Foo\Bar::__construct
Vendor\Package\Foo\Bar::__construct
Vendor\Package\Foo\Bar::__construct

Repl.it:https://repl.it/repls/BuzzingFairSuperuser

namespace Vendor\Package\Foo;
class Bar
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}

namespace Vendor\Package;

$test1 = new Foo\Bar(); // works

$test2 = __NAMESPACE__.'\Foo\Bar';
$test2 = new $test2(); // works

$test3 = 'Vendor\Package\Foo\Bar';
$test3 = new $test3(); // works

答案 2 :(得分:1)

所以我看看能否简单解释一下。在您的第一个实例“ $ test1 = new Foo \ Bar();”中,在编译/加载期间映射了模型的路径。在“ $ test2 ='Foo \ Bar'; $ test2 = new $ test2();”的情况下,您试图在运行时调用该模型...不幸的是,在运行时,链接已经完成,并且没有被重新审视。这意味着“ $ test2 ='\ Vendor \ Package \ Foo \ Bar'”应该可以正常工作,但是名称的缩写形式不起作用,因为在运行时不会重新访问链接步骤。