在 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);
}
REQUEST_URI:包含查詢字符串、PATH_INFO,最完整,**首選**。PHP_SELF:不含查詢字符串,含 PATH_INFO,**次選**。SCRIPT_NAME:不含查詢字符串、不含 PATH_INFO,**兜底**。此順序最大程度保證在各種 SAPI (mod_php, CGI, FastCGI, CLI) 下都能獲取到可用路徑。
strrpos($uri, '/') + 1 目錄截取技巧strrpos 查找**最後一個**斜槓位置。+1 保留斜槓,確保結果以 / 結尾,便於直接拼接文件名 (如 $base . 'api.php')。$uri 為 / (根目錄),strrpos 返回 0,substr(..., 1) 仍返回 /,邏輯自洽。shtmlspecialchars() 的必要性輸出 URL 直接插入 HTML 屬性 (如 <a href="...">、<script src="...">) 時,若 HTTP_HOST 或路徑被污染 (罕見但理論可能),可能導致屬性閉合注入。**輸出編碼是纵深防御基本功**,不可省略。
原代碼硬編碼 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);
HTTP_HOST 風險若 Nginx 未正確設置 proxy_set_header Host $host;,或客戶端發送偽造 Host 頭,$_SERVER['HTTP_HOST'] 可能不可信。**最佳實踐**:在配置文件中顯式定義 $_SCONFIG['siteallurl'] (含協議、域名、目錄),函數優先返回配置值,完全繞過自動檢測的不可靠性。
| 框架 | 方法 | 特點 |
|---|---|---|
| Laravel | url()->current() / url()->full() | 基於 Illuminate\Http\Request,自動處理代理頭 (TrustedProxies 中間件) |
| Symfony | $request->getUri() / $request->getSchemeAndHttpHost() | Request 對象封裝,支持 Request::setTrustedProxies() |
| ThinkPHP | Request::instance()->root(true) / url() | 單例 Request,配置 app_url 可覆蓋 |
| Yii2 | Yii::$app->request->absoluteUrl / hostInfo | 組件化 Request,hostInfo 可配置 |
siteallurl (如 https://www.example.com/mysite/),避免自動檢測受 Header 攻擊、代理誤導。$scheme 邏輯,並配置信任代理頭。shtmlspecialchars / htmlspecialchars(..., ENT_QUOTES, 'UTF-8') 不可省略。$_SERVER 直接操作。