2010-03-13 21 views
8

這很奇怪,有沒有人總結過一個結論呢?包含include()的相對路徑時,PHP會檢查哪些目錄?

有時它也會檢查包含文件的目錄。

但有時沒有。

d:\測試\ 1.PHP

<?php 

include('sub\2.php'); 

d:\測試\ 2.PHP

<?php 

include('3.php'); 

3.php是在相同的目錄作爲2.php

上述作品,但爲什麼呢?當前的目錄應該是D:\test,但它仍然可以找到3.php,這是D:\test\sub

更多故事最終

大約一年前,我遇到了這個問題,然後我結束了硬編碼像下面固定它:

的common.php:

if (file_exists("../../../Common/PHP/Config.inc")) 
    include('../../../Common/PHP/Config.inc'); 

if (file_exists("../../Common/PHP/Config.inc")) 
    include('../../Common/PHP/Config.inc'); 

if (file_exists("../Common/PHP/Config.inc")) 
    include('../Common/PHP/Config.inc'); 

if (file_exists("Common/PHP/Config.inc")) 
    include('Common/PHP/Config.inc'); 

Config.inc是在同一個目錄中Common.php

+1

好問題!我可以在Windows和Linux上確認這一點。我不知道這是爲什麼。 – 2010-03-13 12:03:25

+0

關於你的最後一個例子,如果「Config.inc」和「Common.php」在同一個目錄下,那麼這可以簡化爲include(dirname(__ FILE __)。/ Config.inc');工作,而不管'include_path'和哪個文件「Common.php」包含在內。如果沒有機會在include_path中找到Config.inc(通常包括當前目錄),那麼你可以簡單地調用include,Config.inc,雖然這可能效率較低,首先搜索「include_path」(失敗)。 – MrWhite 2015-02-10 17:55:35

+0

在你的第一個例子中,我假設「D:\ test \ 2.php」應該是「D:\ test \ sub \ 2.php」? (否則'include('sub \ 2.php');'永遠不會工作。) – MrWhite 2015-02-10 17:58:47

回答

1

它會檢查當前路徑,目錄中所列include_path

您可以運行phpinfo()查看包含路徑。

+0

這並不能解釋我描述的問題:( – user198729 2010-03-13 11:44:29

+0

@user據我所知,這就是它的全部。請顯示一些文件何時加載以及何時不加載的示例。 – 2010-03-13 11:46:44

+0

如果我們沒有明確地改變請求,'getcwd()'會在請求期間發生變化(比如'chdir()')。我會很快給出一個例子。 – user198729 2010-03-13 11:51:00

1

有時包含的文件是current working directory有時不是
當前目錄可以getcwd()

+0

嘿,我已經更新了我的問題,看看:) – user198729 2010-03-13 12:02:05

2

如果你看看源代碼在主/ fopen_wrappers.c PHP進行檢查的目錄,你會發現

/* check in calling scripts' current working directory as a fall back case 
    */ 
    if (zend_is_executing(TSRMLS_C)) { 
     char *exec_fname = zend_get_executed_filename(TSRMLS_C); 
     int exec_fname_length = strlen(exec_fname); 

     while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); 
     if (exec_fname && exec_fname[0] != '[' && 
      exec_fname_length > 0 && 
      exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { 
      memcpy(trypath, exec_fname, exec_fname_length + 1); 
      memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); 
      actual_path = trypath; 

這似乎是無條件執行的,因此將始終與包含/文件打開腳本可訪問的文件路徑相同...作爲include_path中指定的所有可能性之後的最後一個選擇。只有在include()中沒有定義相對路徑或絕對路徑時才適用。

+0

我似乎不明白這段代碼,有沒有一些線索,爲什麼有時它不檢查包含文件的目錄? – user198729 2010-03-13 13:45:25

+0

對於'3.php',它首先測試include \ _path中給出的所有位置。在那裏給出的相對路徑,例如'include_path =。; ..; lalala'將相對於當前工作目錄(不會被include()更改)。只有最後一個(額外的)選項是查找與包含文件相同的目錄。它「取」它可以找到的第一個「3.php」。那是你的問題:php會像你期望的那樣抓住另一個3.php?您的其他問題似乎表明... – VolkerK 2010-03-13 13:50:47

+0

我的問題有時它不會找到3.php,但我無法輕鬆再現它。但它與包含文件位於同一目錄中。也許當'包括'是在一個函數/方法,我猜... – user198729 2010-03-13 13:58:02

相關問題