官术网_书友最值得收藏!

5.2 自動加載

在一個文件里使用一個類,我們可以用include、require來引入類文件。

例如,Cat類定義在cat.php文件里,請看示例代碼:(源碼文件:ch05/autoload/require/cat.php)

在test.php里使用Cat類,可以使用include、require函數引入cat.php文件。程序實現如下:(源碼文件:ch05/autoload/require/test.php)

<?php
require './cat.php';
//require_once './cat.php';
//include './cat.php';
//include_once './cat.php';
$tom = new Cat();
$tom->eat();
//Output cat eat fish

但如果需要引入多個文件,使用引入函數就非常低效了:

require './cat.php';
require './dog.php';
require './monkey.php';
require './elephant.php';

為了解決自動加載的問題,PHP提供了三種解決方案:__autoload、spl_autoload和spl_autoload。

5.2.1 __autoload

__autoload是魔術方法,當調用未定義的類時,_autoload()會被調用,用于按照規則加載未定義的類。

__autoload定義如下:

void __autoload ( string $class )

參數是要調用的類名。實現__autoload方法的一般步驟如下:

步驟01 由類名找到對應的文件名。

步驟02 判斷文件是否存在。

步驟03 用include、require等函數引入文件。

為了說明__autoload的使用方法,我們編寫了一個示例,請查看autoload/autoload目錄。

示例中的文件結構如下:

cat.php
dog.php
monkey.php
test.php

我們在調用時,不使用引入函數,直接實現__autoload方法。上面的目錄結構比較簡單,文件名是類名的小寫形式,路徑在當前目錄下查找。

程序實現代碼如下:(源碼文件:ch05/autoload/autoload/test.php)

需要注意的是,__autoload在PHP 7.2.0中已被廢棄。

__autoload不能重復定義,只能注冊一個,這在協作項目或需要引入多個第三方包時,變得非常不方便。所以PHP引入spl_autoload_register來解決這個問題。

5.2.2 spl_autoload_register

為了解決多個自動加載函數的問題,PHP引入了spl_autoload_register函數。其定義如下:

為了說明__autoload的使用方法,我們編寫了一個示例,請查看autoload/spl_autoload_register目錄。

示例中的文件結構如下:

由于表示動物的類分成大型動物(big_animal)和小型動物(small_animal),所以需要兩個加載函數:

spl_autoload_register允許多個加載函數,是非常有用的一個功能。如果從composer安裝一個第三方包,那個包可以自行處理自動加載,而作為使用者無須關心。這使得協作和開源變得更加便利。

關于__autoload與spl_autoload_register的比較如表5-2所示。

表5-2 __autoload與spl_autoload_register的比較

5.2.3 spl_autoload

spl_autoload是__autoload的一個默認實現,當spl_autoload_register無參數時默認調用。其實現的功能為在include路徑里查找類。

以下是一個使用示例:

可以看到,spl_autoload只能設置路徑和文件后綴,所以在實際項目中應用較少,屬于雞肋功能。

5.2.4 面試題:引用文件函數的區別

題目描述1:include、require、inclue_once、require_once有什么區別?

解答:include和require的區別是當引入文件過程中遇到錯誤,include會提示錯誤并繼續執行,而require會終止運行。

inclue_once和require_once則保證腳本執行期間的文件引用不超過1次,避免函數重定義,變量重新賦值等問題。

題目描述2:PHP如何自動加載類文件?

解答:參考“自動加載”一節的內容。

主站蜘蛛池模板: 江永县| 洪江市| 北票市| 大悟县| 理塘县| 台江县| 江油市| 邵阳市| 商河县| 吉安市| 桃源县| 大悟县| 西乌珠穆沁旗| 丹寨县| 德庆县| 扶风县| 梁山县| 台南县| 申扎县| 湘潭县| 大丰市| 夏河县| 西林县| 玛多县| 福贡县| 大同县| 南和县| 桃江县| 赤水市| 通榆县| 南岸区| 河西区| 嘉禾县| 德钦县| 水富县| 石嘴山市| 安徽省| 依安县| 江川县| 鄂托克前旗| 醴陵市|