萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 接收表單提交資料完整指南:$_GET、$_POST、$_REQUEST 實戰詳解

前言

表單處理是 Web 開發最基礎的功能之一。PHP 透過超全域變數 $_GET、$_POST、$_REQUEST 接收客戶端提交的資料。本文詳細說明三者差異、使用時機、安全處理與完整實戰範例。

一、HTTP 請求方法與 PHP 超全域變數對應

HTTP MethodPHP 變數資料位置適用場景資料長度限制
GET$_GETURL 查詢字串搜尋、分頁、篩選、可分享連結~2000 字元(瀏覽器/伺服器限制)
POST$_POST請求主體登入、註冊、資料異動、檔案上傳、敏感資訊受 post_max_size 限制(預設 8MB)
GET/POST$_REQUEST兩者合併不建議使用(來源不明、安全風險)同上

二、HTML 表單基本結構

GET 表單範例

<form action="search.php" method="get">
    <label>關鍵字:<input type="text" name="keyword" /></label>
    <label>分類:
        <select name="category">
            <option value="">全部</option>
            <option value="tech">科技</option>
            <option value="life">生活</option>
        </select>
    </label>
    <button type="submit">搜尋</button>
</form>
<!-- 提交後 URL:search.php?keyword=php&category=tech -->

POST 表單範例(含檔案上傳)

<form action="register.php" method="post" enctype="multipart/form-data">
    <label>帳號:<input type="text" name="username" required /></label>
    <label>密碼:<input type="password" name="password" required /></label>
    <label>大頭照:<input type="file" name="avatar" accept="image/*" /></label>
    <button type="submit">註冊</button>
</form>

三、PHP 端接收與處理

1. 接收 GET 參數

<?php
// search.php
$keyword = $_GET['keyword'] ?? '';
$category = $_GET['category'] ?? 'all';

// 安全處理:輸出時轉義,防止 XSS
$safeKeyword = htmlspecialchars($keyword, ENT_QUOTES, 'UTF-8');
echo "搜尋關鍵字:$safeKeyword";
?>

2. 接收 POST 參數

<?php
// register.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = trim($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';
    
    // 驗證
    $errors = [];
    if ($username === '') $errors[] = '帳號不可為空';
    if (strlen($password) < 8) $errors[] = '密碼至少 8 字元';
    
    if (empty($errors)) {
        // 雜湊密碼、寫入資料庫...
        echo '註冊成功';
    } else {
        echo '錯誤:' . implode('、', $errors);
    }
}
?>

3. 同時支援 GET/POST 的彈性處理

<?php
// 明確指定來源,避免使用 $_REQUEST
$page = $_GET['page'] ?? 1;        // 分頁參數通常在 URL
$action = $_POST['action'] ?? '';  // 異動操作通常用 POST
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? ''; // API 金鑰從 Header 取得
?>

四、表單欄位類型與資料接收對照

HTML 欄位name 屬性PHP 取值方式備註
<input type="text">username$_POST['username']字串
<input type="checkbox">agreeisset($_POST['agree'])未勾選時不會送出,用 isset 判斷
<input type="checkbox"> 多個skills[]$_POST['skills'] 為陣列名稱加 [] 讓 PHP 自動解析為陣列
<input type="radio">gender$_POST['gender']同 name 群組,只會送出被選中的值
<select> 單選city$_POST['city']值為 option 的 value
<select multiple>cities[]$_POST['cities'] 為陣列名稱加 []
<textarea>content$_POST['content']含換行字元
<input type="file">avatar$_FILES['avatar']參考 $_FILES 結構

五、安全防護必做清單

  1. 輸入驗證:型別、長度、格式、範圍、業務規則
  2. 輸出轉義:htmlspecialchars($str, ENT_QUOTES, 'UTF-8') 防 XSS
  3. CSRF 保護:表單加入 <input type="hidden" name="csrf_token" value="...">,驗證 Session 中的 token
  4. 檔案上傳驗證:MIME 類型、副檔名、檔案大小、內容掃描、重新命名儲存
  5. SQL Injection 防護:使用 PDO Prepared Statements,絕不拼接 SQL 字串

六、完整實戰範例:留言板表單

form.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>留言板</title></head>
<body>
<form action="submit.php" method="post">
    <label>暱稱:<input type="text" name="nickname" maxlength="20" required /></label><br>
    <label>內容:<textarea name="content" rows="5" cols="40" required></textarea></label><br>
    <label><input type="checkbox" name="subscribe" value="1" /> 訂閱回覆通知</label><br>
    <button type="submit">送出留言</button>
</form>
</body></html>

submit.php

<?php
session_start();

function h($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); }

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit('Method Not Allowed');
}

// CSRF 驗證
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf_token'] ?? '')) {
    http_response_code(403);
    exit('CSRF token 無效');
}

$nickname = trim($_POST['nickname'] ?? '');
$content  = trim($_POST['content'] ?? '');
$subscribe = isset($_POST['subscribe']);

$errors = [];
if ($nickname === '') $errors[] = '暱稱不可為空';
if (mb_strlen($nickname) > 20) $errors[] = '暱稱不可超過 20 字元';
if ($content === '') $errors[] = '內容不可為空';

if (!empty($errors)) {
    echo '<ul><li>' . implode('</li><li>', array_map('h', $errors)) . '</li></ul>';
    echo '<a href="form.html">返回修正</a>';
    exit;
}

// 資料庫寫入(示意 PDO)
/*
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
$stmt = $pdo->prepare('INSERT INTO messages (nickname, content, subscribe, created_at) VALUES (?, ?, ?, NOW())');
$stmt->execute([$nickname, $content, $subscribe ? 1 : 0]);
*/

echo '留言送出成功!<a href="form.html">繼續留言</a>';
?>

七、常見問題 FAQ

Q: $_POST 為空陣列?
A: 檢查 enctype 是否正確(檔案上傳需 multipart/form-data)、post_max_size 是否過小、PHP 是否載入 php.ini 正確。
Q: 取得陣列值時出現 Notice?
A: 使用 $_POST['key'] ?? '' 或 isset($_POST['key']) 先判斷存在性。
Q: 中文亂碼?
A: 確認 HTML <meta charset="utf-8">、PHP 檔案儲存為 UTF-8、資料庫連線 SET NAMES utf8mb4。

總結

掌握 $_GET、$_POST 的差異與適用場景,明確指定資料來源,配合嚴格的輸入驗證與輸出轉義,是建構安全 PHP 表單處理的核心。拒絕使用 $_REQUEST,讓資料流向清晰可控。

copyright © 萬盛學電腦網 all rights reserved