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