首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 入門

PHP $_POST 超全域變數完整指南:表單資料接收、安全處理與最佳實踐

     編輯:PHP 入門

PHP $_POST 超全域變數完整指南

$_POST 是 PHP 接收 HTTP POST 請求表單資料的核心超全域陣列。理解其運作機制、資料結構、安全處理與限制,是建構安全可靠表單處理的基礎。

基本特性

  • 資料來源:Content-Type: application/x-www-form-urlencoded 或 multipart/form-data 的 HTTP POST 請求主體
  • 可見性:不顯示於 URL(Address Bar),相對 $_GET 較隱私
  • 資料結構:關聯陣列,鍵名對應表單 name 屬性
  • 大小限制:預設 8MB(post_max_size),可在 php.ini 調整
  • 作用域:超全域,所有函數、類別、檔案皆可直接存取

基本表單與接收範例

HTML 表單

<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 接收處理

<?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';

安全處理:輸入驗證與過濾

1. 過濾輸入

<?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)) { /* 錯誤 */ }

2. 防止 XSS:輸出編碼

<?php
// 顯示使用者輸入時務必編碼
echo "<div>您輸入:" . htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8') . "</div>";

// 屬性值雙重編碼
echo '<input value="' . htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8') . '">';

3. CSRF 保護

<?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 驗證失敗');
    }
    // 處理表單...
}

檔案上傳與 $_POST 關係

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));

最佳實踐總結

  1. 永遠驗證:不信任任何 $_POST 資料
  2. 使用 Null 合併操作符:$_POST['key'] ?? 'default' 避免 Undefined Array Key 警告
  3. 明確轉型:(int), (float), (bool), (string)
  4. 過濾器優先:filter_var(), filter_input(INPUT_POST, 'key', FILTER_*)
  5. CSRF Token 保護:所有狀態變更表單必須驗證
  6. 輸出時編碼:htmlspecialchars() 防 XSS
  7. 限制大小:設定合理 post_max_size, max_input_vars
  8. 記錄稽核:重要操作記錄 $_POST 內容(移除敏感欄位)

掌握 $_POST 運作細節與安全處理模式,是 PHP 表單開發的核心技能。配合現代驗證庫(如 Respect/Validation、Laravel Validator),能構建既安全又優雅的資料輸入介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved