【发布时间】:2010-02-20 16:59:20
【问题描述】:
spl_autoload_register可以做这种工作,但我不明白这种工作是怎么做的?
spl_autoload_register(array('Doctrine', 'autoload'));
【问题讨论】:
spl_autoload_register可以做这种工作,但我不明白这种工作是怎么做的?
spl_autoload_register(array('Doctrine', 'autoload'));
【问题讨论】:
基本思想是您不必再编写include/require 指令:每当您尝试使用未定义的类时,PHP 都会调用自动加载器。
那么,自动加载器的工作就是确定应该加载哪个文件,然后include 它,所以类被定义了。
然后 PHP 可以使用该类,就好像您是编写 include 指令的人一样,该指令实际上已在自动加载函数中执行。
“诀窍”是自动加载功能:
这就是命名约定的原因,例如 PEAR 约定,它表示 Project_SubProject_Component_Name 之类的类映射到 Project/SubProject/Component/Name.php 之类的文件——即类名中的“_”被替换为文件系统上的斜线(目录、子目录)。
例如,如果您查看Doctrine_Core::autoload 方法,在您的案例中该方法将被称为自动加载器,它包含这部分代码(在处理某些特定情况后) :
$class = self::getPath()
. DIRECTORY_SEPARATOR .
str_replace('_', DIRECTORY_SEPARATOR, $className)
. '.php';
if (file_exists($class)) {
require $class;
return true;
}
return false;
这意味着类名映射到文件系统,将“_”替换为“/”,并在文件名中添加最后一个.php。
例如,如果您尝试使用 Doctrine_Query_Filter_Chain 类,而 PHP 不知道它,则将调用 Doctrine_Core::autoload 函数;它将确定应该加载的文件是 Doctrine/Query/Filter/Chain.php ;并且由于该文件存在,它将被包含在内——这意味着 PHP 现在“知道”Doctrine_Query_Filter_Chain 类。
【讨论】:
Doctrine的一个?
spl_autoload_register注册的自动加载函数,你会有一个自动加载函数的“队列”。 PHP 将(引用php.net/spl_autoload_register)“按照定义的顺序遍历它们中的每一个”;;;这意味着将调用第一个函数;如果该类仍然不存在,则将调用第二个类;等等——类名的独立性。
"Doctrine" 字符串仅意味着您正在注册的自动加载功能是autoload 类中的静态方法autoload Doctrine (请参阅此处的“回调”:php.net/manual/en/language.pseudo-types.php) ;;;它没有说明自动加载器能够自动加载哪些类。
spl_autoload_register 不接受数组作为参数,但是为什么上面仍然有效?
spl_autoload_register 接受 "callback" 作为其第一个参数;一个包含类名作为第一个元素,静态方法名作为第二个元素的数组是一个有效的回调——请参阅我在第二条评论中发布的链接。