PHP 通過超全局數組獲取客戶端提交數據,理解三者差異、優先級、安全性,是構建健壯 Web 應用的基礎。
| 數組 | 數據來源 | HTTP 方法 | 典型場景 | 安全性 |
|---|---|---|---|---|
$_GET | URL 查詢字符串 | GET、HEAD | 搜索、分頁、篩選、可分享鏈接 | 低(明文、長度限制、日誌記錄) |
$_POST | 請求體 | POST、PUT、PATCH | 表單提交、文件上傳、敏感操作、大數據 | 中(不在 URL、但明文傳輸需 HTTPS) |
$_REQUEST | 合併:GET + POST + COOKIE | 所有 | 快速原型、兼容舊代碼 | **低(來源不確定、COOKIE 污染風險)** |
受 request_order (PHP 5.3+) 或 variables_order 配置影響,默認 GP (GET 後 POST,POST 覆蓋 GET),若包含 C 則 COOKIE 最後覆蓋。
// php.ini
request_order = "GPC" // GET → POST → COOKIE (後者覆蓋前者)
variables_order = "EGPCS" // 環境、GET、POST、COOKIE、SERVER
風險: 攻擊者可通過 Cookie 覆蓋 GET/POST 參數,繞過業務邏輯。
application/x-www-form-urlencoded:標準表單,自動填充 $_POSTmultipart/form-data:文件上傳,自動填充 $_POST + $_FILESapplication/json:不自動填充 $_POST,需 file_get_contents('php://input') 手動解析$raw = file_get_contents('php://input'); // 獲取原始請求體
// 適用:JSON API、XML RPC、原始文本、二進制數據
// 注意:只能讀取一次(除非啟用 php://temp 緩存)
// 搜索接口:明確用 GET
$keyword = $_GET['q'] ?? '';
$page = (int)($_GET['page'] ?? 1);
// 表單提交:明確用 POST
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 文件上傳
$avatar = $_FILES['avatar'] ?? null;
// 現代框架統一用 ServerRequestInterface
$request = $this->getRequest(); // 或從容器獲取
$keyword = $request->getQueryParams()['q'] ?? '';
$username = $request->getParsedBody()['username'] ?? '';
$jsonData = $request->getParsedBody(); // 已解析 JSON
// 白名單過濾
$allowed = ['name', 'email', 'age'];
$input = array_intersect_key($_POST, array_flip($allowed));
// 類型轉換與驗證
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 120]
]);
if ($age === false) { /* 驗證失敗 */ }
// 危險:來源不明,Cookie 可注入
$id = $_REQUEST['id'];
// 攻擊者設置 Cookie: id=malicious_sql
// 導致 SQL 注入、越權訪問等
client_max_body_size + PHP 邏輯截斷| 框架 | 獲取 GET | 獲取 POST | 獲取 JSON | 原始輸入 |
|---|---|---|---|---|
| Laravel | $request->query('key') | $request->input('key') | $request->input('key') (自動解析) | $request->getContent() |
| Symfony | $request->query->get('key') | $request->request->get('key') | json_decode($request->getContent(), true) | $request->getContent() |
| ThinkPHP | Request::get('key') | Request::post('key') | Request::param('key') (自動識別) | file_get_contents('php://input') |
| Yii2 | $request->get('key') | $request->post('key') | $request->getBodyParams() | $request->getRawBody() |
明確數據來源、拒絕隱式合併、統一驗證入口,是 PHP 參數處理的職業素養。