當前位置:才華齋>計算機>php語言>

PHP自動載入

php語言 閱讀(2.81W)

很多的初學者在學習 PHP 的時候最早面對的問題之一就是 require 、 include 和 require_once 、include_once 的相愛相殺。那麼在瞭解了它們相愛相殺的故事後,往往就開始使用起了框架。以下是關於框架的介紹,希望對大家有用,更多內容請關注應屆畢業生網!

PHP自動載入

框架固然是幹活的好工具,但是你知道你平時 new 一個新類的時候,發生了什麼嗎?有想過為什麼我們遵循規範就會自動的幫我們做好一切的載入嗎? 讓我們一切來探索發現其中的奧祕。

  時間線

  蒸汽時代

在 PHP 程式碼的頂部你是不是經常看到這樣的程式碼。

require '';require '';require '';

如果只是引入幾個 PHP 指令碼,那還可以接受。那引入成千上萬個指令碼的時候,爆炸是在所難免的。如果對一個指令碼改了個名字,還需要對引入改指令碼的每個指令碼改名,能不爆炸嗎?連打出這段話都怎麼繞。

  電氣時代

在 PHP 電氣時代,開始出現了 __autoload 和 spl_autoload_register 函式註冊自定義的自動載入策略。

通俗的來說,__autoload 和 spl_autoload_register 是一個 殺手組織,他們會去僱傭 各國殺手 (函式)。當我們想搞定某個人的時候(new),只需要提供名字(類名),剩下的 殺手 會幫我們搞定的。

__autoload

PHP 5 開始提供這個函式 傳送門。當你使用的 類 找不到的時候,它把類名當成引數扔進這個函式。

}

}

}$lionis = new Lionis();

輸出

歐耶耶, 我就是 Lionis

spl_autoload_register

如果我們 專案 很大很老又或者你是一個 愛折騰 的少先隊員,需要引入的東西有不一樣的規範,這時候如果都放在 autoload 函式裡,這個函式馬上就會膨脹的。而且autoload 是全域性唯一的,如果被人佔用了,可能會導致錯誤。(欲使一個人滅亡,必將先使其膨脹。)

PHP 5.1.2 開始提供這個函式 傳送門,註冊給定的函式作為 __autoload 的實現。所以,我們看一些框架或外掛在自己使用的時候,為了相容可能會出現 function_exists(spl_autoload_register)。

}// 函式spl_autoload_register('lionisIsCoolFind');// 匿名函式spl_autoload_register(function($require) { require './' . $classname . '';

});// 類中的函式spl_autoload_register(array('Lionis', 'loadClass'));

歐耶,這下我們可以寫很多不同的自動載入函數了。

資訊時代

師傅小心,前面有妖氣! 。如果我們每個人都自己實現一套自動載入的方法,每個PHP 元件和 框架都使用獨特的自動載入器,而且每個框架使用不同的邏輯載入PHP類、介面和性狀。

那當我們使用一些第三方框架的時候,還需要去弄清楚引導檔案中的 自動載入器,那樣是有多和 時間 過不去呢。 PHP-FIG 認識到了這個問題了,推薦使用 PSR-4 規範,來促進元件之間的 互操作性,這樣我們就可以使用一個自動載入器了。

  PSR-4 規範

利用名稱空間的字首和檔案系統中的目錄對應起來。

對映關係為

namespace => filePathLionisCool => cool

帶有名稱空間的類

}

建立一個物件

這個時候,按照 PSR-4 的規範,自動載入器應該去載入 cool/ 目錄下的 。

不對!那這樣不是還要自己去實現 自動載入器 嘛,不然怎麼 無中生有 出現 自動載入器 呢?難道官方 內建 了?

你 out 了吧,我們可以使用依賴管理器 composer 來生成 PSR-4 自動載入器。你可能會疑問,那我的舊專案沒有遵循 PSR-4 規範怎麼辦?嘿嘿,讓我們來探索發現一下 composer 是怎麼解決這個問題的吧。

  Composer

哦吼吼,我們這次的重點在與探究自動載入,所以 composer 的安裝和使用等,就不去討論了。

composer 自動載入設定了 4種 載入方式:

PSR-0

PSR-4

classmap

files

  PSR-0

要求名稱空間和目錄層層對應,且可以使用 _ 作為路徑分隔符,但是這會導致目錄結果變得過深。

在 composer 執行 install 等操作時,composer 會把檔案中的配置儲存在 vendor/composer/autoload_檔案中的返回陣列中。

例如:定義了VeryGood=>vendorLionisIsRealCool,在呼叫 use VeryGoodLoveSomeClass,PSR-0 載入的實際目錄為 vendor/Lionis/IsReal/Cool/Very/Good/Love/。

對吧,這簡直深得嚇人,所以 PSR-0 被官方廢除了。但是一些主流的框架已經實現了 PSR-0,為了向下相容還是要實現 PSR-0。

配置:"autoload": { "psr-0": { "VeryGood": "vendorLionisIsRealCool"

}

}

  PSR-4

PSR-4 是現在比較推薦的方法,用於替代 PSR-0。

與 PSR-0 不同的是,取消掉了 _ 作為分隔符和目錄結構。

在 composer 執行 install 等操作時,composer 會把檔案中的配置儲存在 vendor/composer/autoload_檔案中的返回陣列中。

例如:定義了VeryGood=>vendorLionisIsRealCool,在呼叫 use VeryGood

LoveSomeClass,PSR-4 載入的.實際目錄為 vendor/Lionis/IsReal/Cool/Love/。

配置:

"autoload": { "psr-4": { "VeryGood": "vendorLionisIsRealCool"

}

}

  classmap

classmap 通過配置指定的目錄和檔案,在 composer 執行 install 等操作時,composer 會去掃描對應的目錄下以結尾的檔案中的 class,並存儲在 vendor/composer/autoload_檔案中的返回陣列中。

配置:"autoload": { "classmap": [ "Lionis/", "Xiaoer/"

]

}

如果 Lionis 下有一個叫 VeryCool的檔案,那麼在vendor/composer/autoload_ 中會生成。

$baseDir . '/Lionis/', // 其他的對映);

  files

files 就是直接簡單粗暴的載入檔案。在 composer 執行 install 等操作時,composer 會把檔案中的配置儲存在 vendor/composer/autoload_檔案中的生成一個 $files 陣列。

配置:"autoload": { "files": ["Lionis/Very/"]

}

  小結

composer 通過使用 ,用 json 的格式來指定我們需要自動載入的規則。我們只要在入口檔案引入 vendor/ 就能很方便的便能使用 自動載入。

如果你對 composer 實現 自動載入 的原理感興趣,可以順著 vendor 中的 去看看原始碼。

  總結

從 石器時代 到 資訊時代,PHP 經歷了很多試驗和改變後正在變得越來越好。當然,許多優秀的框架讓我們開發速度更快,需要理解的一些知識點也隨之被隱藏起來,讓我們更加專注於實現邏輯。但是,我們有的時候還是要嘗試的去理解他們工作的原理,來提升我們自己。像我老師說過的,所不定一下子踩到狗屎運了呢。