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 '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__).'/'."../folder_b/file_b_a.php"); $x = new X(); $x.printInfo(); ?> |
對就是這些,需要注意的是,這些代碼已經被復制到了index.php,也就是說,現在index.php的內容實際上就變成了:
代碼如下 | 復制代碼 |
<?php require_once(dirname(__FILE__).'/'."../folder_b/file_b_a.php"); $x = new X(); $x.printInfo(); echo "文件folder_a_a.php被包含成功"; ?> |
我們來看個注意事項
假設有如下三個文件, c.php a.php b.php 對應的存放目錄為:localhost/ localhost/ localhost/demo
代碼如下 | 復制代碼 |
c.php require_once("a.php"); |
b.php的內容比較有意思,因為它自己要繼承 CLASS A 所以自己把a.php也引入進去了
代碼如下 | 復制代碼 |
require_once("../a.php"); |
執行localhost/c.php 系統報錯,報錯信息如下
Warning: require_once(../a.php) [function.require-once]: failed to open stream: No such file or directory in F:wwwdemob.php on line 2
Fatal error: require_once() [function.require]: Failed opening required '../a.php' (include_path='.;C:php5pear') in F:wwwdemob.php on line 2但是,驚奇的發現,如果去掉b.php里面的require_once語句,執行正常,那么一定是require_once語句定義多了嗎?原因就是Class A重定義了兩次?可是不會啊。如果我只在c.php里面加require_once(‘a.php’);這條語句,哪怕我寫兩遍也是沒錯的,那到底是咋回事呢?
原因就是,b.php定義的目錄和c.php執行文件的目錄層級不一致,導致在c.php里面require_once語句有兩條。使其相當於
代碼如下 | 復制代碼 |
require_once("a.php"); |
原因找到了,因為在c.php里面,其相對目錄 “..”就是 c.php的上一層了,導致文件找不到報錯。
所以,我們的結論是,在 PHP 里面,使用require_once的時候,存在不同層級關系,且有相對目錄的使用那么一定要謹慎,小心。
require_once很簡單用但在使用時大家盡量使用絕對路徑了。