首页 -> Zend PHP 5 认证指南 第二版 -> 第六章:PHP的面向对象技术 Object Oriented Programming in PHP 6.6 按需载入 Lazy Loading
第六章:PHP的面向对象技术 Object Oriented Programming in PHP 6.6 按需载入 Lazy Loading
2010-04-28 14:22:35
作者:Siemen

PHP 5之前的版本,如果实例化一个不存在的类的对象,或者调用一个不存在的类的内不的静态方法将会导致一个致命错误。这意味着需要事先引入所有可能被使用的类文件,更好的办法是在被需要时才引入文件——为了不漏掉文件,就需要一个复杂的文件引入机制来处理外部文件的引入。

为了解决这个问题,PHP5中的“autoload”特性,可以实现“自动载入”,也就是按需载入文件。当试图对一个不存在的类进行类型暗示、静态调用,或者试图实例化一个对象,PHP就会使用调用__autoload()这个全局函数试图载入这个类文件。如果在调用autoload()后,类还是没有定义,解释器会停止工作并且抛出一个致命错误。

function __autoload($class)
{
  // 需要 PEAR-compatible 类库的支持
  require_once str_replace("_", "/", $class);
}
 
$obj = new Some_Class();

当对Some_Class类进行实例化,__autoload()就会被调用,传入"Some_Class.php"作为参数$class的值。函数中会把下划线替换成斜杠并通过require_once()引入。

通过使用__autoload()对于单命名空间来说非常有帮助;它会按需载入类文件,因此,用不到的类文件就不会被载入。但是当你在编写复杂的代码和使用不同的的类库时(比如:PEAR和一些大型应用)调用__autoload()会变得很难操控,从而使程序变得庞大而缓慢。

Siemen注:说实话这块真的不是看的很明白。

幸好标准的PHP类库(SPL)提供了一个简单的解决办法,将autoloader堆砌在其自身的顶部。如果一个执行失败了,下一个autoloader会接着尝试载入,直到文件被载入或者产生一个致命错误。

默认的,SPL使用自己的autoloader,称为spl_autoload();这是内建函数,检查所有的引入路径的文件名是否与需要载入的类的名称小写符合,且扩展名是.inc, .php或者其他在spl_autoload_extenstions()中用都好隔开传入的扩展名列表。

另外,按需载入可以通过spl_autoload_register()来加入堆栈。第一次调用这个函数用来替换__autoload()——也就是说,如果已经存在一个用户自定义__autoload()就需要将其按顺序注册到SPL中以便继续运行:

sql_autoload_register('spl_autoload');
if (function_existed('__autoload')) {
  spl_autoload_register('__autoload');
}