自動載入

z y_發表於2020-10-14

在編寫面相物件程式設計(OOP)程式時,PHP檔案頂部程式要引入檔案,如

include 'path/to/file1.php';
include 'path/to/file2.php';

你可能知道require(), require_once(), inclued(), inclued_onle()這些函式的作用。
如果只需載入幾個PHP指令碼,使用這些函式能很好的完成工作。如果一次需要引入上百個PHP指令碼,甚至更多,這時候這些函式就無法勝任。
有了自動載入器,就無需像前面那樣手動引入檔案,自動載入策略能找到PHP類,介面或者性狀,然後執行時按需將其載入PHP直譯器。

在PHP-FIG釋出PSR-4推薦規範前,PHP元件和框架的作者使用__autoload()和spl_autoload_register()函式註冊自定義的自動載入策略。

PSR-4自動載入器策略

與PHP自動載入器一樣,PSR-4策略用於在執行時查詢並載入PHP類,介面等,PSR-4自動載入策略依賴PHP名稱空間和檔案系統目錄結構查詢並載入PHP指令碼。
PSR-4的精髓是把名稱空間的字首和檔案系統中的目錄對應起來。如: \GuzzleHttp\Client的名稱空間對應於src/Client.php檔案。

如何編寫PSR-4自動載入器(不該這樣做)
符合PSR-4規範的程式碼有個名稱空間對應於檔案系統中的目錄,這個名稱空間字首中的子名稱空間對應於這個目錄裡的子目錄。
下面這段程式碼摘抄自PHP-FIG網站(

/**
 * 舉例實現專案專用的自動載入器.
 *
 * 在SPL中註冊這個自動載入函式後,遇到下面程式碼時
 * 這個函式會嘗試從/path/to/project/src/Baz/Qux.php檔案載入
 * \Foo\Bar\Baz\Qux class:
 * 
 *      new \Foo\Bar\Baz\Qux;
 *
 * @param string $class 完全限定的類名。
 * @return void
 */
spl_autoload_register(function ($class) {

    // 專案名稱空間字首
    $prefix = 'Foo\\Bar\\';

    // 名稱空間字首對應的基目錄
    $base_dir = __DIR__ . '/src/';

    // 引數傳入的類是否使用名稱空間字首?
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // 不使用,交給註冊的下一個自動載入器處理
        return;
    }

    // 獲取去掉字首後的類名
    $relative_class = substr($class, $len);

    // 把名稱空間字首替換成基目錄
    // 去掉字首的類名中,把名稱空間分隔符替換成目錄空間分隔符
    // 然後加上 .php
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';

    // 如果檔案存在,將其匯入
    if (file_exists($file)) {
        require $file;
    }
});

複製上面這段程式碼,修改base_dir和preifx的值,這樣就有一個可以的PSR-4自動載入器類。
不過沒必要自己實現,因為可以使用Composer自動生成的PSR-4自動載入器

相關文章