PHP autoload自動加載機制

原文地址: http://www.jb51.net/article/31399.htmphp

一直不是很明白__autoload()和spl_autoload_register()到底有什麼不一樣,找到了一個問章,介紹的很好,做爲參考。json

魔術函數__autoload()和spl_autoload_register()的區別:框架

__autoload的使用方法1:
最常常使用的就是這種方法,根據類名,找出類文件,而後require_one。函數

1 function __autoload($class_name) {
2   $path = str_replace('_', '/', $class_name);
3   require_once $path . '.php';
4 }
5 // 這裏會自動加載Http/File/Interface.php 文件
6 $a = new Http_File_Interface(); 

這種方法的好處就是簡單易使用。固然也有缺點,缺點就是將類名和文件路徑強制作了約定,當修改文件結構的時候,就勢必要修改類名。ui

__autoload的使用方法2(直接映射法)this

 1 $map = array(
 2   'Http_File_Interface' => 'C:/PHP/HTTP/FILE/Interface.php'
 3 );
 4 function __autoload($class_name) {
 5   if (isset($map[$class_name])) {
 6   require_once $map[$class_name];
 7   }
 8 }
 9 // 這裏會自動加載C:/PHP/HTTP/FILE/Interface.php 文件
10 $a = new Http_File_Interface(); 

這種方法的好處就是類名和文件路徑只是用一個映射來維護,因此當文件結構改變的時候,不須要修改類名,只須要將映射中對應的項修改就行了。spa

這種方法相較於前面的方法缺點是當文件多了的時候這個映射維護起來很是麻煩,或許這時候你就會考慮使用json或者單獨一個文件來進行維護了。或許你會想到使用一個框架來維護或者創建這麼一個映射。.net

-----------------------------------code

spl_autoloadhtm


__autoload的最大缺陷是沒法有多個autoload方法

好了, 想下下面的這個情景,你的項目引用了別人的一個項目,你的項目中有一個__autoload,別人的項目也有一個__autoload,這樣兩個__autoload就衝突了。解決的辦法就是修改__autoload成爲一個,這無疑是很是繁瑣的。

所以咱們急需使用一個autoload調用堆棧,這樣spl的autoload系列函數就出現了。你可使用spl_autoload_register註冊多個自定義的autoload函數。

若是你的PHP版本大於5.1的話,你就可使用spl_autoload。

 

spl_autoload() 是_autoload()的默認實現,它會去include_path中尋找$class_name(.php/.inc)
spl_autoload()實現自動加載:

 1 /*http.php*/
 2 <?php
 3 class http{
 4     public function callname(){
 5     echo "this is http";
 6     }
 7 }
8 /*test.php*/ 9 <?php 10 set_include_path("/home/yejianfeng/handcode/"); //這裏須要將路徑放入include 11 spl_autoload("http"); //尋找/home/yejianfeng/handcode/http.php 12 $a = new http(); 13 $a->callname();

 

spl_autoload_register()
將函數註冊到 SPL __autoload 函數棧中,直接看一個例子:

 1 /*http.php*/
 2 <?php
 3 class http{
 4     public function callname(){
 5     echo "this is http";
 6     }
 7 }
 8 
 9 /*test.php*/
10 <?php
11 spl_autoload_register(function($class){
12     if($class == 'http'){
13     require_once("/home/yejianfeng/handcode/http.php");
14     }
15 });
16 
17 $a = new http();
18 $a->callname(); 

 

spl_autoload_call()
調用spl_autoload_register()中註冊的調用函數, 看下面的例子

 1 /*http.php*/
 2 <?php
 3 class http{
 4     public function callname(){
 5     echo "this is http";
 6     }
 7 }
 8 
 9 /*http2.php*/
10 <?php
11 class http{
12     public function callname(){
13     echo "this is http2";
14     }
15 }
16 
17 /*test.php*/
18 <?php
19 spl_autoload_register(function($class){
20     if($class == 'http'){
21     require_once("/home/yejianfeng/handcode/http.php");
22 }
23   if($class == 'http2'){
24     require_once("/home/yejianfeng/handcode/http2.php");
25     }
26 });
27 spl_auto_call('http2');
28 $a = new http();
29 $a->callname(); //這個時候會輸出"this is http2" 

 

spl_auto_register()這個函數使得咱們不使用__autoload(),使用自定義的函數來進行自動加載成爲可能。這個方法如今是常常使用到的。
Zend的AutoLoader模塊就使用了這個方法。摘錄其中對應的代碼

1 spl_autoload_register(array(__CLASS__, 'autoload'));
2 
3 public static function autoload($class){
4     //...
5 } 
相關文章
相關標籤/搜索