請離開include_once和require_once
誠然, 這個理由是對的, 不過, 我今天要說的, 是另外一個的原因.
我們知道, PHP去判斷一個文件是否被加載, 是需要得到這個文件的opened_path的, 意思是說, 比如:
<?php
set_include_path("/tmp/:/tmp2/");
include_once("2.php");
?>
當(dāng)PHP看到include_once “2.php”的時候, 他并不知道這個文件的實(shí)際路徑是什么, 也就無法從已加載的文件列表去判斷是否已經(jīng)加載, 所以在include_once的實(shí)現(xiàn)中, 會首先嘗試解析這個文件的真實(shí)路徑(對于普通文件這個解析僅僅類似是檢查getcwd和文件路徑, 所以如果是相對路徑, 一般是不會成功), 如果解析成功, 則查找EG(include_files), 如果存在則說明包含過了, 返回, 否則open這個文件, 從而得到這個文件的opened_path. 比如上面的例子, 這個文件存在于 “/tmp2/2.php”.
然后, 得到了這個opened_path以后, PHP去已加載的文件列表去查找, 是否已經(jīng)包含, 如果沒有包含, 那么就直接compile, 不再需要open file了.
1. 嘗試解析文件的絕對路徑, 如果能解析成功, 則檢查EG(included_files), 存在則返回, 不存在繼續(xù)
2. 打開文件, 得到文件的打開路徑(opened path)
3. 拿opened path去EG(included_files)查找, 是否存在, 如果存在則返回, 不存在繼續(xù)
4. 編譯文件(compile_file)
這個在大多數(shù)情況下, 不是問題, 然而問題出在當(dāng)你使用APC的時候…
但是, 很可惜, 如我所說, APC的include_once_override實(shí)現(xiàn)的一直不好, 會有一些未定義的問題, 比如:
<?php
set_include_path("/tmp");
function a($arg = array()) {
include_once("b.php");
}
a();
a();
?>
然后, 我們的b.php放置在”/tmp/b.php”, 內(nèi)容如下:
<?php
class B {}
?>
那么在打開apc.include_once_override的情況下, 連續(xù)訪問就會得到如下錯誤:
Fatal error - include() : Cannot redeclare class
排除這些技術(shù)因素, 我也一直認(rèn)為, 我們應(yīng)該使用include, 而不是include_once, 因?yàn)槲覀兺耆茏龅阶约阂?guī)劃, 一個文件只被加載一次. 還可以借助自動加載, 來做到這一點(diǎn).
你使用include_once,只能證明, 你對自己的代碼沒信心.
所以, 建議大家, 不要再使用include_once
相關(guān)文章
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence錯誤的處理方法
在利用php解析xml時提示Invalid byte 1 of 1-byte UTF-8 sequence錯誤了,這個問題我百度查實(shí)說是編碼問題,結(jié)果我把編碼處理一下果然KO了,下面我來分享一下解決辦法2013-11-11Mac環(huán)境下php操作mysql數(shù)據(jù)庫的方法分享
今天在mac上搭建好了php的環(huán)境,我們就把php操作mysql數(shù)據(jù)庫的方法分享給大家,有需要的小伙伴參考下。2015-05-05php post大量數(shù)據(jù)時發(fā)現(xiàn)數(shù)據(jù)丟失問題解決方法
這篇文章主要介紹了php post大量數(shù)據(jù)時發(fā)現(xiàn)數(shù)據(jù)丟失問題解決方法,原因是默認(rèn)配置里的數(shù)據(jù)量配置太小造成的這個問題,修改一下配置即可,需要的朋友可以參考下2015-06-06