php中的檔案包含

來源:互聯網
上載者:User
php關鍵詞      php中用於檔案包含的關鍵詞有:include、include_once、require、require_once。一般來說,把include和require分在一組裡,而include_once和require_once是一種改進完善形式。本文通過研究include和require的性質,兼顧include_once和require_once,獲得php檔案包含的基本知識和潛在問題,並提供一個可行的解決方案。被包含檔案的類型       使用包含關鍵詞包含的檔案,只要是文字檔,php解析器都將檔案的內容作為php檔案處理。

     也即php解析器將當前執行指令碼的包含檔案讀出後,將php嵌入標籤中的內容作為原始碼執行,而其他沒有被標籤包含的將作為文本直接輸出。     設有兩個檔案a和b.php,內容分別如下:

a
akjfladskjfla<br><?echo $_SERVER['PHP_SELF'],'<br>';echo 'I am A<br>';?>

b.php
<?phpinclude 'a';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am B<br>';?>

     輸出如下:

akjfladskjfla /webapp/codesnipe/b.php
I am A
/webapp/codesnipe/b.php
I am B

     

     檔案a無尾碼名,其中包含了一個php嵌入標籤。如果執行檔案a,系統將會報錯。但是在檔案b中,包含了檔案a。沒有被包含在php嵌入標籤中的文本被直接輸出,而包含在標籤中的文本作為php原始碼執行。資訊格式      還是上面的實驗,我們把檔案a刪除,運行b.php。報錯資訊如下:

Warning: include(a) [function.include]: failed to open stream: No such file or directory in C:/xampp/htdocs/webapp/codesnipe/b.php on line 3

Warning: include() [function.include]: Failed opening 'a' for inclusion (include_path='.;C:/xampp/php/pear/') in C:/xampp/htdocs/webapp/codesnipe/b.php on line 3
/webapp/codesnipe/b.php
I am B

       可以對照上面,總結出報錯資訊的格式如下:

       語句或函數:failed to open stream:具體的提示資訊,在檔案的第幾行

include和require的區別       當遇到檔案找不到的情況是,它們的處理不同。include會發出警告,然後繼續執行下去;require則報錯,並停止當前指令碼的執行。

      資訊格式中給出的警告格式就是include發出的。兩個警告之後就是b.php的輸出內容。如果將include換成require,則資訊如下:


Warning: require(a) [function.require]: failed to open stream: No such file or directory in C:/xampp/htdocs/webapp/codesnipe/b.php on line 3

Fatal error: require() [function.require]: Failed opening required 'a' (include_path='.;C:/xampp/php/pear/') in C:/xampp/htdocs/webapp/codesnipe/b.php on line 3


      可見,它們資訊的格式相同,而且require第二個資訊變成了Fatal error。錯誤資訊後也沒有b.php執行後的輸出,因為require報錯之後就是的指令碼的執行退出了。檔案包含的死迴圈     最簡單的死迴圈形式是兩個檔案的形式:a.php和b.php。如果a.php中包含檔案b.php,而b.php中包含檔案a.php,則無論執行a.php還是b.php,都會進入死迴圈。

     只要將第一個例子中的a加上包含b.php的語句,就可以得到一個很好的例子。死迴圈的原因還容易理解,這裡不做解釋。可能有人覺得項目開發時不會犯這種低級的錯誤。項目小的時候可能正確,但是一個大型的軟體多人合作,如何保證沒有潛在的執行環呢?再說,從維護的角度來說,這種設計也不合理。include_once和require_once     include_once和require_once在第一次執行時,其結果和include和require一樣。其後再遇到檔案包含關鍵詞(同組的關鍵詞)則會跳過不執行。

     假設有三個檔案:indexa.php、indexb.php和indexc.php。其原始碼如下:

indexa.php
<?phpinclude_once 'indexb.php';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am A<br>';?>

indexb.php
<?phpinclude_once 'indexa.php';include_once 'indexc.php';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am B<br>';?>

indexc.php
<?phpinclude_once 'indexb.php';include_once 'indexa.php';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am C<br>';?>

輸出如下:


/webapp/codesnipe/indexa.php
I am C
/webapp/codesnipe/indexa.php
I am B
/webapp/codesnipe/indexa.php
I am A

     執行檔案indexa.php,遇到包含語句包含indexb.php,所以讀入indexb.php的原始碼。indexb.php的原始碼的第一句就包含檔案indexa.php。由於indexa.php的內容已經存在,故該包含語句無效;第二局包含indexc.php。indexc.php的原始碼的第一句包含檔案indexb.php。基於indexb.php的內容已經存在,故該語句同樣無效;同樣的第二個語句也無效。最後程式執行,結果就如上面所示。     將任一個include_once語句換成require_once,程式執行一樣。因而在同組內,處理錯誤處理不同,並沒有什麼差別。     為了更形象地理解,我們可以設想php解析器會給每個執行檔案建立一個原始碼來源記錄表。記錄表記錄了原始碼被包含進來的檔案完整路徑。include_once和require_once會在每次包含新檔案時,檢查新檔案是否已經在記錄表中。如果已經存在,檔案內容不會被包含進來;否則檔案路徑被記錄入記錄表,並將其內容包含進來。與前一組的區別     這裡不需要多說,include和require並不檢查記錄表,這就是差別。通過這種方式,我們很容易解決潛在的死迴圈的問題,提高程式的可靠性。目錄結構導致的錯誤     檔案包含除了受到檔案內含項目關聯性影響,第二個重要因素就是檔案包含的目錄結構。前面的原始碼中我都包含了變數$_SERVER['PHP_SELF']的值。從輸出中可以看出變數的值是當前正在啟動並執行指令碼的名稱,就是直接運行請求的php檔案而不是包含進來的檔案。這個事實說明,被包含檔案的原始碼將被執行在直接執行檔案的環境中,不如最終要的檔案尋找路徑。     一個簡單的例子。項目包含一個檔案夾include,下面是兩個檔案indexb.php和indexc.php。和檔案夾include同目錄的是檔案indexa.php。原始碼如下:

indexa.php
<?phpinclude_once 'include/indexb.php';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am A<br>';?>

indexb.php
<?phpinclude_once './indexc.php';


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am B<br>';?>

indexc.php
<?php


echo $_SERVER['PHP_SELF'],'<br>';echo 'I am C<br>';?>

輸出如下:


Warning: include_once(./indexc.php) [function.include-once]: failed to open stream: No such file or directory in C:/xampp/htdocs/webapp/codesnipe/include/indexb.php on line 3

Warning: include_once() [function.include]: Failed opening './indexc.php' for inclusion (include_path='.;C:/xampp/php/pear/') in C:/xampp/htdocs/webapp/codesnipe/include/indexb.php on line 3
/webapp/codesnipe/indexa.php
I am B
/webapp/codesnipe/indexa.php
I am A


上面的輸出可以看出,indexb.php的原始碼中的"./indexc.php"中的"."指向的是indexa.php所在的目錄而不是include目錄本身,因而導致檔案尋找錯誤。如果把indexb.php中的"./indexc.php"改成"indexc.php",那麼指令碼將正常運行。這是因為php本身會有一個預設的檔案尋找路徑值。但是從可維護性角度來說,這種僥倖的正確時不可行的。一個解決方案     由於存在上面的問題,所以項目設計時會有一個系統的設定檔,在設定檔中設定系統的路徑值,通過這種方式來獲得要包含檔案的絕對路徑,從而避免上面的問題。具體的說明可見下一篇文章。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.