Reputation: 18578
Im confused at why a variable class name seems to ignore the current name space ?
I would expect the following to be the same
<?php
namespace so\level1{
class test{
function __construct() {
echo "working correctly\r\n";
}
}
}
namespace so {
$a = new level1\test();
$b = 'level1\\test';
$c = new $b();
}
Instead $c
is a new \level1\test
instead of a \so\level1\test
This seems to contradict http://php.net/manual/en/language.namespaces.fallback.php
Class names always resolve to the current namespace name
http://php.net/manual/en/language.namespaces.rules.php
Says
Inside a namespace, all qualified names not translated according to import rules have the current namespace prepended. For example, if a call to C\D\e() is performed within namespace A\B, it is translated to A\B\C\D\e().
I have no import rules, so it also seems to suggest $a
and $c
are the same
Is there any documentation I am missing ? or is the behaviour wrong ?
Output of above
working correctly
PHP Fatal error: Class 'level1\test' not found in /tmp/namespace.php on line 15
PHP Stack trace:
PHP 1. {main}() /tmp/namespace.php:0
using PHP 5.5.9 and 5.5.21
adding
namespace level1 {
class test{
function __construct() {
echo "Not working correctly\r\n";
}
}
}
Makes the second name space resolve, But it seems like incorrect behaviour
To confirm, this seems incorrect because of the following
<?php
namespace so {
$test = "namespace";
$var = "test";
echo $$var;
}
This resolves "correctly" but inconsistently with the above.
Though call_user_func behaves in a similar way to the classes
namespace so {
function testing() {
echo "in namespace";
}
call_user_func(__NAMESPACE__ . "\\testing");
}
in the last case, it is actually documented. using a variable function behaves in the same way
Upvotes: 2
Views: 189
Reputation: 59701
The answer is, it doesn't work, because if you start using dynamic class names the "current namespace" is the global namespace.
But it seems like incorrect behavior, no as I said if you use dynamic class names the "current namespace" is the global one and not the one which it is written in.
But with one point you're kind of right. This isn't explicit said in the manual.
So how to solve this now? You just can use the magic constant __NAMESPACE__
to get the current namespace and you can simply do this:
namespace so\level1{
class test{
function __construct() {
echo "working correctly\r\n";
}
}
}
namespace so {
$a = new level1\test();
$b = __NAMESPACE__ . '\\level1\\test';
$c = new $b();
}
Output:
working correctly working correctly
Upvotes: 3