目錄層級
各層級代碼如下:
test.php
<?php
require("a/a.php");
?>
a.php
<?php
require("../b/b.php");
?>
b.php
<?php
echo "b";
exit;
?>
aaa.php
<?php
echo "aaa";
exit;
?>
首先test.php能夠正確引用到a.php,a.php也能正確引用到b.php,但是訪問test.php時報(bào)錯(無法找到b.php):test報(bào)錯
而我們直接訪問a.php是能夠找到b.php的:
image.png
原因其實(shí)是因?yàn)閜hp require()默認(rèn)的引用機(jī)制不是相對最近一次引用的路徑,而是相對你當(dāng)前訪問的那個文件的路徑,a.php和b.php都覺得自己引用與被引用沒有問題,但test.php覺得a.php引用b.php的時候出了問題。
于是從test.php的角度看,a.php必須修復(fù)代碼,把require("../b/b.php")改成require("b/b.php"),這樣test就能正常訪問到b了。但是新的問題來了,修改之后直接訪問a是無法正確引用到b的...
這樣的機(jī)制稍微一改動就牽扯全身,以下給出兩種解決方案和一點(diǎn)注意事項(xiàng):
-
引用的時候統(tǒng)一使用絕對路徑。這樣減少理解成本,且絕不會出錯,缺點(diǎn)是顯得冗余,且不易看出路徑的相對關(guān)系
-
require的時候使用dirname(__FILE__),具體用法可以自行搜索,最后實(shí)現(xiàn)的效果是每個文件都只關(guān)心自己的引用是正確的,即test只管能正常引用a,a只管正常引用b,那么test就能正常引用b。不過個人不是很推薦這種做法,之后解釋原因
-
注意點(diǎn):其實(shí)引用的這個坑只在內(nèi)層的引用文件往外層去引用會發(fā)生(如上面測試的test.php引用了a.php,而a.php卻往上一層的b文件夾里去引用b.php,導(dǎo)致test和b的相對路徑混亂,test.php找不到b.php從而報(bào)錯),但是當(dāng)我們把a(bǔ).php里的引用改成require("aaa/aaa.php"),此時理論上test.php應(yīng)該也是找不到aaa.php的,因?yàn)閍aa.php對test.php的相對路徑應(yīng)該是a/aaa/aaa.php才對,but奇怪的是并沒有出現(xiàn)之前的報(bào)錯,即這里的問題只會發(fā)生在內(nèi)層往外引用時,當(dāng)所有引用都是一層層往里時,是沒有問題的(改成require("a/aaa/aaa.php")之后test.php依舊可以找到aaa.php,但是a.php會找不到aaa.php的)
對于這種引用機(jī)制可以這么理解:php作為一個腳本語言,其require的引用原理就是簡單的文本拷貝替換,所以最初test.php的第一行代碼require("a/a.php")直接被替換成了a.php的全部內(nèi)容,即require("../b/b.php"),而test.php根據(jù)這樣的相對路徑找不到b.php,因此報(bào)錯(假設(shè)找到了,同理則把這行require再替換成b.php的全部內(nèi)容)。
但是這樣好像依舊解釋不了一層層往里面引用時不會報(bào)錯的情況。對這種情況有合理解釋的歡迎指教。