web服務器經過代理后的絕對路徑問題,以及 dirname(__FILE__)和__DIR__
- 問題描述
- 情況解析
- 資源路徑分析
- 訪問過程分析
- dirname(\_\_FILE\_\_) 與 \_\_DIR\_\_
同步發布在個人筆記web服務器經過代理后的絕對路徑問題,以及 dirname(__FILE__)和__DIR__
問題描述
我有一個部署在自家網絡的服務器,為了實現在公網也可以訪問(內網穿透),我把web服務通過公網服務器上的 nginx + frp 方案進行了反向代理。實現方式參考這篇文章NGINX配合SSH/FRP反向代理實現內網穿透。
于是在某次使用絕對路徑訪問文件時,無論如何使用本地服務器上的絕對路徑都無法成功訪問。(確定內網服務器上的絕對路徑是正確的)
情況解析
原因是當我們通過公網服務器的代理服務訪問內網服務器上的資源時,如果使用的是內網服務器上的絕對路徑,由于套了一層殼,是不能正常訪問的。訪問者以為的絕對路徑將是公網服務器路徑與內網服務器路徑的一個結合。
資源路徑分析
以我的情況舉例,使用圖表展示的更清晰些。
內網服務器 | 公網服務器 | |
---|---|---|
文件名 | yourplugin.php | default.conf |
文件路徑 | /home/user/wordpress/wp-content/plugins/ | /var/www/html |
路徑拆分 | 根目錄:/home/user/wordpress/ 下級目錄:wp-content/plugins/ | 根目錄:/var/www/html/ |
內網服務器中需要注意的是(以 wordpress 項目為例),項目的根目錄是一定的,項目不同資源分布在根目錄下的不同下級目錄中。
公網服務器中關鍵的是 nginx 配置文件中設置的 root 位置,我的設置是 /var/www/html。具體可見NGINX 多域名訪問多端口應用。
訪問過程分析
以上文情況舉例,我想訪問 wordpress 項目下的 yourplugin.php 文件,需要使用下面這個 url。
URL:https://www.domain.com/wordpress/yourplugin
域名 | 后續字段 | |
---|---|---|
URL | www.domain.com | wordpress/yourplugin |
資源路徑 | 根目錄 | 下級目錄 |
當我們通過 url 來訪問 web 資源時,域名(形如 www.domain.com)被 nginx 等 web 程序解析到根目錄的位置;后續字段代表的是資源所在的下級目錄。這樣我們才可以通過 url 從世界各地都能訪問到特定服務器上的特定文件。
此時關注內網穿透情況下的訪問過程:
此時路徑結構就清晰了,考慮絕對路徑 = 根目錄 + 下級目錄,注意此時根目錄是在公網服務器上解析的,下級目錄是在內網服務器上解析的,所以:
內網穿透下絕對路徑 = 公網服務器根目錄 + 內網服務器下級目錄
參考文章第一個表格,重要路徑已經粗體強調,yourplugin.php 的絕對路徑應該為:/var/www/html/wp-content/plugins/yourplugin.php
。
dirname(__FILE__) 與 __DIR__
通過上述解析我們的確可以對每個資源都設置出可用的絕對路徑,但是在編程時采取此法則不甚明智。因為一些項目遷移等原因很容易使得路徑失效,并且也不方便。
在 php 中,我們可以使用 dirname(__FILE__) 和 __DIR__ 來方便的獲取當前資源的絕對路徑。
- dirname(__FILE__)
獲取當前資源所在的目錄的絕對路徑,例如/var/www/html/wp-content/plugins
。 - __DIR__
獲取當前資源本身的絕對路徑,例如/var/www/html/wp-content/plugins/yourplugin.php
。
常用方法:
#如果只是想調用這個文件本身,那么可以使用:
$filepath = __DIR__;#如果是想訪問當前文件同一目錄下的資源,那么可以使用:
$filepath = dirname(__FILE__) . '/text.txt'; #注意后綴的字符串需要有 / 。因為dirname最后一位不是 / ,需要我們補全。