一文讀懂PHP文件加載機制

php文件加載有四種語句:

1. include

2. require

3. include_once

4. require_once

一文讀懂PHP文件加載機制

方法詳解:

1. `include` 語句包含並運行指定文件。

2. `require` 和 `include` 幾乎完全一樣,除了處理失敗的方式不同之外。`require` 在出錯時產生 `E_COMPILE_ERROR`(編譯致命錯誤 64 編譯時致命性錯。這就像由Zend腳本引擎生成了一個 `E_ERROR`。) 級別的錯誤。換句話說將導致腳本中止而 `include` 只產生警告(`E_WARNING`),腳本會繼續運行。

3. `include_once` 語句在腳本執行期間包含並運行指定文件。此行為和 `include` 語句類似,唯一區別是如果該文件中已經被包含過,則不會再次包含。如同此語句名字暗示的那樣,只會包含一次。可以用於在腳本執行期間同一個文件有可能被包含超過一次的情況下,想確保它只被包含一次以避免函數重定義,變量重新賦值等問題。

4. `require_once` 語句和 `require` 語句完全相同,唯一區別是 `PHP` 會檢查該文件是否已經被包含過,如果是則不會再次包含。


總結:

1. `include` 和 `require` 語句都是包含並運行指定文件,不同的是處理失敗的方式不同,所以一般 require 用於加載重要文件,比如加載框架的引導文件,如果出錯將終止程序,`include` 一般用於加載配置文件或者第三方擴展庫等,比如 `composer` 就是用的 `include` 加載文件的。

2. `include_once` 和 `require_once` 語句與 `include` 和 `require` 語句的不同就是,如果該文件已經包含過就不會再次包含了,這在避免文件重複加載,函數重定義,變量重新賦值等問題上有用,但是一定程度上會有性能損耗問題,畢竟需要檢查是否加載過。所以一般確定的情況下會優先使用 `include` 和 `require` ,而不是 `include_once` 和 `require_once` 語句。


實驗

擴展知識:

包含文件的語句會受php.ini 和 include_path(;include_path = ".:/php/includes")配置項影響,相關函數:

`ini_set()` - 為一個配置選項設置值

`set_include_path` - 設置當前的 `include_path` 配置選項

`get_include_path()` - 獲取當前的 `include_path` 配置選項

`restore_include_path()` - 還原 `include_path` 配置選項的值

  1. 直接引入(包含)文件默認是以上面set_include_path設置的目錄為環境目錄,環境目錄找不到再從當前目錄找

  2. /表示服務器根目錄,linux上面直接表示磁盤根目錄,Windows下面表示某個磁盤根目錄例如D:\\\\,`realpath()`可以返回絕對路徑。

  3. ./表示當前運行文件的同級目錄(入口),而不是當前腳本所在的目錄(include 語句所在腳本文件的目錄)

  4. 如果以相對於當前腳本文件引用文件請用__DIR__常量

注意:第一種情況,請小心了!這個一般表示從當前目錄找,但是什麼是當前目錄呢?這個不同情況是不同的,它會先把當前運行文件的目錄當成當前目錄,如果找不到,再把當前腳本所在的目錄當成當前目錄,從當前腳本所在目錄開始找,如果還找不到就報錯,引入文件不存在。

所以如果意圖清楚,最好是使用最後兩種方式引入文件,這樣能減少不必要的麻煩,另外使用絕對路徑比使用相對路徑加載文件性能更高,這樣能避免系統去解析相對路徑而耗費一些時間。

當前運行文件

當前腳本,請注意仔細理解它們的差別,前者作為入口運行,後者則被腳本通過引用的方式調用。魔術常亮__FILE____DIR__就是後者的文件名(包含完整的絕對路徑)和目錄。


關於路徑的其他引申

PHP腳本這種文件相互引用包含的關係可和網頁中靜態文件css中的`../`路徑不同,css中的路徑之和所在css文件url路徑相關,和網頁沒有半毛錢關係,網頁只是加載它而已,但是如果css中使用`/`那情況就不同了,一般`/`為根域名,再說一遍,靜態文件中除了`/`其他的路徑都是相對於當前靜態文件的,和網頁地址沒有關係。網頁中的`./`和`/`則是相對於當前url路徑(對於pathinfo也沒有關係,不會受影響,認不出是假目錄的)和根域。

還可以通過註冊自動加載方法來實現自動加載,框架大部分都實現了自動加載,不然手動寫包含語句不利於維護,太麻煩。


分享到:


相關文章: