使用 PHP 变量实例化类 - 命名空间的问题



下面的所有示例都基于保证所有文件都存在于其正确的位置。我已经高音检查过了。

(1) 这在不使用命名空间时有效:

$a = "ClassName";
$b = new $a();

这不起作用:

// 'class not found' error, even though file is there
namespace pathtohere;
$a = "ClassName";
$b = new $a();

这确实有效:

namespace pathtohere;
$a = "pathtohereClassName";
$b = new $a();

因此,在使用变量实例化类时,似乎忽略了命名空间声明。

有没有更好的方法(比我上一个示例),这样我就不需要浏览一些代码并更改每个变量以包含命名空间?

命名空间始终是完整类名的一部分。对于某些 use 语句,您只会在运行时为类创建别名。

<?php
use NameSpaceClass;
// actually reads like
use NameSpaceClass 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  = "FooFoo"; // 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.
}

最新更新