【问题标题】:PHP namespace and dynamic classnamePHP 命名空间和动态类名
【发布时间】:2012-08-10 15:20: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();

这工作正常,文件 classes/user/student.class.php 成功加载,两个构造都成功。但是,用法有点不同:

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

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

感谢您的任何解释。

【问题讨论】:

  • 尝试删除字符串中的前导反斜杠。动态类名始终是完全限定的,因此不鼓励在其中添加反斜杠。

标签: php namespaces autoload dynamic-class


【解决方案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() 的第二个参数

【讨论】:

    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 2019-11-13
    • 1970-01-01
    相关资源
    最近更新 更多