IMB
IMB

Reputation: 15889

Namespace not working when used as variable?

<?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

I was looking to use $test2 but it doesn't work even though it looks like it should as it's pretty much the same as $test3 which worked.

Is this expected or is there some syntax I need to use for test2 to work?

Upvotes: 0

Views: 69

Answers (3)

user2226755
user2226755

Reputation: 13157

You can prefix your strign with __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

Upvotes: 2

Michael Miller
Michael Miller

Reputation: 399

So I'll see if I can explain this simply. In your first instance "$test1 = new Foo\Bar();", the path to the model is mapped during compile/load time. In the case where "$test2 = 'Foo\Bar'; $test2 = new $test2();", you're trying to call this model during runtime... Unfortunately, at runtime, the linking has already been done, and is not revisited. What this means it that "$test2 = '\Vendor\Package\Foo\Bar'" should work, but a shortened version of the name can't work, as the linking step is not revisited during runtime.

Upvotes: 1

Barmar
Barmar

Reputation: 780994

When you use a dynamic class name, it has to be fully qualified. The documentation says:

One must use the fully qualified name (class name with namespace prefix). Note that because there is no difference between a qualified and a fully qualified Name inside a dynamic class name, function name, or constant name, the leading backslash is not necessary.

Foo\Bar is not fully qualified, it's relative to Vendor\Package that you selected with the earlier namespace statement.

Upvotes: 5

Related Questions