使用PHP变量实例化类-名称空间问题
下面的所有示例都基于所有文件都存在于其正确位置的保证。我已经查过了 (1) 这在不使用名称空间时有效:使用PHP变量实例化类-名称空间问题,php,namespaces,Php,Namespaces,下面的所有示例都基于所有文件都存在于其正确位置的保证。我已经查过了 (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
$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();
因此,在使用变量实例化类时,似乎忽略了名称空间声明
有没有更好的方法(比我的上一个示例更好),这样我就不需要遍历一些代码并更改每个变量以包含名称空间?名称空间始终是完整类名的一部分。对于某些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();
?>
在字符串中存储类名时,需要存储完整的类名,而不仅仅是相对于当前命名空间的名称:
<?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.
}
名称空间声明通常只在源文件的顶部执行一次,而不是在需要它的变量前面。最好使用\uuuu Namespace\uuuu
关键字更改变量名称空间,如$a=\uuu Namespace\uuuu。“\\ClassName”代码>。这并不能解决问题,但至少现在,如果名称空间发生了变化,代码也会发生变化。感谢大家的评论和回答。实际上,我认为上面的最后一条评论是最好的方法(除非调用名称空间有性能问题,我对此表示怀疑)。再次感谢两个答案,我都投了赞成票。我接受的答案是上面最后的评论。