首頁 > 後端開發 > php教程 > 建議盡量不要使用include_once(require_once)

建議盡量不要使用include_once(require_once)

黄舟
發布: 2023-03-11 12:32:02
原創
2130 人瀏覽過

本篇文章是對不要使用(include/require)_once的原因進行了詳細的分析介紹,需要的朋友參考下

關於使用include還是include_once(以下,都包含require_once), 這個討論很長了, 結論也一直有, 就是盡量使用include, 而不是include_once, 以前最多的理由的是, include_once需要查詢一遍已加載的文件列表, 確認是否存在, 然後再加載.

#誠然, 這個理由是對的, 不過, 我今天要說的, 是另外一個的原因.

我們知道, PHP去判斷一個檔案是否被載入, 是需要得到這個檔案的opened_pa​​th的, 意思是說, 例如:

複製程式碼 程式碼如下:

<?php
set_include_path
("/tmp/:/tmp2/");
include_once("2.php");
?>
登入後複製


當PHP看到include_once “2.php”的時候, 他並不知道這個檔案的實際路徑是什麼, 也就無法從已載入的檔案清單去判斷是否已經加載, 所以在include_once的實現中, 會首先嘗試解析這個文件的真實路徑(對於普通文件這個解析僅僅類似是檢查getcwd和文件路徑, 所以如果是相對路徑, 一般是不會成功), 如果解析成功, 則查找EG(include_files), 如果存在則說明包含過了, 返回, 否則open這個文件, 從而得到這個文件的opened_pa​​th. 比如上面的例子, 這個文件存在於“/tmp2/2.php”.

然後, 得到了這個opened_pa​​th以後, PHP去已載入的檔案清單去查找, 是否已經包含, 如果沒有包含, 那麼就直接compile, 不再需要open file了.

#1. 嘗試解析檔案的絕對路徑, 如果能解析成功, 則檢查EG(included_files), 存在則回傳, 不存在繼續
2. 開啟檔案, 得到檔案的開啟路徑(opened path)
3. 拿opened path去EG(included_files)查找, 是否存在, 如果存在則返回, 不存在繼續
4. 編譯文件(compile_file)

這個在大多數情況下,不是問題, 然而問題出在當你使用APC的時候…

在使用APC的時候, APC劫持了compile_file這個編譯文件的指針, 從而直接從cache中得到編譯結果, 避免了對實際文件的open, 避免了對open的system call.

然而, 當你在程式碼中使用include_once的時候, 在compile_file之前, PHP已經嘗試去open file了, 然後才進入被APC劫持的compile file中, 這樣一來, 就會產生一次額外的open操作. 而APC正是為了解決這個問題, 引入了include_once_override, 在include_once_override開啟的情況下, APC會劫持PHP的ZEND_INCLUDE_OR_EVAL opcode handler, 通過stat來確定文件的絕對路徑, 然後如果發現沒有被載入, 就改寫opcode為include, 做一個tricky解決方案.

但是, 很可惜, 如我所說, APC的include_once_override實現的一直不好, 會有一些未定義的問題, 例如:

複製程式碼 程式碼如下:

<?php
set_include_path("/tmp");
function a($arg = array()) {
    include_once("b.php");
}
a();
a();
?>
登入後複製


#然後, 我們的b.php放置在」/tmp/ b.php”, 內容如下:

程式碼如下:

<?php
  class B {}
?>
登入後複製


那麼在開啟apc.include_once_override的情況下, 連續存取就會得到如下錯誤:

Fatal error - include() : Cannot redeclare class b

排除這些技術因素, 我也一直認為, 我們應該使用include, 而不是include_once, 因為我們完全能做到自己規劃, 一個文件做到自己規劃, 一個文件只被載入一次. 也可以藉助自動載入, 來做到這一點.

你使用include_once, 只能證明, 你對自己的程式碼沒信心.

#所以, 建議大家, 不要再使用include_once

以上是建議盡量不要使用include_once(require_once)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板