PHP 自動加載

回顧

開始的時候, 若是想在一個php文件中使用其它文件的類或方法, 須要經過include/require方法將文件包含進來. 這種方法的缺點也很明顯:php

  1. 若是須要引入不少文件, 就須要不少的include語句, 不只不美觀, 並且也不免會又遺漏
  2. 若是多個文件中定義了相同名稱的常量, 會致使拋出重複定義的警告

autoload

爲了解決這個問題, 在PHP5中引入了自動加載的概念, 經過 *__autoload* 函數來實現, 以下:java

function __autoload($classname){
    // 完成 指定名稱類的加載任務
    include_once($classname.'.php')
}

將這個函數定義在文件中, 當遇到未引入的類時, 會調用此函數進行引入, 看起來貌似很好, 咱們只須要將此函數定義在也給PHP文件中, 之後咱們的每一個文件就只須要引入這一個自動加載文件就能夠了, 看起來完事大吉.composer

但經過使用, 這種方式也存在不少問題:函數

  1. 由於PHP不能出現同名函數, 因此當出現兩個自動加載函數時, 會報錯. 固然, 本身的項目能夠保證, 但咱們仍是要引入第三方庫的啊.
  2. 全部的函數映射都放到一個函數中, 勢必形成函數的臃腫, 同時也不利於維護

很明顯, 問題就出在了, 這是一個全局函數, 只可以定義一次,ui

spl_autoload

那麼如何解決這個問題呢? PHP引入了一個擴展庫, 能夠定義多個自動加載函數, 在查找的時候會依次調用定義好的自動加載函數進行加載, 有以下方法:spa

  1. spl_autoload_register: 註冊自動加載函數
  2. spl_autoload_unregister: 刪除已註冊的自動加載函數
  3. spl_autoload_functions: 獲取全部註冊的自動加載函數
  4. spl_autoload_call: 依次調用全部註冊的自動加載函數進行加載
  5. spl_autoload: 自動加載函數的默認實現, 若沒有進行註冊, 默認調用此函數
  6. spl_autoload_extionsions: 註冊並返回 spl_autoload 中使用的默認文件擴展名

有了它, 咱們就能夠定義多個自動加載函數了.code

下面是一個例子:io

test01.phpfunction

namespace test01;
class test{
    public static function tt(){
        echo 'test01';
    }
}

test02.phpclass

namespace test02;
class test{
    public static function tt(){
        echo 'test02';
    }
}

run.php

spl_autoload_register(function ($classname){
    include_once $classname.'01.php';
});
spl_autoload_register(function ($classname){
    include_once $classname.'02.php';
});

use test01\test;
test::tt();

運行run.php, 報錯:

Warning: include_once(test01\test01.php): failed to open stream: No such file or directory in

打印傳入的 $classname, 發現是: test01\test

也就是說, 咱們使用的時候能夠將命名空間與路徑相對應, 關於這個好像還有一個標準, 具體記不清了.

這樣一對應, 有沒有感受和java中的包有些同樣了, 反正我是以爲挺像.

composer

好了, 如今經過 composer來管理第三方庫, 它將自動加載都作好了, 只要引入他的 autoload.php 文件就能夠了.

composer提供了幾種類型的自動加載

1.psr-4

大概就是咱們上面說的路徑和命名空間對應的形式

2. classmap

保存各個類與文件的映射map


等等吧, 沒有具體研究, 不過大致是對自動加載的封裝, 很方便.

簡單總結一下, 才疏學淺..

相關文章
相關標籤/搜索