php require_once用法與相對目錄要謹慎

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

-- folder_a // 文件夾A網站

   file_a_a.phpui

   file_a_b.phpspa

   file_a_c.php繼承

-- folder_b // 文件夾Bci

   file_b_a.phpio

   file_b_b.phptable

   file_b_c.phpfunction

-- index.phpclass

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

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

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");
require_once("demo/b.php");
B::demo();a.php
class A
{
}

b.php的內容比較有意思,由於它本身要繼承 CLASS A 因此本身把a.php也引入進去了

 代碼以下 複製代碼

require_once("../a.php");
class B extends A
{
    public static function demo()
    {
    echo "xx";
    }
}

執行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");
require_once("../a.php");
class B extends A
{
    public static function demo()
    {
    echo "xx";
    }
}
B::demo();

緣由找到了,由於在c.php裏面,其相對目錄 「..」就是 c.php的上一層了,致使文件找不到報錯。
因此,咱們的結論是,在 PHP 裏面,使用require_once的時候,存在不一樣層級關係,且有相對目錄的使用那麼必定要謹慎,當心。

require_once很簡單用但在使用時你們儘可能使用絕對路徑了。

相關文章
相關標籤/搜索