首頁  >  文章  >  後端開發  >  PHP關於require_once路徑問題的詳解

PHP關於require_once路徑問題的詳解

黄舟
黄舟原創
2018-05-14 16:24:279389瀏覽

我的網站目錄如下:

*********************************** ***************************

wwwroot   //網站根目錄絕對路徑為: F:/wwwroot

-- folder_a // 資料夾A

 file_a_a.php
   file_a_b.php
   file_a_c.php

-- folder_b // 資料夾B

file_b_a.php
   file_b_b.php
   file_b_c.php

-- index.php

******** ************************************************** ***

這個目錄層次已經很清楚了:

wwwroot為根目錄,下面有index.php檔案和folder_a,folder_b兩個資料夾

這兩個資料夾分別有3個php檔案

先來看index.php檔案的內容:

<?php
     require_once("folder_a/file_a_a.php");
     echo "文件folder_a_a.php被包含成功";
?>

再來看folder_a/folder_a_a.php檔案的內容:

<?php
     require_once("../folder_b/file_b_a.php");
     $x = new X();
     $x.printInfo();
?>

最後再來看看folder_b/folder_b_a.php檔案的內容:

<?php
     class X{
          function printInfo(){
               echo &#39;success;
          }
     }
?>

ok 如果我現在直接執行floder_a/file_a_a.php

##那麼會輸出: success

如果我運行wwwroot下的index.php

那麼會報錯,原因是找不到

包含檔案:file_b_a.php

但是如果我在所有的require_once()中加入

dirname(FILE).'/'

那麼無論執行file_a_a.php 或index.php 都可以正常輸出

********* ************************************************

問題:

我第一次使用的是相對路徑,所以重複包含的時候就出錯了

而我第二次使用的是絕對路徑,所以不出錯.可是我還是有點疑惑:

我先分析了以下使用相對路徑會出錯的原因:

我運行index.php,它能找到folder_a目錄,也能找到該目錄下的file_a_a.php,於是它就把folder_a/file_a_a.php 裡的內容複製到了index.php 的第一行(包含語句的那行),然後再繼續運行(也就是運行包含過來的內容),因此此時等於是在index.php中運行file_a_a.php 中的require_once('../folder_b/file_b_a.php'); 它根據當前index.php的位置去找這個路徑文件(file_b_a.php),當然找不到啦,所以它出錯了.

可是我使用絕對路徑的時候不是一樣的道理嗎?可為什麼它就不出錯?可能這句話大家有點不解了,我來詳細說明(根據程式的運作順序來說明).

程式先執行index.php(注意此時我加上了dirname(FILE),所以目前是絕對路徑),

#index.php先執行第一句程式碼:require_once(dirname(FILE).'/'.'folder_a/file_a_a.php');

dirname(FILE) 是f:/wwwroot/ 所以這句程式碼包含的路徑也是:

f:/wwwroot/folder_a/file_a_a.php

這個路徑是正確的,因此沒問題是吧

ok 第一步正確完成

#然後它就把file_a_a.php 中的程式碼複製到的index.php 的這個地方:

然後仍然繼續運行: 這是也就是在index.php 中運行file_a_a.php 中的所有程式碼,那麼我們來看看它運行那些代碼?

<?php
     require_once(dirname(FILE).&#39;/&#39;."../folder_b/file_b_a.php");
     $x = new X();
     $x.printInfo();
?>

對就是這些,需要注意的是,這些代碼已經被複製到了index.php,也就是說,現在index.php的內容實際上就變成了:

<?php
     require_once(dirname(FILE).&#39;/&#39;."../folder_b/file_b_a.php");
     $x = new X();
     $x.printInfo();
     echo "文件folder_a_a.php被包含成功";
?>

那麼仍然按程式的執行順序來分析以上程式碼:

dirname(FILE) 應該是f:/wwwroot (因為現在這些程式碼在index.php中執行,和相對路徑一樣的道理,因此得到的是index.php所在的目錄)

那麼包含的路徑應該就是: f:/wwwroot/../folder_b/file_b_a.php

#那麼我們檢查下這個路徑是否有file_b_a.php檔呢? 答案是沒有,因為f:/wwwroot/../folder_b 已經返回到的f:盤符下的folder_b目錄,而這個目錄並不存在.

但是執行的結果卻讓我不解,它竟然正確輸出了.

也許大家會說:在相對路徑中,index.php 先包含了file_a_a.php 然後再執行包含file_b_a.php 的程式碼,所以找不到目錄.而使用絕對路徑後,index.php 在包含file_a_a.php 之前,file_a_a.php 已經先執行了包含file_b_a.php 的程式碼,所以正確輸出.但是請注意:php文檔中以及許多文檔教程都是這樣說明的:包含一個文件,實際上就是將被包含的文件中的代碼複製到包含命令的地方,就算這個觀點是錯誤的,那麼同樣是require_once 命令,不可能對相對路徑就是先包含再執行,而對絕對路徑卻是先執行再包含吧.

不解,請大家指教.(非常感謝大家能看到這裡,問題很長,是因為我鬱悶的時間更長,所以請大家不要Ctrl+C Ctrl+V,也不要說:看API 或自己找資歷等等了.)謝謝.

不要想得太複雜...

用絕對路徑:

你的c:\a.php

可以

引用

d:\b.php

你理解錯誤的一點就是FILE永遠指向當前文件,無論是主執行文件,還是被包含文件

也就是說: 如果是使用相對路徑../folder_b/file_b_a.php那麼會先複製過來,然後在指向地址,如果使用FILE,就會先指向,然後再被包含,是這樣嗎?

如果用的是虛擬目錄那這個目錄就會以你當前運行的檔案為基準

也就是

folder_a/folder_a_a.php文件的内容这样写:

<?php
     require_once("folder_b/file_b_a.php");
     $x = new X();
     $x.printInfo();
?>

你看下会不会错

在跟目录里建个文件,把要引用的文件全部按绝对路经引进来;其他目录引这个文件就好了.

以上是PHP關於require_once路徑問題的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn