$_SERVER 是 PHP 最核心的超全局變量之一,包含了服務器環境、請求頭、腳本路徑等關鍵信息。本文系統梳理常用鍵值的含義、差異、安全風險與實戰用法,助你精準獲取域名、路徑、客戶端 IP 等信息。
| 鍵名 | 含義 | 示例值 | 可靠性/備註 |
|---|---|---|---|
| HTTP_HOST | 客戶端發送的 Host 頭 | example.com:8080 | 可偽造,需驗證 |
| SERVER_NAME | 服務器配置的主機名 | example.com | 較可靠,取決於 Apache/Nginx 配置 |
| REQUEST_URI | 請求的 URI(含查詢字符串) | /path/to/page?id=1&name=test | 不含域名,以 / 開頭 |
| PHP_SELF | 當前腳本相對文檔根目錄路徑 | /index.php | 含查詢字符串時需注意 XSS |
| SCRIPT_FILENAME | 當前執行腳本的絕對路徑 | /var/www/html/index.php | 最可靠的腳本路徑 |
| DOCUMENT_ROOT | Web 根目錄絕對路徑 | /var/www/html | Apache/Nginx root 指令值 |
| REQUEST_METHOD | HTTP 請求方法 | GET/POST/PUT/DELETE | 標準方法 |
| QUERY_STRING | 查詢字符串(不含 ?) | id=1&name=test | 同 parse_url URL 的 query |
| REMOTE_ADDR | 客戶端 IP | 192.168.1.100 | 代理下需看 X-Forwarded-For |
| HTTP_USER_AGENT | 客戶端 User-Agent | Mozilla/5.0... | 可偽造 |
| HTTP_REFERER | 來源頁面 URL | https://google.com/ | 可為空、可偽造 |
| HTTPS | 是否 HTTPS 請求 | on / 空 | Apache 模式;Nginx 需配置 fastcgi_param |
| SERVER_PORT | 服務器端口 | 80 / 443 | |
| SERVER_PROTOCOL | 協議版本 | HTTP/1.1 |
<?php
function getCurrentUrl(): string {
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
$uri = $_SERVER['REQUEST_URI'] ?? '';
return $scheme . '://' . $host . $uri;
}
?>
<?php
function getClientIp(): string {
$proxyHeaders = [
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'HTTP_CLIENT_IP',
'HTTP_CF_CONNECTING_IP', // Cloudflare
];
foreach ($proxyHeaders as $header) {
if (!empty($_SERVER[$header])) {
$ips = explode(',', $_SERVER[$header]);
$ip = trim($ips[0]);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
return $ip;
}
}
}
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}
?>
<?php
function isAjax(): bool {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}
?>
<?php
// 入口文件 index.php 中定義
define('ROOT_PATH', dirname($_SERVER['SCRIPT_FILENAME']));
// 或使用 __DIR__(推薦,PHP 5.3+)
define('ROOT_PATH', __DIR__);
?>
<?php
function asset(string $path): string {
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$base = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
return "$scheme://$host$base/$path";
}
// 使用:asset('css/app.css') → https://example.com/project/css/app.css
?>
<?php
// ❌ 危險:攻擊者訪問 /index.php/">
// $_SERVER['PHP_SELF'] 會包含 /">
echo '<form action="' . $_SERVER['PHP_SELF'] . '">';
// ✅ 安全:使用 htmlspecialchars 或 $_SERVER['SCRIPT_NAME']
echo '<form action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '">';
// 或
echo '<form action="' . $_SERVER['SCRIPT_NAME'] . '">';
?>
<?php
// ❌ 危險:生成密碼重置鏈接、Canonical URL 等
$resetLink = "https://{$_SERVER['HTTP_HOST']}/reset?token=$token";
// ✅ 安全:使用配置文件定義的可信域名
$trustedHost = 'example.com'; // 從配置讀取
$resetLink = "https://$trustedHost/reset?token=$token";
?>
<?php
// ❌ 危險
$file = $_SERVER['DOCUMENT_ROOT'] . $_GET['path'];
// ✅ 安全:實際路徑解析 + 白名單校驗
$requested = realpath($_SERVER['DOCUMENT_ROOT'] . '/' . $_GET['path']);
$allowed = realpath($_SERVER['DOCUMENT_ROOT'] . '/public');
if ($requested && strpos($requested, $allowed) === 0) {
// 安全訪問
}
?>
Nginx 預設不傳遞某些變量,需在 fastcgi_params 或站點配置中顯式設置:
# nginx.conf / site.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
fastcgi_param HTTP_X_REAL_IP $remote_addr;
<?php
// 僅開發環境使用
echo '<pre>';
print_r($_SERVER);
echo '</pre>';
// 或保存到文件分析
file_put_contents('/tmp/server_dump_' . time() . '.txt', print_r($_SERVER, true));
?>
$_SERVER 是通往服務器環境與請求上下文的橋樑。掌握核心鍵值語義、區分可信與不可信來源、做好輸出轉義與輸入驗證,是編寫安全、可移植 PHP 應用的基石。建議封裝為 Request 類統一訪問,集中處理代理、HTTPS、Host 等環境差異。