Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP变量实例化类-名称空间问题_Php_Namespaces - Fatal编程技术网

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

使用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

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

(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();
因此,在使用变量实例化类时,似乎忽略了名称空间声明


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

名称空间始终是完整类名的一部分。对于某些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”。这并不能解决问题,但至少现在,如果名称空间发生了变化,代码也会发生变化。感谢大家的评论和回答。实际上,我认为上面的最后一条评论是最好的方法(除非调用名称空间有性能问题,我对此表示怀疑)。再次感谢两个答案,我都投了赞成票。我接受的答案是上面最后的评论。