相对命名空间和 call_user_func()

2022-01-14 00:00:00 namespaces php

代码胜于雄辩:

namespaces.php:

<?php

namespace foo;

use foomodels;

class factory
{
    public static function create($name)
    {
        /*
         * Note 1: FQN works!
         * return call_user_func("\foo\models\$name::getInstance");
         *
         * Note 2: direct instantiation of relative namespaces works!
         * return models	est::getInstance();
         */

        // Dynamic instantiation of relative namespaces fails: class 'models	est' not found
        return call_user_func("models\$name::getInstance");
    }
}

namespace foomodels;

class test
{
    public static $instance;

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    public function __construct()
    {
        var_dump($this);
    }
}

namespace_test.php:

<?php

require_once 'namespaces.php';

foofactory::create('test');

正如评论的那样,如果我在 call_user_func() 中使用全限定名称,它会按预期工作,但如果我使用相对命名空间,它会说找不到该类 –但直接实例化有效.我是否遗漏了某些东西或它的设计奇怪?

As commented, if I use the full-qualified name inside call_user_func() it works as expected, but if I use relative namespaces it says the class was not found – but direct instantiations works. Am I missing something or its weird by design?

推荐答案

你必须在回调中使用完全限定的类名.

You have to use the fully qualified classname in callbacks.

参见 示例 #3 call_user_func() 使用命名空间名称

See Example #3 call_user_func() using namespace name

<?php

namespace Foobar;

class Foo {
    static public function test() {
        print "Hello world!
";
    }
}

call_user_func(__NAMESPACE__ .'Foo::test'); // As of PHP 5.3.0
call_user_func(array(__NAMESPACE__ .'Foo', 'test')); // As of PHP 5.3.0

我相信这是因为 call_user_func 是来自全局范围的函数,也执行来自全局范围的回调.无论如何,请参见第一句话.

I believe this is because call_user_func is a function from the global scope, executing the callback from the global scope as well. In any case, see first sentence.

另请参阅上面的注释示例 #2 动态访问命名空间元素其中声明

Also see the note aboveExample #2 Dynamically accessing namespaced elements which states

必须使用完全限定名(带有命名空间前缀的类名).

One must use the fully qualified name (class name with namespace prefix).

相关文章