Relative namespaces and call_user_func ()

The code speaks better than the words:

namespaces.php:

<?php

namespace foo;

use foo\models;

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\test::getInstance();
         */

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

namespace foo\models;

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';

foo\factory::create('test');

As commented, if I use the full name inside call_user_func(), it works as expected, but if I use relative namespaces, it says the class was not found - but direct instances work. Am I missing something or is it strange in design?

+5
source share
2 answers

You must use the fully qualified class name in callbacks.

See Example # 3 call_user_func()Using a Namespace Name

<?php

namespace Foobar;

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

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

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

. # 2 ,

( ).

+7

PHP, , - . , , .

PHP v5.5 , Classname::class, , FQN .

. PHP RFC: https://wiki.php.net/rfc/class_name_scalars

:

return call_user_func([models\$name::class,"getInstance"]);

; 5.5 . , .

+1

All Articles