PHP命名空间和动态类名

时间:2012-08-14 10:37:56

标签: php namespaces autoload dynamic-class

我遇到了一个奇怪的"在尝试使用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();

这很好用,文件类/ user / student.class.php加载成功,两个结构都成功。但是,用法有点不同:

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

失败" .. Class \ User \ Student无法加载......"。我建议它应该以某种方式与静态/动态命名空间解析相关。但是,我不认为这两者之间应该有任何区别,除非它们在(编译与运行时)处理它们的时间。

感谢您的任何解释。

1 个答案:

答案 0 :(得分:4)

这里的“问题”实际上比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()的第二个参数