我的 localhost 是 D:/001_htdocs,
在 D:/001_htdocs/path 資料夾內有放3個檔案,
檔名分別是:
index.php
require.php
image.gif
請問我在 index.php 內設定:
require_once( $_SERVER['DOCUMENT_ROOT'] . '/path/require.php' );
require_once( 'D:/001_htdocs/path/require.php' );
require_once( '/require.php' );
都可以正常執行。
但為何同樣在 index.php 內設定:
echo '<img src="' . $_SERVER['DOCUMENT_ROOT'] . '/path/image.gif" />';
echo '<img src="D:/001_htdocs/path/image.gif" />';
echo '<img src="/image.gif" />';
卻都無法顯示圖片,必須要設定下面這樣才行:
echo '<img src="/path/image.gif" />';
根目錄路徑觀念不太懂,請問可以教我一下嗎?
謝謝!
在 Server 上面,Document root 是 D:/001_htdocs/
,PHP 若沒額外限制的話,是可以讀取 Document root 外面的檔案的。當然你也可以隨意的更換 Document root 的位置。
在瀏覽器,Document root 永遠是 /
,瀏覽器不會知道(也不需要知道)你實際把檔案放在什麼位置,他就是在 Document root 底下找檔案而已。
所以當你使用路徑的時候,要區分清楚這個路徑是在 Server 端解釋,還是在瀏覽器端解釋。
瀏覽器看到的 /path/index.php
對應於 Server 的 {$document_root}/path/index.php
。對瀏覽器來說,絕對路徑都是 /
開頭的。這應該沒什麼問題。
/path/index.php
裡面若有個圖片路徑是 path/example.jpg
,因為是相對路徑,瀏覽器會先轉成絕對路徑,去 /path/path/example.jpg
找檔案。
而當瀏覽器看到一個路徑是 d:/htdocs/....
這樣的時候,你認為他會跑去讀取 Server 的 d:/
還是瀏覽器所在電腦的 d:/
?
答案是瀏覽器那台電腦的 d:/
。所以你那樣做是行不通的。
很久以前有一個很紅的網站為了節省流量,就利用這點將網站圖片另外做成安裝包,讓用戶安裝以後網站直接顯示用戶本地的圖檔,這樣就不會吃到 Server 的流量了。
所以說那個很紅的網站是 windows only?XD
froce 我記得他是有個選項可以切換從本機讀取圖片, 那個年代不光網站想省流量, 用戶頻寬也不高, 只是我已經忘記網站名稱了
謝謝 weiclin:
您說在 Server 上面,Document root 是 D:/001_htdocs/
所以以下2種方式都可以執行,這我了解了
require_once( $_SERVER['DOCUMENT_ROOT'] . '/path/require.php' );
require_once( 'D:/001_htdocs/path/require.php' );
而這邊不懂:
如果根目錄 / 的路徑是 D:/001_htdocs/
那麼
require_once( '/require.php' );
應該等於是
require_once( 'D:/001_htdocs/require.php' );
但為何他可以執行呢?
不是應該要從根目錄進到 path 資料夾找到 require.php 這個檔案才對嗎?
像是這樣
require_once( 'D:/001_htdocs/path/require.php' );
因為 php 不是單純找你指定的地方而已,官方文件裡面有這句:If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing.
可是這樣子反而會錯誤,請問是為什麼呢?
require_once( '/path/require.php' );
因為你又把瀏覽器的路徑跟 Server 的路徑搞混了吧,Server 在收到瀏覽器要求的時候,會把 /
變成 {$document_root}/
,但是在 php 裡面你打 /
就是 /
另外我在想可能是你跑在 Windows 的關係,不然以 /
開頭的路徑是絕對路徑,按理說 require_once( '/require.php' );
是找不到的,你可以上傳到 linux 之類的網頁空間試試
謝謝 weiclin:
我還是弄不太懂,
請問以我這個例子來說,瀏覽器的根目錄和 Server 的根目錄分別是哪個資料夾呢?
而 / 對於瀏覽器和 Server 分別代表哪個資料夾呢?
你弄不懂的跟哪個資料夾無關,而是對每個環節的行為不清楚。
瀏覽器送來的路徑,經過 web server 處理,在 document root 裡面找到對應的 php 檔案,然後執行 php 程式。所以 web server 才是負責把瀏覽器的路徑轉換成 server 實際的檔案路徑的部份。
php 根本就不管 document root 的,頂多有個環境變數紀錄一下是哪一個資料夾而已。在 linux 的環境原本就有個 /
根目錄,執行在 linux 的 php 看到路徑 /path/
會去找 linux 底下的 /path/
,不會去找 $document_root/path/
。
我了解囉,謝謝
1.在 index.php 中,程式碼是在你主機中執行的。所以 require_once 會去讀取你主機中的檔案。
2.但 echo 出去的,是傳到 browser 上給你 browser 解析的 HTML code。
3.所以請問你跟你網站瀏覽者的 browser 說,顯示「D:/001_htdocs/path/image.gif」(<img src="D:/001_htdocs/path/image.gif" />),你網站瀏覽者有辦法找的到你主機D槽下的檔案嗎?
另外說一點,從你的檔案路徑,可以得知你使用windows,那你有沒有注意到 「D:/001_htdocs/path/image.gif」跟你在windows上顯示的斜線方向不同?這在 unix like os 上有沒有不同?
這邊可能需要說明所謂的路徑問題。
一般來說,我以前在教人的時候,會先教,何謂主機路徑跟何謂web路徑。
主機路徑來說,一般是要給在php內部上使用的。可以不受web路徑的影響讀取web路徑外的東西。
而一般瀏覽器,是無法使用主機路徑的。而是使用web路徑。
我相信一般初學者可能看到這,就花花的了。
簡單來說好了。用上面的說法。
你的DOCUMENT_ROOT是在 D:/001_htdocs/
那這個網站的主機路徑就是 D:/001_htdocs/
其web路徑就是 / (且它無法在其主機路徑讀取其它非其目錄下的東西)
這邊就說一下為何會這樣說
如果今天這是主機路徑的情況下,你下達了如 ../test.txt 的路徑命令。
其主機路徑就會變成是在 D:/test.txt
但WEB路徑還是會在 /test.txt (因為它無法在往上一層)
看到這是不是又更花了??
總之,我一般都會在/index.php內先宣告如下的常數。
define('FCPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
這樣我就可以很單純的去載入我要的程式碼
require_once( FCPATH . '/path/require.php' );