当前位置:首页 > PHP教程 > php高级应用 > 列表

php自动加载__autoload()函数用法

发布: 来源: PHP粉丝网  添加日期:2018-06-11 10:12:31 浏览: 评论:0 

在PHP5之后,我们可以通过 __autoload来解决这个问题,而且在PHP5.1之后,还提供了 spl_autoload_register() 来提供更完善的加载机制.

通过阅读了 Autoloading in PHP 这篇文章,我理解的 Autoload 的加载机制,当通过 new 来实例化一个类时,PHP会通过定义的__autoload 函数加载相应的文件,如果这个类文件使用了 extends 或者 implements 需要用到其他的类文件,php会重新运行 autoload 去进行类文件的查找和加载,如果发生了两次对同一类文件的请求,就会报错

自动加载原理:

在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利。这也是OO设计的基本思想之一。在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可,下面是一个实际的例子:

  1. /* Person.class.php */ 
  2. <?php 
  3.  class Person { 
  4.   var $name$age
  5.    
  6.   function __construct ($name$age
  7.   { 
  8.    $this->name = $name
  9.    $this->age = $age
  10.   } 
  11.  } 
  12. ?> 
  13.  
  14. /* no_autoload.php */ 
  15. <?php 
  16.  require_once (”Person.class.php”); 
  17.  
  18.  $person = new Person(”Altair”, 6); 
  19.  var_dump ($person); 
  20. ?> 

在这个例子中,no-autoload.php文件需要使用Person类,它使用了require_once将其包含,然后就可以直接使用Person类来实例化一个对象。

但随着项目规模的不断扩大,使用这种方式会带来一些隐含的问题:如果一个PHP文件需要使用很多其它类,那么就需要很多的require/include语句,这样有可能会造成遗漏或者包含进不必要的类文件。如果大量的文件都需要使用其它的类,那么要保证每个文件都包含正确的类文件肯定是一个噩梦。

PHP5为这个问题提供了一个解决方案,这就是类的自动装载(autoload)机制。autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。

下面是使用autoload机制加载Person类的例子:

  1. /* autoload.php */ 
  2. <?php 
  3.  function __autoload($classname) { 
  4.   require_once ($classname . “class.php”); 
  5.  } 
  6.  
  7.  $person = new Person(”Altair”, 6); 
  8.  var_dump ($person); 
  9.  ?> 

通常PHP5在使用一个类时,如果发现这个类没有加载,就会自动运行__autoload()函数,在这个函数中我们可以加载需要使用的类。在我们这个简单的例子中,我们直接将类名加上扩展名”.class.php”构成了类文件名,然后使用require_once将其加载。从这个例子中,我们可以看出autoload至少要做三件事情,第一件事是根据类名确定类文件名,第二件事是确定类文件所在的磁盘路径(在我们的例子是最简单的情况,类与调用它们的PHP程序文件在同一个文件夹下),第三件事是将类从磁盘文件中加载到系统中。第三步最简单,只需要使用include/require即可。要实现第一步,第二步的功能,必须在开发时约定类名与磁盘文件的映射方法,只有这样我们才能根据类名找到它对应的磁盘文件。

因此,当有大量的类文件要包含的时候,我们只要确定相应的规则,然后在__autoload()函数中,将类名与实际的磁盘文件对应起来,就可以实现lazy loading的效果。从这里我们也可以看出__autoload()函数的实现中最重要的是类名与实际的磁盘文件映射规则的实现。

但现在问题来了,如果在一个系统的实现中,如果需要使用很多其它的类库,这些类库可能是由不同的开发人员编写的,其类名与实际的磁盘文件的映射规则不尽相同。这时如果要实现类库文件的自动加载,就必须在__autoload()函数中将所有的映射规则全部实现,这样的话__autoload()函数有可能会非常复杂,甚至无法实现。最后可能会导致__autoload()函数十分臃肿,这时即便能够实现,也会给将来的维护和系统效率带来很大的负面影响。在这种情况下,难道就没有更简单清晰的解决办法了吧?答案当然是:NO! 在看进一步的解决方法之前,我们先来看一下PHP中的autoload机制是如何实现的。

(2) PHP的autoload机制的实现

实现自动加载,我们需要借助一个函数来实现:

  1. /* 
  2. autoload_function 
  3. 欲注册的自动装载函数。如果没有提供任何参数,则自动注册 autoload 的默认实现函数spl_autoload()。 
  4.  
  5. throw 
  6. 此参数设置了 autoload_function 无法成功注册时, spl_autoload_register()是否抛出异常。 
  7.  
  8. prepend 
  9. 如果是 true,spl_autoload_register() 会添加函数到队列之首,而不是队列尾部。 
  10. */ 
  11. bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] ) 

最常用的一种方式就是通过spl_autoload_register函数来注册自动加载类的方法!

通过spl_autoload_register注册

我们可以通过spl_autoload_register函数注册类的方法,在类调用前,我们判断类文件路径是否是文件,如果是则引入之!

下面是一个小例子:

  1. class autoload  
  2.     publicstatic functionload($className)  
  3.     { 
  4.         $name = str_replace('\\', '/', $className); 
  5.         $fileName = sprintf('%s.php'$name); 
  6.         if (is_file($fileName)) { 
  7.             require_once $fileName
  8.         } 
  9.         // var_dump($fileName); 
  10.     } 
  11.  
  12. // 这样写也可以的 
  13. // spl_autoload_register(array("autoload", "load")); 
  14. spl_autoload_register("autoload::load"); 

通过__autoload函数实现

我们新建一个autoload.php文件,里面只放如下代码也可以实现上面一样的功能:

  1. function__autoload($className) { 
  2.  
  3.     $name = str_replace('\\', '/', $className); 
  4.     $fileName = sprintf('%s.php'$name); 
  5.  
  6.     if (is_file($fileName)) { 
  7.         require_once($fileName); 
  8.     } 

小结:

自动加载可以使得我们的操作更简便,经常需要自动加载一些默认配置,因此掌握自动加载的实现是非常重要的!

Tags: php自动加载 __autoload

分享到: