$_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME']、$_SERVER['REQUEST_URI'] 都返回當前腳本路徑相關信息,但行為差異巨大,錯誤使用易導致安全漏洞(如 XSS)或路由錯誤。本文通過具體 URL 示例對比三者差異。
https://www.example.com/example/)| 訪問 URL | PHP_SELF | SCRIPT_NAME | REQUEST_URI |
|---|---|---|---|
https://www.example.com/example/ | /example/index.php | /example/index.php | / |
https://www.example.com/example/index.php | /example/index.php | /example/index.php | /example/index.php |
https://www.example.com/example/index.php?a=test | /example/index.php | /example/index.php | /example/index.php?a=test |
https://www.example.com/example/index.php/dir/test | /dir/test | /example/index.php | /example/index.php/dir/test |
/ 結尾,自動補全 index.php。PATH_INFO 部分(如 /dir/test),直接輸出到 HTML 表單 action 會導致 XSS(攻擊者構造 /script.php/">)。htmlspecialchars() 使用。/example/index.php)。| 場景 | 推薦變量 | 處理方式 |
|---|---|---|
| 表單 action | SCRIPT_NAME | htmlspecialchars($_SERVER['SCRIPT_NAME']) |
| 當前頁完整鏈接(含參數) | REQUEST_URI | 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] |
| 路由分發/框架入口 | REQUEST_URI | 解析 path、query、移除基礎路徑 |
| 生成 Canonical 標簽 | REQUEST_URI | 去除參數、統一斜杠 |
| 腳本自檢路徑 | SCRIPT_NAME | 直接比較 |
<?php
// ❌ 危險:直接輸出 PHP_SELF 導致 XSS
echo '<form action="' . $_SERVER['PHP_SELF'] . '">';
// ✅ 安全:使用 SCRIPT_NAME + 轉義
echo '<form action="' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '">';
// ✅ 現代框架做法:使用路由組件生成 URL,不直接依賴 $_SERVER
echo '<form action="' . $router->url('current') . '">';
?>
理解三者語義邊界,選對變量、做好轉義,是 PHP Web 安全與路由正確性的基石。