什麼是自動加載
自動加載就是當我們在目前檔案中執行個體化一個不存在的類時,調用自動加載機制引入相應的類檔案。
注:自動加載有兩種方式(都是php内置的),一種是通過__autoload(),另一種是通過spl_autoload_register()。
二、通過__autoload() 實作自動加載
/data/www/test2/test2.php
<?php
class 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的值就是test2
include_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的值就是test2
include_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
<?php
class 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的值就是test2
include_once __DIR__.'/test2/'.$class.'.php';//相當于加載了test2/test2.php
}
function autoload_test4($class)
{
echo '目前自動加載的類名為'.$class."<br><br>";//此時,$class的值就是test4
include_once __DIR__.'/'.$class.'.class.php';//相當于加載了test4.class.php
(2)spl_autoload_register()可以被catch到錯誤,而__aotuload不能。
(3)spl_autoload_register注冊的加載函數可以按需被spl_autoload_unregister掉
還有,值得注意的是,如果對類檔案加入了命名空間,就必須保證正确的加載了類檔案的同時,還要通過use引入對應的命名空間。