在 PHP 開發中,處理用戶提交的表單資料是最基礎也最關鍵的環節。PHP 提供了三個主要的超全域陣列變數來接收資料:$_POST、$_GET 和 $_REQUEST。理解它們的差異、適用場景及潛在風險,對於構建安全、健壯的應用至關重要。
$_POST 是一個關聯陣列,專門用於儲存透過 HTTP POST 方法提交的表單資料。POST 方法的特點是資料包含在 HTTP 請求主體中,不會顯示在 URL 裡,適合傳輸敏感資訊(如密碼)或大量資料。
<form action="handle.php" method="post">
<label>用戶名:<input type="text" name="username"></label>
<label>密碼:<input type="password" name="password"></label>
<input type="submit" value="登入">
</form>
<?php
// 獲取單一欄位
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 除錯:查看所有 POST 資料
var_dump($_POST);
?>
注意:鍵名必須與表單 name 屬性完全一致,且區分大小寫。
$_GET 同樣是關聯陣列,儲存 URL 查詢字串中的參數(即 ? 後面的 key=value 對)。GET 請求適用於資料檢索、分頁、搜尋等無副作用的操作。
表單的 action 屬性若包含查詢字串,且 method 為 post,則會同時產生 GET 和 POST 資料:
<form action="handle.php?source=sidebar&ref=home" method="post">
<input type="text" name="keyword">
<input type="submit">
</form>
此時:
$_GET['source'] = 'sidebar'$_GET['ref'] = 'home'$_POST['keyword'] = 用戶輸入值$_REQUEST 並非獨立資料來源,而是 $_GET、$_POST(及 $_COOKIE)的合併陣列。其合併順序由 php.ini 的 request_order 指令決定(預設 "GP",即先 GET 後 POST,同名鍵 POST 會覆蓋 GET)。
若 URL 為 ?id=100,表單隱藏欄位 name="id" value="200":
$_GET['id'] = '100'$_POST['id'] = '200'$_REQUEST['id'] = '200'(預設 GP 順序)最佳實踐: 明確使用 $_GET 或 $_POST,避免使用 $_REQUEST,以提高程式碼可讀性並防止資料來源混淆導致的安全漏洞(如 CSRF)。
$_SERVER 包含伺服器環境、請求標頭、腳本路徑等關鍵資訊。常用鍵值:
| 鍵名 | 說明 |
|---|---|
REMOTE_ADDR | 用戶端 IP 位址 |
SERVER_ADDR | 伺服器 IP 位址 |
SERVER_NAME | 伺服器主機名 |
DOCUMENT_ROOT | 網站根目錄絕對路徑 |
PHP_SELF | 當前腳本路徑(相對於 Document Root) |
QUERY_STRING | 原始查詢字串(不含 ?) |
REQUEST_URI | 完整請求 URI(含查詢字串) |
HTTP_USER_AGENT | 用戶端瀏覽器標識 |
REQUEST_METHOD | 請求方法(GET、POST 等) |
<?php
// 獲取用戶真實 IP(考慮代理)
function getClientIP() {
$keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
foreach ($keys as $key) {
if (!empty($_SERVER[$key])) {
$ips = explode(',', $_SERVER[$key]);
return trim($ips[0]);
}
}
return 'unknown';
}
?>
$_GET(查詢/分頁)或 $_POST(狀態變更/敏感資料)。filter_input()、filter_var() 或驗證庫進行嚴格校驗。掌握這三大超全域變數的特性與邊界,是編寫安全、可維護 PHP 應用的基石。