Skip to content

PHP 表单完整示例

网页开发中的常见需求是处理 HTML 表单。这包括在服务器端验证用户输入,并在验证失败时使用之前输入的值回填表单,以改善用户体验。

为了在用户提交表单后(尤其是在发生错误时)在输入字段中显示值,我们需要在 HTML 表单元素中嵌入 PHP 代码。

对于文本输入框(text inputs)、文本区域(textareas)和下拉选择框(select dropdowns),将 value 属性(或 <textarea> 的内容)设置为提交的值。对于单选按钮(radio buttons)和复选框(checkboxes),如果提交的值与按钮/复选框的值匹配,则动态添加 checked 属性。

重要安全提示: 在将用户提供的数据输出回 HTML 之前,务必进行转义,以防止跨站脚本攻击(Cross-Site Scripting, XSS)。使用 htmlspecialchars() 函数。

示例代码片段:

<!-- 姓名输入 -->
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="<?= htmlspecialchars($_POST['name'] ?? '') ?>">
<!-- 电子邮件输入 -->
<label for="email">E-mail:</label>
<input type="text" id="email" name="email" value="<?= htmlspecialchars($_POST['email'] ?? '') ?>">
<!-- 网站输入 -->
<label for="website">Website:</label>
<input type="text" id="website" name="website" value="<?= htmlspecialchars($_POST['website'] ?? '') ?>">
<!-- 评论文本区域 -->
<label for="comment">Comment:</label>
<textarea id="comment" name="comment" rows="5" cols="40"><?= htmlspecialchars($_POST['comment'] ?? '') ?></textarea>
<!-- 性别单选按钮 -->
<fieldset>
<legend>Gender:</legend>
<input type="radio" id="female" name="gender" value="female" <?= (($_POST['gender'] ?? '') === 'female') ? 'checked' : '' ?>>
<label for="female">Female</label>
<input type="radio" id="male" name="gender" value="male" <?= (($_POST['gender'] ?? '') === 'male') ? 'checked' : '' ?>>
<label for="male">Male</label>
</fieldset>
<!-- 注意:?? '' (空值合并运算符) 在 POST 变量未设置时提供一个空的默认值,防止页面初次加载时出错。 -->

这是一个演示使用现代 PHP 实践进行服务器端验证和表单回填的完整示例。

<?php
// 初始化错误和提交数据的变量
$errors = [];
$formData = [
'name' => '',
'email' => '',
'website' => '',
'comment' => '',
'gender' => ''
];
// --- 表单处理逻辑 ---
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// 基本清洗(移除空白字符)
$formData['name'] = trim($_POST['name'] ?? '');
$formData['email'] = trim($_POST['email'] ?? '');
$formData['website'] = trim($_POST['website'] ?? '');
$formData['comment'] = trim($_POST['comment'] ?? '');
$formData['gender'] = $_POST['gender'] ?? ''; // 单选/选择框不需要 trim
// --- 验证规则 ---
// 姓名验证
if (empty($formData['name'])) {
$errors['name'] = "Name is required";
} elseif (!preg_match("/^[a-zA-Z-' ]*$/", $formData['name'])) { // 允许字母、空白字符、连字符、撇号
$errors['name'] = "Only letters, hyphens, apostrophes and white space allowed";
}
// 电子邮件验证
if (empty($formData['email'])) {
$errors['email'] = "Email is required";
} elseif (!filter_var($formData['email'], FILTER_VALIDATE_EMAIL)) {
$errors['email'] = "Invalid email format";
}
// 网站验证(可选字段)
if (!empty($formData['website'])) {
// 使用 filter_var 进行健壮的 URL 验证
if (!filter_var($formData['website'], FILTER_VALIDATE_URL)) {
$errors['website'] = "Invalid URL format";
}
}
// 评论验证(可选 - 示例:如果需要,检查长度)
// if (!empty($formData['comment']) && strlen($formData['comment']) > 500) {
// $errors['comment'] = "Comment cannot exceed 500 characters";
// }
// 性别验证
if (empty($formData['gender'])) {
$errors['gender'] = "Gender is required";
} elseif (!in_array($formData['gender'], ['female', 'male'])) { // Validate against expected values
$errors['gender'] = "Invalid gender selected";
}
// --- 检查验证是否通过 ---
if (empty($errors)) {
// 处理有效数据(例如,保存到数据库,发送电子邮件)
// ...
echo "<p style='color:green;'>Form submitted successfully!</p>";
// 可选:重定向或清除表单数据
// header('Location: thank_you.php');
// exit;
} else {
echo "<p style='color:red;'>Please fix the errors below.</p>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>PHP Form Example</title>
<style>
.error { color: #FF0000; }
label { display: block; margin-top: 10px; }
input[type=text], textarea { width: 300px; }
fieldset { border: 1px solid #ccc; padding: 10px; margin-top: 10px; width: 300px; }
legend { font-weight: bold; }
</style>
</head>
<body>
<h2>PHP Form Validation Example</h2>
<form method="post" action="<?= htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="<?= htmlspecialchars($formData['name']) ?>">
<span class="error"><?= $errors['name'] ?? '' ?></span>
<label for="email">E-mail:</label>
<input type="text" id="email" name="email" value="<?= htmlspecialchars($formData['email']) ?>">
<span class="error"><?= $errors['email'] ?? '' ?></span>
<label for="website">Website:</label>
<input type="text" id="website" name="website" value="<?= htmlspecialchars($formData['website']) ?>">
<span class="error"><?= $errors['website'] ?? '' ?></span>
<label for="comment">Comment:</label>
<textarea id="comment" name="comment" rows="5" cols="40"><?= htmlspecialchars($formData['comment']) ?></textarea>
<span class="error"><?= $errors['comment'] ?? '' ?></span>
<fieldset>
<legend>Gender:</legend>
<input type="radio" id="female" name="gender" value="female" <?= ($formData['gender'] === 'female') ? 'checked' : '' ?>>
<label for="female" style="display:inline;">Female</label>
<input type="radio" id="male" name="gender" value="male" <?= ($formData['gender'] === 'male') ? 'checked' : '' ?>>
<label for="male" style="display:inline;">Male</label>
<br><span class="error"><?= $errors['gender'] ?? '' ?></span>
</fieldset>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
  • CSRF 防护: 实际应用必须实现跨站请求伪造(Cross-Site Request Forgery, CSRF)防护,通常使用令牌(token)。本示例为简化而省略。
  • 数据清洗(Sanitization)与验证(Validation): 验证检查数据是否符合正确的格式。数据清洗清理或修改数据(例如,用于输出的 trim()、htmlspecialchars(),或在存储到数据库前移除潜在有害代码)。请适当应用它们。
  • 错误显示: 示例在字段旁边显示错误。您可能更喜欢在顶部显示错误汇总列表或其他 UI 方法。
  • 框架: 现代 PHP 框架(如 Laravel, Symfony)提供了强大的组件用于表单处理、验证和安全,极大地简化了此过程。