Home » Php » php – Relative namespaces and call_user_func()

php – Relative namespaces and call_user_func()

Posted by: admin July 12, 2020 Leave a comment


Code speaks better than words:



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()



require_once 'namespaces.php';


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?

How to&Answers:

You have to use the fully qualified classname in callbacks.

See Example #3 call_user_func() using namespace name


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 is a function from the global scope, executing the callback from the global scope as well. In any case, see first sentence.

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

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


In current versions of PHP, the way you have it is the way it is — when using a string to reference a classname, it needs to be fully qualified with it’s complete namespace. It’s not great, but that’s the way it is.

In the forthcoming PHP v5.5, they will include a feature to address this, by providing a new Classname::class syntax, which you can use instead of putting the FQN classname in a string.

For more info on this, please see the relevant PHP RFC page here: https://wiki.php.net/rfc/class_name_scalars

Your code would look something like this:

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

That may not be exact; I don’t have a copy of 5.5 to test with to confirm. But either way, the new syntax will make things a lot better for use cases like yours.