PHP命名空间和动态类名(PHP namespace and dynamic classname)

2019-09-21 04:45发布

我遇到一个“奇怪”的事情,而与spl_autoload,命名空间和动态类名实验。 我用PHP 5.3.2,称这样的自动加载

set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register();

现在的核心。 建议下面的代码:

new \User\Student;
$name="\User\Student";
new $name();

这工作得很好,文件类/用户/ student.class.php被成功加载,两种构建成功。 但是,有一点不同的用法:

$name="\User\Student";
new $name();
new \User\Student;

失败的“..Class \用户\学生无法加载...”。 我建议应该进行相关的静态/动态命名空间分辨率莫名其妙。 不过,我不认为应该有除了他们在被处理的时间(编译与运行时),这两者之间有什么区别。

感谢您的任何解释。

Answer 1:

“问题”在这里实际上是在比SPL一个较低的水平,并且还可以与看到__autoload() 这是在代码最好证明:

function __autoload ($class) {
  echo "Loading $class\n";
}

new Test;
// displays "Loading Test"

$var = 'Test';
new $var;
// displays "Loading Test"

// However, when we introduce namespaces...

new \This\Is\A\Test;
// displays "Loading This\Is\A\Test"

$var = '\This\Is\A\Test';
new $var;
// displays "Loading \This\Is\A\Test"

请注意如何在引进的时候命名空间,静态调用的时候,领先的斜线不传递给函数,但它是动态调用时。

因此,解决的办法是要么做这些很简单的事情:

  • 取下动态类名实例化的斜线。
  • 包裹默认spl_autoload()这样的功能:
set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register(function($class) {
  spl_autoload(ltrim($class, '\\'));
});

当然,如果你这样做,你也可以去掉调用spl_autoload_extensions()只是通过".class.php"字符串的第二个参数spl_autoload()



文章来源: PHP namespace and dynamic classname