2013-10-28 18:05
浏览 135

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

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:

$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?

图片转代码服务由CSDN问答提供 功能建议

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


  $ a =“ClassName”; \  n $ b = new $ a(); 


  //'  class not found'错误,即使文件在那里
namespace path \ to \ here; 
 $ a =“ClassName”; 
 $ b = new $ a(); 


 命名空间路径\到\ here; 
 $ a =“path \ to \ here \ ClassName”; 
  $ b = new $ a(); 

因此,当使用变量实例化类时,似乎忽略了名称空间声明。 \ n


  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dongxin2734 2013-10-28 18:27

    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 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).

    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.*

    $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.

    解决 无用
    打赏 举报
  • doudang1052 2013-10-28 18:46

    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:

    // 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.
    解决 无用
    打赏 举报

相关推荐 更多相似问题