简体   繁体   English

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

[英]Using a PHP variable to instantiate a class - problems with namespaces

All examples below are based on the guarantee that all files exist in their correct location. 以下所有示例都基于所有文件都存在于正确位置的保证。 I've treble checked this. 我高音检查过这个。

(1) This works when NOT using namespaces: (1)这在不使用命名空间时有效:

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

This doesn't work: 这不起作用:

// 'class not found' error, even though file is there

namespace path\to\here;
$a = "ClassName";
$b = new $a();

This DOES work: 这个工作:

namespace path\to\here;
$a = "path\to\here\ClassName";
$b = new $a();

So it seems the namespace declaration is ignored when using a variable to instantiate a class. 因此,当使用变量实例化类时,似乎忽略了名称空间声明。

Is there a better way (than my last example) so I don't need to go through some code and change every variable to include the namespace? 有没有更好的方法(比我上一个例子)所以我不需要经历一些代码并更改每个变量以包含命名空间?

The namespace is always part of the complete class name. 命名空间始终是完整类名的一部分。 With some use statements you'll only create an alias for a class during runtime. 使用一些use语句,您只能在运行时为类创建别名。

<?php

use Name\Space\Class;

// actually reads like

use Name\Space\Class as Class;

?>

The namespace declaration before a class only tells the PHP parser that this class belongs to that namespace, for instantiation you still need to reference the complete class name (which includes the namespace as explained before). 类之前的名称空间声明只告诉PHP解析器该类属于该名称空间,对于实例化,您仍需要引用完整的类名(包括如前所述的名称空间)。

To answer your specific question, no, there isn't any better way than the last example included in your question. 要回答您的具体问题,不,没有比您的问题中包含的最后一个示例更好的方法。 Although I'd escape those bad backslashes in a double quoted string.* 虽然我用双引号字符串来逃避那些坏的反斜杠。*

<?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();

?>

*) No need for escaping if you use single quoted strings. *)如果使用单引号字符串,则无需转义。

When storing a class name in a string, you need to store the full class name, not only the name relative to the current namespace: 在字符串中存储类名时,需要存储完整的类名,而不仅是相对于当前名称空间的名称:

<?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.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM