一、什么是自動加載
自動加載就是當我們在當前文件中實例化一個不存在的類時,調用自動加載機制引入相應的類文件。
注:自動加載有兩種方式(都是php內置的),一種是通過__autoload(),另一種是通過spl_autoload_register()。
以下兩種方式的介紹中,都是執行test3.php文件。
?
?
二、通過__autoload() 實現自動加載
/data/www/test2/test2.php
<?phpclass test2
{function aa(){echo 'this is function aa';echo "<br><br>";}static function bb(){echo 'this is function bb';echo "<br><br>";}
}
/data/www/test3.php
<?php//加載過程
//1、實例化test2類,由于當前文件不存在test2類,所以會自動執行__autoload()方法,并自動將類名傳過去
//2、執行完__autoload()方法之后,會加載test2/test2.php文件
//3、由于當前文件已經通過__autoload()方式require進文件test2.php了,所以也就可以調用test2.php中的方法了$test = new test2();
$test->aa();//調用aa方法
test2::bb();//調用bb靜態類方法function __autoload($class)
{echo '當前自動加載的類名為'.$class."<br><br>";//此時,$class的值就是test2include_once __DIR__.'/test2/'.$class.'.php';//相當于加載了test2/test2.php
}
?
?
三、通過spl_autoload_register()實現自動加載【推薦的方式】
注:由于__autoload()自動加載方式已經逐漸被php官方廢棄了,所以這里采用另一種方式spl_autoload_register來實現。
這里,test2.php文件和上面一樣,只改變test3.php文件。
?
/data/www/test3.php
<?php//加載過程
//1、實例化test2類時,由于當前文件并沒有test2類,所以php會自動調用spl_autoload_register自動加載機制
//2、調用spl_autoload_register,就會調用我們自己定義的autoload_test()方法
//3、進而引入了相應的test2.php類文件
//4、引入了相應的類文件之后,自然也就可以實例化類,并調用相應的方法了spl_autoload_register(autoload_test);$test = new test2();
$test->aa();//調用aa方法
test2::bb();//調用bb靜態類方法/*** 用于實現自動加載* @param $class*/
function autoload_test($class)
{echo '當前自動加載的類名為'.$class."<br><br>";//此時,$class的值就是test2include_once __DIR__.'/test2/'.$class.'.php';//相當于加載了test2/test2.php
}
?
?
四、總結
spl_autoload_register()相比于__autoload()的優點在于:
(1)可以按需多次寫spl_autoload_register注冊加載函數,加載順序按誰先注冊誰先調用。__aotuload由于是全局函數只能定義一次,不夠靈活。
比如下面,由于需要同時加載test2.php 以及 test4.class.php,__autoload就實現不了這個需求,而使用spl_autoload_register來實現就比較合適。
test4.class.php
<?phpclass test4
{function dd(){echo "this is test4 function dd";}}
?test3.php
<?php//加載過程
//1、實例化test2類時,由于當前文件并沒有test2類,所以php會自動調用spl_autoload_register自動加載機制
//2、調用spl_autoload_register,就會調用我們自己定義的autoload_test()方法
//3、進而引入了相應的test2.php類文件
//4、之后又實例化了test4類,test4類在當前文件同樣沒有,這時php會自動調用spl_autoload_register自動加載機制
//4.1 首先調用第一個注冊自動加載函數spl_autoload_register(autoload_test),加載之后沒有找到test4類
//4.2 所以php會繼續調用第二個自動注冊函數spl_autoload_register(autoload_test4)
//4.3 這時,終于找到test4類了,也就不用繼續在往下找了
//5、引入了相應的類文件之后,自然也就可以實例化類,并調用相應的方法了spl_autoload_register(autoload_test);
spl_autoload_register(autoload_test4);$test = new test2();
$test->aa();//調用aa方法
test2::bb();//調用bb靜態類方法$test4 = new test4();
$test4->dd();/*** 用于實現自動加載* @param $class*/
function autoload_test($class)
{echo '當前自動加載的類名為'.$class."<br><br>";//此時,$class的值就是test2include_once __DIR__.'/test2/'.$class.'.php';//相當于加載了test2/test2.php
}function autoload_test4($class)
{echo '當前自動加載的類名為'.$class."<br><br>";//此時,$class的值就是test4include_once __DIR__.'/'.$class.'.class.php';//相當于加載了test4.class.php
}
(2)spl_autoload_register()可以被catch到錯誤,而__aotuload不能。
(3)spl_autoload_register注冊的加載函數可以按需被spl_autoload_unregister掉
?
還有,值得注意的是,如果對類文件加入了命名空間,就必須保證正確的加載了類文件的同時,還要通過use引入對應的命名空間。
?