| 函數 | 用途 | 回傳值範例 |
php_uname('s') | 作業系統名稱 | Linux, Windows NT, Darwin |
php_uname('r') | OS 版本 | 5.15.0-91-generic |
php_uname('m') | 硬體架構 | x86_64, arm64 |
php_sapi_name() | PHP 運行模式 | fpm-fcgi, cli, apache2handler |
phpversion() | PHP 版本 | 8.3.2 |
zend_version() | Zend Engine 版本 | 4.3.2 |
getmypid() | 當前進程 PID | 12345 |
get_current_user() | 腳本擁有者 | www-data |
memory_get_usage() | 記憶體使用量 | 2097152 (bytes) |
memory_get_peak_usage() | 記憶體峰值 | 4194304 |
disk_free_space('/') | 磁碟剩餘空間 | 10737418240 |
sys_getloadavg() | 系統負載 | [0.52, 0.58, 0.59] |
實用封裝類別:ServerInfo
class ServerInfo {
public static function getClientIp(): string {
$headers = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'];
foreach ($headers as $header) {
if (!empty($_SERVER[$header])) {
$ips = explode(',', $_SERVER[$header]);
return trim($ips[0]);
}
}
return 'unknown';
}
public static function getHost(): string {
return $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'unknown';
}
public static function getProtocol(): string {
return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
public static function getFullUrl(): string {
return self::getProtocol() . '://' . self::getHost() . ($_SERVER['REQUEST_URI'] ?? '/');
}
public static function isAjax(): bool {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}
public static function isHttps(): bool {
return self::getProtocol() === 'https';
}
public static function getUserAgent(): string {
return $_SERVER['HTTP_USER_AGENT'] ?? '';
}
public static function isMobile(): bool {
$ua = strtolower(self::getUserAgent());
$mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'phone', 'tablet'];
foreach ($mobileKeywords as $keyword) {
if (strpos($ua, $keyword) !== false) return true;
}
return false;
}
public static function getOs(): array {
return [
'name' => php_uname('s'),
'version' => php_uname('r'),
'arch' => php_uname('m'),
];
}
public static function getPhpInfo(): array {
return [
'version' => phpversion(),
'sapi' => php_sapi_name(),
'zend' => zend_version(),
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'upload_max_filesize' => ini_get('upload_max_filesize'),
'post_max_size' => ini_get('post_max_size'),
];
}
}
安全性注意事項
| 風險 | 說明 | 防範 |
| HTTP 標頭偽造 | HTTP_X_FORWARDED_FOR 等可被客戶端竄改 | 僅信任受信任 Proxy 之後的標頭 |
| PHP_SELF XSS | <form action="<?= $_SERVER['PHP_SELF'] ?>"> 可注入腳本 | 使用 htmlspecialchars($_SERVER['PHP_SELF']) 或留空 action |
| 資訊洩露 | 錯誤頁面顯示 $_SERVER 內容 | 生產環境關閉 display_errors |
| 內網 IP 洩露 | SERVER_ADDR 可能洩露內部架構 | 避免在前端輸出 |
常見應用場景
// 1. 建構標準 API 回應元資料
function apiResponse($data, $meta = []) {
return json_encode([
'data' => $data,
'meta' => array_merge([
'timestamp' => $_SERVER['REQUEST_TIME_FLOAT'],
'request_id' => $_SERVER['HTTP_X_REQUEST_ID'] ?? uniqid('req_'),
'server' => gethostname(),
], $meta),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
// 2. 速率限制識別鍵
$rateLimitKey = 'ratelimit:' . ServerInfo::getClientIp() . ':' . $_SERVER['REQUEST_URI'];
// 3. 多語系自動偵測
function detectLocale(): string {
$acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'zh-TW';
$locales = ['zh-TW', 'zh-CN', 'en-US', 'ja-JP'];
foreach (explode(',', $acceptLang) as $lang) {
$lang = trim(explode(';', $lang)[0]);
if (in_array($lang, $locales)) return $lang;
}
return 'zh-TW';
}
// 4. 維護模式檢查
if (file_exists(__DIR__ . '/.maintenance') && ServerInfo::getClientIp() !== '192.168.1.100') {
http_response_code(503);
die('系統維護中');
}
掌握 $_SERVER 與核心函數,能讓 PHP 程式「感知」執行環境,做出智慧決策:自適應部署、精準日誌、安全防護、效能監控。記住:HTTP 標頭不可信,伺服器變數相對可信,核心函數最可信。
- 上一篇文章: PHP 實作多搜尋引擎跳轉:關鍵字導向 Google、Yahoo、百度
- 下一篇文章: PHPDoc 註釋規範深度解析:從標籤語法到團隊協作最佳實踐
Copyright ©
程式碼之家 All Rights Reserved