以下所有示例都基于所有文件都在正确位置的保证。我高音检查了这个。
(1)这在不使用名称空间时有效:
$a = "ClassName";
$b = new $a();
这不起作用:
// 'class not found' error, even though file is there
namespace path\to\here;
$a = "ClassName";
$b = new $a();
这项工作:
namespace path\to\here;
$a = "path\to\here\ClassName";
$b = new $a();
因此,当使用变量实例化类时,似乎忽略了名称空间声明。
有没有更好的方法(比我上一个例子)所以我不需要经历一些代码并更改每个变量以包含命名空间?
答案 0 :(得分:5)
命名空间始终是完整类名的一部分。使用一些use语句,您只能在运行时为类创建别名。
<?php
use Name\Space\Class;
// actually reads like
use Name\Space\Class as Class;
?>
类之前的名称空间声明只告诉PHP解析器该类属于该名称空间,对于实例化,您仍然需要引用完整的类名(包括如前所述的名称空间)。
要回答您的具体问题,不,没有比问题中包含的最后一个例子更好的方法。虽然我用双引号字符串来逃避那些不好的反斜杠。*
<?php
$foo = "Name\\Space\\Class";
new $foo();
// Of course we can mimic PHP's alias behaviour.
$namespace = "Name\\Space\\";
$foo = "{$namespace}Foo";
$bar = "{$namespace}Bar";
new $foo();
new $bar();
?>
*)如果使用单引号字符串,则无需转义。
答案 1 :(得分:1)
在字符串中存储类名时,需要存储完整的类名,而不仅仅是相对于当前名称空间的名称:
<?php
// global namespace
namespace {
class Outside {}
}
// Foo namespace
namespace Foo {
class Foo {}
$class = "Outside";
new $class; // works, is the same as doing:
new \Outside; // works too, calling Outside from global namespace.
$class = "Foo";
new $class; // won't work; it's the same as doing:
new \Foo; // trying to call the Foo class in the global namespace, which doesn't exist
$class = "Foo\Foo"; // full class name
$class = __NAMESPACE__ . "\Foo"; // as pointed in the comments. same as above.
new $class; // this will work.
new Foo; // this will work too.
}