首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取當前站點完整 URL 的 getsiteurl() 函數實現解析

     編輯:PHP 綜合知識

函數作用

在 CMS、框架、模板引擎中常需動態獲取「當前站點的基礎 URL」(Scheme + Host + 目錄路徑),用於生成絕對鏈接、資源路徑、API 回調地址等。getsiteurl() 即為此類通用工具函數。

代碼邏輯解析

function getsiteurl() {
    global $_SCONFIG; // 全局配置數組

    // 1. 若配置中已顯式設置站點完整 URL,直接返回 (最高優先級,支持反向代理、負載均衡場景)
    if (!empty($_SCONFIG['siteallurl'])) {
        return $_SCONFIG['siteallurl'];
    }

    // 2. 自動檢測:依次嘗試 REQUEST_URI → PHP_SELF → SCRIPT_NAME
    $uri = $_SERVER['REQUEST_URI']
        ? $_SERVER['REQUEST_URI']
        : ($_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']);

    // 3. 截取目錄部分:從開頭到最後一個 '/' (含)
    // 例:/mysite/index.php → /mysite/ ; /admin/user/list → /admin/user/
    $base_path = substr($uri, 0, strrpos($uri, '/') + 1);

    // 4. 組裝完整 URL 並進行 HTML 特殊字符轉義 (防 XSS)
    return shtmlspecialchars('https://' . $_SERVER['HTTP_HOST'] . $base_path);
}

關鍵點深度剖析

1. 三元運算符鏈的容錯順序

  • REQUEST_URI:包含查詢字符串、PATH_INFO,最完整,**首選**。
  • PHP_SELF:不含查詢字符串,含 PATH_INFO,**次選**。
  • SCRIPT_NAME:不含查詢字符串、不含 PATH_INFO,**兜底**。

此順序最大程度保證在各種 SAPI (mod_php, CGI, FastCGI, CLI) 下都能獲取到可用路徑。

2. strrpos($uri, '/') + 1 目錄截取技巧

  • strrpos 查找**最後一個**斜槓位置。
  • +1 保留斜槓,確保結果以 / 結尾,便於直接拼接文件名 (如 $base . 'api.php')。
  • 若 $uri 為 / (根目錄),strrpos 返回 0,substr(..., 1) 仍返回 /,邏輯自洽。

3. shtmlspecialchars() 的必要性

輸出 URL 直接插入 HTML 屬性 (如 <a href="...">、<script src="...">) 時,若 HTTP_HOST 或路徑被污染 (罕見但理論可能),可能導致屬性閉合注入。**輸出編碼是纵深防御基本功**,不可省略。

4. 協議自動檢測缺失 (改進點)

原代碼硬編碼 https://,**不支持 HTTPS**。生產環境必須改為:

$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
// 或檢測反向代理頭
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $scheme = 'https';
}
return shtmlspecialchars($scheme . '://' . $_SERVER['HTTP_HOST'] . $base_path);

5. 反向代理/負載均衡下的 HTTP_HOST 風險

若 Nginx 未正確設置 proxy_set_header Host $host;,或客戶端發送偽造 Host 頭,$_SERVER['HTTP_HOST'] 可能不可信。**最佳實踐**:在配置文件中顯式定義 $_SCONFIG['siteallurl'] (含協議、域名、目錄),函數優先返回配置值,完全繞過自動檢測的不可靠性。

現代框架中的對應實現

框架方法特點
Laravelurl()->current() / url()->full()基於 Illuminate\Http\Request,自動處理代理頭 (TrustedProxies 中間件)
Symfony$request->getUri() / $request->getSchemeAndHttpHost()Request 對象封裝,支持 Request::setTrustedProxies()
ThinkPHPRequest::instance()->root(true) / url()單例 Request,配置 app_url 可覆蓋
Yii2Yii::$app->request->absoluteUrl / hostInfo組件化 Request,hostInfo 可配置

總結與建議

  1. 配置優先,檢測兜底:生產環境**務必**在配置文件寫死 siteallurl (如 https://www.example.com/mysite/),避免自動檢測受 Header 攻擊、代理誤導。
  2. 支持 HTTPS 自動檢測:補全 $scheme 邏輯,並配置信任代理頭。
  3. 輸出必經編碼:shtmlspecialchars / htmlspecialchars(..., ENT_QUOTES, 'UTF-8') 不可省略。
  4. 遷移至框架 Request 對象:新項目直接使用成熟框架的 URL 生成組件,拋棄全局函數與 $_SERVER 直接操作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved