Skip to content

PHP 表单处理

PHP 表单处理:安全地处理用户输入

Section titled “PHP 表单处理:安全地处理用户输入”

HTML 表单是用户与 Web 应用程序交互的主要方式。PHP 提供了机制来接收和处理通过这些表单提交的数据,使用的超全局数组(superglobal arrays)是 $_GET 和 $_POST。

安全性至关重要,尤其是在处理表单数据时。永远不要直接信任用户输入。在使用之前,务必在服务器端(server-side)验证(validate)并清理(sanitize)数据。

这个示例展示了一个基本的 HTML 表单,包含姓名和电子邮件字段,使用 POST 方法提交数据。

文件:user_form.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Form</title>
</head>
<body>
<h2>User Information Form</h2>
<form action="welcome.php" method="post">
<div>
<label for="name">Name:</label><br>
<input type="text" id="name" name="user_name" required>
</div>
<br>
<div>
<label for="email">E-mail:</label><br>
<input type="email" id="email" name="user_email" required>
</div>
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>

当用户填写此表单并点击“Submit”时,浏览器会通过 HTTP POST 请求将数据(user_name 和 user_email)发送到 action 属性中指定的 welcome.php 脚本。

在 PHP 中处理表单数据 (welcome.php)

Section titled “在 PHP 中处理表单数据 (welcome.php)”

PHP 脚本在 $_POST 超全局数组中接收提交的数据。验证和清理这些数据至关重要。

文件:welcome.php (处理 POST 请求)

<?php
declare(strict_types=1);
// 检查表单是否使用了 POST 方法提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// --- 数据获取和基本验证 ---
// 使用 filter_input 进行更安全的访问和基本清理/验证
// FILTER_SANITIZE_SPECIAL_CHARS 是用于 HTML 输出的数据的良好默认选项
$name = filter_input(INPUT_POST, 'user_name', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'user_email', FILTER_VALIDATE_EMAIL);
// 移除空白符
$name = trim($name ?? '');
$errors = [];
// --- 更具体的验证 ---
if (empty($name)) {
$errors[] = "Name is required.";
}
// 你可以添加更多名字验证 (例如,长度、允许的字符)
if ($email === false) {
$errors[] = "A valid email address is required.";
} elseif ($email === null || $email === '') {
// 如果变量未设置,filter_input 返回 null;如果过滤失败,返回 false
// 我们也检查空字符串以防万一
$errors[] = "Email address is required.";
}
// --- 处理数据或显示错误 ---
if (empty($errors)) {
// 在此示例中,数据被认为是有效的
// 重要提示:在使用数据的特定上下文中再次进行清理!
// 在此处使用 htmlspecialchars 可确保在 HTML 中安全显示。
echo "<p>Welcome, " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "!</p>";
// 通常可以直接显示已验证的电子邮件地址,但 htmlspecialchars 增加了一层额外的保护。
echo "<p>Your email address is: " . htmlspecialchars($email, ENT_QUOTES, 'UTF-8') . "</p>";
// --- 进一步处理 ---
// 现在你可以安全地:
// - 将数据存储到数据库中 (使用预处理语句!)
// - 发送电子邮件
// - 等等。
} else {
// 显示错误
echo "<h2>Please correct the following errors:</h2>";
echo "<ul>";
foreach ($errors as $error) {
echo "<li>" . htmlspecialchars($error, ENT_QUOTES, 'UTF-8') . "</li>";
}
echo "</ul>";
// (可选) 重定向回带有错误消息的表单
}
} else {
// 处理没有 POST 数据直接访问脚本的情况
echo "<p>Form submission method not recognized.</p>";
// 重定向回表单通常能提供良好的用户体验
// header('Location: user_form.html');
// exit;
}
?>
</body>
</html>

所示的关键安全步骤:

  • 检查请求方法: 确保脚本仅在通过预期方法 (POST) 提交时处理数据。
  • 使用 filter_input(): 安全地获取输入变量。它提供了基本的过滤/验证选项。
  • 验证: 检查是否包含必需字段 (empty()),以及数据是否符合预期格式 (FILTER_VALIDATE_EMAIL)。根据需要添加更具体的验证(长度、允许的字符等)。
  • 清理输出: 在将用户提供的数据输出到 HTML 中时使用 htmlspecialchars(),以防止跨站脚本 (XSS) 攻击。
  • 处理错误: 清晰地告知用户验证错误。

如果表单方法是 get,数据将作为查询参数(query parameters)附加到 URL 中(例如,welcome_get.php?user_name=John&user_email=john%40example.com)。在 PHP 中,可以通过 $_GET 超全局数组访问这些数据。

使用 GET 的 HTML:

<form action="welcome_get.php" method="get">
<!-- input fields -->
</form>

PHP 处理 GET (welcome_get.php):

<?php
if ($_SERVER["REQUEST_METHOD"] == "GET") {
$name = filter_input(INPUT_GET, 'user_name', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_GET, 'user_email', FILTER_VALIDATE_EMAIL);
// 其余的验证和处理类似于 POST 示例 ...
if (!empty($name)) { // 基本检查
echo "Welcome (from GET), " . htmlspecialchars($name ?? '', ENT_QUOTES, 'UTF-8') . "!";
}
}
?>

这两种方法都以键值对(key-value pairs)的形式发送数据,在 PHP 中通过 $_GET 和 $_POST 访问(它们也合并在 $_REQUEST 中,但显式使用 $_GET/$_POST 更清晰)。

  • $_GET: 数据在 URL 的查询字符串中发送。对用户可见,服务器会记录日志,长度有限制(通常约 2000 个字符),可以被书签收藏。
  • $_POST: 数据在 HTTP 请求体中发送。在 URL 中不可见,没有实际的长度限制,不能被直接书签收藏。
  • 用于非敏感数据检索(例如,搜索查询、页码)。
  • 当你希望结果页面可以带参数被书签收藏/分享时。
  • 用于幂等请求(idempotent requests,指不会改变服务器状态的请求;多个相同的 GET 请求与一个请求效果相同)。

切勿使用 GET 提交密码、敏感数据或会修改服务器数据的操作。

  • 用于提交敏感数据(密码、个人信息)。
  • 用于改变服务器状态的操作(创建用户、提交订单、删除数据)。
  • 提交大量数据时。
  • 上传文件时。
  • 跨站请求伪造 (CSRF): 使用 CSRF 令牌保护执行操作的表单。
  • 文件上传: 务必小心处理文件上传(检查文件类型、大小,扫描恶意软件,安全存储)。
  • 速率限制: 防止对登录或提交表单的暴力破解攻击。
  • 输入验证: 严格进行验证。只允许预期的字符和格式。
  • HTTPS: 始终使用 HTTPS 加密浏览器和服务器之间的数据传输。

掌握安全的表单处理对于构建健壮且安全的 PHP 应用程序至关重要。