$_POST 是 PHP 接收 HTTP POST 請求表單資料的核心超全域陣列。理解其運作機制、資料結構、安全處理與限制,是建構安全可靠表單處理的基礎。
Content-Type: application/x-www-form-urlencoded 或 multipart/form-data 的 HTTP POST 請求主體$_GET 較隱私name 屬性post_max_size),可在 php.ini 調整<form action="process.php" method="post">
<label>姓名: <input type="text" name="username" required></label><br>
<label>電子郵件: <input type="email" name="email" required></label><br>
<label>年齡: <input type="number" name="age" min="1" max="120"></label><br>
<label>興趣:
<select name="interests[]" multiple>
<option value="coding">程式設計</option>
<option value="reading">閱讀</option>
<option value="gaming">遊戲</option>
</select>
</label><br>
<button type="submit">送出</button>
</form>
<?php
// process.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 取得純量值
$username = $_POST['username'] ?? '';
$email = $_POST['email'] ?? '';
$age = (int)($_POST['age'] ?? 0);
// 取得陣列值(多選下拉、核取方塊群)
$interests = $_POST['interests'] ?? [];
// 驗證
$errors = [];
if (empty($username)) $errors[] = '姓名必填';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = '郵件格式錯誤';
if ($age < 1 || $age > 120) $errors[] = '年齡範圍 1-120';
if (empty($errors)) {
// 處理業務邏輯...
echo "感謝 $username 提交!";
} else {
echo "錯誤:" . implode(', ', $errors);
}
}
?>
| 輸入類型 | name 屬性 | $_POST 結構 |
|---|---|---|
| 文字、密碼、隱藏、Email、數字等 | name="field" | 字串 |
| 核取方塊 | name="agree" | 勾選時為 "on",未勾選不存在於 $_POST |
| 核取方塊群 | name="colors[]" | 陣列 ['red', 'blue'] |
| 單選按鈕 | name="gender" (同群組同名) | 選中項目的 value |
| 多選下拉 | name="items[]" | 陣列 |
| 檔案上傳 | name="file" | 不在 $_POST,在 $_FILES |
| 圖片按鈕 | name="submit" | ['submit_x' => 12, 'submit_y' => 34] |
<?php
// 錯誤:isset($_POST['agree']) 在值為 "0" 或 "" 時也為 true
// 正確:檢查是否存在於 POST 中
$agreed = isset($_POST['agree']); // 僅勾選時存在
// 或明確值
$newsletter = ($_POST['newsletter'] ?? '') === 'yes';
<?php
// 移除標籤、編碼特殊字元
$cleanInput = htmlspecialchars(trim($_POST['comment'] ?? ''), ENT_QUOTES, 'UTF-8');
// 數值轉型
$quantity = (int)($_POST['qty'] ?? 0);
$price = (float)($_POST['price'] ?? 0.0);
// 郵件驗證
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
if ($email === false) { /* 錯誤 */ }
// URL 驗證
$url = filter_var($_POST['url'] ?? '', FILTER_VALIDATE_URL);
// 正則驗證(如身分證字號)
$id = $_POST['id'] ?? '';
if (!preg_match('/^[A-Z][12]\d{8}$/', $id)) { /* 錯誤 */ }
<?php
// 顯示使用者輸入時務必編碼
echo "<div>您輸入:" . htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8') . "</div>";
// 屬性值雙重編碼
echo '<input value="' . htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8') . '">';
<?php
// 產生 Token(Session 中)
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// 表單中包含
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
// 驗證
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
die('CSRF Token 驗證失敗');
}
// 處理表單...
}
enctype="multipart/form-data" 表單同時產生 $_POST(文字欄位)與 $_FILES(檔案欄位)。
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="text" name="title">
<input type="file" name="document">
<button type="submit">上傳</button>
</form>
<?php
// upload.php
$title = $_POST['title'] ?? ''; // 文字欄位在 $_POST
$file = $_FILES['document'] ?? null; // 檔案在 $_FILES
?>
非標準表單(JSON、XML、原始資料)不會填入 $_POST,需讀取 php://input:
<?php
// JSON API 請求
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (json_last_error() === JSON_ERROR_NONE) {
// $data 為關聯陣列
$username = $data['username'] ?? '';
}
| 問題 | 原因 | 解決 |
|---|---|---|
| $_POST 為空 | method 非 POST、enctype 錯誤、post_max_size 超限 | 檢查 form method、enctype、php.ini 設定 |
| 陣列鍵名遺失 | name 屬性未加 []、未勾選核取方塊 | name="items[]"、isset() 檢查 |
| 中文亂碼 | 頁面編碼非 UTF-8、資料庫連線編碼錯誤 | HTML meta charset、PHP header、DB 連線皆設 UTF-8 |
| 大型表單截斷 | max_input_vars (預設 1000) 限制 | 調大 php.ini max_input_vars |
| 檔案上傳 $_POST 正常但 $_FILES 空 | upload_max_filesize 或 post_max_size 過小 | 調整 php.ini、檢查 $_FILES['error'] |
<?php
// 開發環境快速檢視
echo '<pre>';
var_dump($_POST);
echo '</pre>';
// 或寫入日誌
error_log('POST: ' . print_r($_POST, true));
$_POST['key'] ?? 'default' 避免 Undefined Array Key 警告(int), (float), (bool), (string)filter_var(), filter_input(INPUT_POST, 'key', FILTER_*)htmlspecialchars() 防 XSSpost_max_size, max_input_vars掌握 $_POST 運作細節與安全處理模式,是 PHP 表單開發的核心技能。配合現代驗證庫(如 Respect/Validation、Laravel Validator),能構建既安全又優雅的資料輸入介面。