PHP: 表单处理
如果说 PHP 有一张王牌,那就是处理表单。别的语言需要装框架才能做的事,PHP 从出生那天就会——这节课让你掌握 Web 开发中最实用的技能。
1. HTML 表单基础回顾
HTML
<form method="POST" action="process.php">
<!-- 各种表单字段 -->
<button type="submit">提交</button>
</form>
| 属性 | 值 | 说明 |
|---|---|---|
method |
GET 或 POST |
GET=查询,POST=修改数据 |
action |
URL(""=当前页) |
数据提交到哪里 |
name |
字段名 | 必须设置,PHP 用这个名字取数据 |
🔥 易错: 表单字段必须有
name 属性。没有 name 的字段,PHP 收不到它的数据。
2. 各种表单字段的数据接收
(1) 文本类字段
PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$bio = $_POST['bio'] ?? '';
}
?>
<form method="POST" action="">
<input type="text" name="name" placeholder="用户名"><br>
<input type="email" name="email" placeholder="邮箱"><br>
<input type="password" name="password" placeholder="密码"><br>
<textarea name="bio" placeholder="个人简介"></textarea><br>
<button type="submit">注册</button>
</form>
(2) 选择类字段(单选/复选框/下拉)
▶ 示例:选择类字段处理
PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$gender = $_POST['gender'] ?? '';
$skills = $_POST['skills'] ?? []; // 复选框返回数组
$city = $_POST['city'] ?? '';
echo "性别:{$gender}<br>";
echo "技能:" . implode(', ', $skills) . "<br>";
echo "城市:{$city}<br>";
}
?>
<form method="POST" action="">
<label>性别:</label>
<input type="radio" name="gender" value="male"> 男
<input type="radio" name="gender" value="female"> 女
<br>
<label>掌握技能:</label>
<input type="checkbox" name="skills[]" value="php"> PHP
<input type="checkbox" name="skills[]" value="mysql"> MySQL
<input type="checkbox" name="skills[]" value="js"> JavaScript
<br>
<label>城市:</label>
<select name="city">
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<br>
<button type="submit">提交</button>
</form>
⚠️ 注意: 复选框的
name 必须写成 skills[](带方括号),PHP 才会把所有选中值打包成一个数组。否则只能收到最后一个选中的值。
3. 表单回显(保留用户已输入的内容)
用户填了一半提交失败,表单内容全没了——这是最让人崩溃的体验。用 PHP 轻松解决:
▶ 示例:带错误回显的完整表单
PHP
<?php
$errors = [];
$name = $email = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($name === '') {
$errors[] = '用户名不能为空';
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = '邮箱格式不正确';
}
if (empty($errors)) {
echo "<h3 style='color:green'>注册成功!欢迎,{$name}!</h3>";
$name = $email = ''; // 成功后清空表单
} else {
echo "<ul style='color:red'>";
foreach ($errors as $e) echo "<li>{$e}</li>";
echo "</ul>";
}
}
?>
<form method="POST" action="">
<input type="text" name="name" placeholder="用户名"
value="<?= htmlspecialchars($name) ?>"><br>
<input type="email" name="email" placeholder="邮箱"
value="<?= htmlspecialchars($email) ?>"><br>
<button type="submit">注册</button>
</form>
💡 提示:
htmlspecialchars() 是关键——防止用户输入中的 " < > 破坏 HTML 结构或注入脚本(XSS 攻击)。第 18 课表单验证会详细讲安全防护。
4. 单选/复选框的回显
PHP
<?php
$gender = $_POST['gender'] ?? 'male';
$skills = $_POST['skills'] ?? [];
?>
<!-- 单选:用 checked 属性 -->
<input type="radio" name="gender" value="male"
<?= $gender === 'male' ? 'checked' : '' ?>> 男
<!-- 复选框:用 in_array 检查 -->
<input type="checkbox" name="skills[]" value="php"
<?= in_array('php', $skills) ? 'checked' : '' ?>> PHP
<!-- 下拉框:用 selected 属性 -->
<select name="city">
<option value="beijing" <?= $city === 'beijing' ? 'selected' : '' ?>>北京</option>
</select>
5. 检测表单提交
PHP
<?php
// 方法1:检测请求方法(推荐)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 处理表单
}
// 方法2:检测提交按钮是否存在
if (isset($_POST['submit'])) {
// 处理表单
}
// 方法3:直接检查是否有POST数据
if (!empty($_POST)) {
// 处理表单
}
?>
6. PRG 模式(POST-Redirect-GET)
用户提交表单后点刷新会重复提交——PRG 模式根治此问题:
PHP
<?php
// prg.php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 处理数据
$name = trim($_POST['name'] ?? '');
// 存到 Session 用于显示
$_SESSION['flash_message'] = "注册成功,{$name}!";
// 重定向到当前页(GET请求)
header("Location: " . $_SERVER['PHP_SELF']);
exit;
}
// 显示 flash 消息
if (isset($_SESSION['flash_message'])) {
echo "<div style='color:green'>{$_SESSION['flash_message']}</div>";
unset($_SESSION['flash_message']);
}
?>
<form method="POST" action="">
<input type="text" name="name" placeholder="用户名">
<button type="submit">注册</button>
</form>
💡 提示:
header("Location: ...") 做重定向,exit 立即终止脚本。PRG 模式流程:POST 处理完数据 → 重定向到 GET 页面 → 用户在 GET 页面刷新也不会重复提交。
❓ 常见问题
Q 为什么我的复选框总收不到数据?
A 检查 name 有没有写
[](如 skills[])。普通 name 只能收最后一个值,name[] 才能收数组。Q 用户禁用了 JavaScript,表单还能工作吗?
A 完全能!PHP 的表单处理完全在服务器端,不依赖 JS。JS 只是让体验更好(前端验证、AJAX 提交),但核心功能不需要 JS。
Q
header("Location: ...") 报错怎么办?A 最常见原因是
header() 之前已经有输出了(包括 echo、HTML、甚至 PHP 标签前的空白和 BOM)。确保 header() 在所有输出之前,且 PHP 文件是 UTF-8 without BOM 编码。📖 小节
- 表单字段必须有
name属性,PHP 才能取到数据 - 不同字段类型(text/radio/checkbox/select)的接收方式不同
value="..."实现文本回显,checked/selected实现选择回显htmlspecialchars()防 XSS 攻击$_SERVER['REQUEST_METHOD']判断 GET/POST- PRG 模式防重复提交:POST 处理 → redirect → GET 显示
📝 作业
- 创建一个完整的用户注册表单,包含:用户名、邮箱、密码、性别(单选)、兴趣(多选)、城市(下拉框)。提交后用
var_dump查看所有接收到的数据。 - 给上面的表单加上错误验证和回显:用户名不能空、邮箱格式检查、必须选择性别。验证失败时保留用户已填的内容。
- 实现 PRG 模式:注册成功后重定向到同一个页面,显示绿色的"注册成功"消息。