Skip to content

PHP 表单 URL/E-mail

本章重点介绍使用现代 PHP 实践验证常见表单输入,如姓名、电子邮件地址和 URL。

输入净化(Sanitization)和验证(Validation)

Section titled “输入净化(Sanitization)和验证(Validation)”

在验证之前,对从 $_POST 或 $_GET 获取的输入数据进行净化至关重要。一个常用的辅助函数可能如下所示:

<?php
// Basic input sanitization function
// 基本的输入净化函数
function sanitize_input(string $data): string {
$data = trim($data); // Remove leading/trailing whitespace
// 移除前导/尾随的空白字符
$data = stripslashes($data); // Remove backslashes added by magic quotes (legacy)
// 移除魔术引号(遗留特性)添加的反斜杠
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); // Convert special characters to HTML entities to prevent XSS
// 将特殊字符转换为 HTML 实体以防止 XSS 攻击
return $data;
}
?>

htmlspecialchars() 对于安全性至关重要,可以在将用户提供的数据显示回 HTML 中时防止跨站脚本(XSS)攻击。

由于跨文化差异,验证姓名可能很复杂。一种简单的方法是检查字母和空白字符,但这通常过于严格。

简单示例(只允许字母和空白字符):

<?php
$name = sanitize_input($_POST["name"] ?? ''); // Use null coalescing operator for safety
// 使用 null 合并运算符确保安全
$nameErr = "";
if (!empty($name)) {
// Basic check: allows letters (Unicode) and spaces
// 基本检查:允许字母(Unicode)和空格
if (!preg_match("/^[pLs'-]+$/u", $name)) {
$nameErr = "Only letters, spaces, hyphens, and apostrophes allowed";
// 只允许字母、空格、连字符和撇号
}
} else {
$nameErr = "Name is required";
// 姓名是必填项
}
// The pattern used:
// 使用的模式:
// ^ asserts position at start of the string
// ^ 断言字符串的开头位置
// [pLs'-]+ matches one or more Unicode letters (pL), whitespace (s), hyphens, or apostrophes
// [pLs'-]+ 匹配一个或多个 Unicode 字母 (pL)、空白字符 (s)、连字符或撇号
// $ asserts position at the end of the string
// $ 断言字符串的末尾位置
// u modifier enables Unicode matching
// u 修饰符启用 Unicode 匹配
?>

注意:preg_match() 函数搜索字符串中与模式(正则表达式)匹配的部分。模式 /^[pLs'-]+$/u 比 /^[a-zA-Z ]*$/ 更具包容性,允许 Unicode 字母、空格、连字符和撇号。根据你的具体要求调整模式。

PHP 中验证电子邮件地址的推荐方法是使用 filter_var() 函数和 FILTER_VALIDATE_EMAIL 过滤器。它检查格式是否看起来像一个有效的电子邮件地址。

<?php
$email = sanitize_input($_POST["email"] ?? '');
$emailErr = "";
if (!empty($email)) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
// 无效的电子邮件格式
}
} else {
$emailErr = "Email is required";
// 电子邮件是必填项
}
?>

重要:FILTER_VALIDATE_EMAIL 仅检查语法。它不验证电子邮件地址是否实际存在。

类似地,使用 filter_var() 和 FILTER_VALIDATE_URL 是验证 URL 的首选方法。

<?php
$website = sanitize_input($_POST["website"] ?? '');
$websiteErr = "";
// URL is often optional, so only validate if provided
// URL 通常是可选的,因此只在提供时进行验证
if (!empty($website)) {
// FILTER_VALIDATE_URL requires a scheme (like http:// or https://)
// FILTER_VALIDATE_URL 要求一个方案(如 http:// 或 https://)
// To allow URLs like www.example.com, you might need additional logic or regex
// 要允许 www.example.com 这样的 URL,你可能需要额外的逻辑或正则表达式
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = "Invalid URL format (e.g., must include http:// or https://)";
// 无效的 URL 格式(例如,必须包含 http:// 或 https://)
}
}
// No error if website is empty, assuming it's optional.
// 如果网站为空,则没有错误,假设它是可选的。
?>

注意:FILTER_VALIDATE_URL 相当严格,通常需要一个方案(例如 http://)。如果你需要验证不太严格的 URL(例如 www.example.com),你可能需要结合其他检查或使用更复杂的正则表达式,尽管 filter_var 通常更安全。

下面是验证逻辑如何集成到典型的表单处理脚本中的示例:

<?php
declare(strict_types=1);
// Basic input sanitization function (define once)
// 基本输入净化函数(定义一次)
function sanitize_input(string $data): string {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
return $data;
}
// Define variables and initialize with empty values
// 定义变量并用空值初始化
$nameErr = $emailErr = $websiteErr = $genderErr = $commentErr = "";
$name = $email = $website = $gender = $comment = "";
$formIsValid = false; // Flag to check if form is valid overall
// 标记,用于检查表单是否整体有效
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Validate Name
// 验证姓名
$name = sanitize_input($_POST["name"] ?? '');
if (empty($name)) {
$nameErr = "Name is required";
// 姓名是必填项
} elseif (!preg_match("/^[pLs'-]+$/u", $name)) {
$nameErr = "Only letters, spaces, hyphens, and apostrophes allowed";
// 只允许字母、空格、连字符和撇号
}
// Validate Email
// 验证电子邮件
$email = sanitize_input($_POST["email"] ?? '');
if (empty($email)) {
$emailErr = "Email is required";
// 电子邮件是必填项
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
// 无效的电子邮件格式
}
// Validate Website (Optional)
// 验证网站(可选)
$website = sanitize_input($_POST["website"] ?? '');
if (!empty($website) && !filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = "Invalid URL format (include http:// or https://)";
// 无效的 URL 格式(包含 http:// 或 https://)
}
// Validate Comment (Example: Check length)
// 验证评论(示例:检查长度)
$comment = sanitize_input($_POST["comment"] ?? '');
if (strlen($comment) > 500) { // Example constraint
// 示例约束
$commentErr = "Comment cannot exceed 500 characters";
// 评论不能超过 500 个字符
}
// Validate Gender (Assuming radio buttons with required selection)
// 验证性别(假设单选按钮需要选择)
$gender = sanitize_input($_POST["gender"] ?? '');
if (empty($gender)) {
$genderErr = "Gender is required";
// 性别是必填项
} // Add specific checks if needed, e.g., ensure value is 'male', 'female', 'other'
// 如果需要,添加特定检查,例如确保值为 'male'、'female' 或 'other'
// Check if all errors are empty
// 检查所有错误是否为空
if (empty($nameErr) && empty($emailErr) && empty($websiteErr) && empty($genderErr) && empty($commentErr)) {
$formIsValid = true;
// Process the valid data (e.g., save to database, send email)
// 处理有效数据(例如,保存到数据库,发送电子邮件)
// echo "Form submitted successfully!";
// 表单提交成功!
// Optionally redirect or display success message
// 可选地重定向或显示成功消息
} else {
$formIsValid = false;
// Errors exist, form will re-display with error messages
// 存在错误,表单将重新显示并带错误消息
}
}
// Form HTML would go here, displaying $name, $email, etc. in input values
// 表单 HTML 将放在这里,在输入框值中显示 $name, $email 等
// and $nameErr, $emailErr, etc. near the respective fields if they are not empty.
// 并在各自字段附近显示 $nameErr, $emailErr 等(如果它们不为空)。
?>
<!-- Example HTML Snippet -->
<!-- 示例 HTML 片段 -->
<!-- Make sure the form posts to the same PHP script -->
<!-- 确保表单提交到同一个 PHP 脚本 -->
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, 'UTF-8'); ?>">
Name: <input type="text" name="name" value="<?php echo $name; ?>">
姓名: <input type="text" name="name" value="<?php echo $name; ?>">
<span class="error">* <?php echo $nameErr; ?></span>
<br><br>
E-mail: <input type="text" name="email" value="<?php echo $email; ?>">
电子邮件: <input type="text" name="email" value="<?php echo $email; ?>">
<span class="error">* <?php echo $emailErr; ?></span>
<br><br>
Website: <input type="text" name="website" value="<?php echo $website; ?>">
网站: <input type="text" name="website" value="<?php echo $website; ?>">
<span class="error"><?php echo $websiteErr; ?></span>
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"><?php echo $comment; ?></textarea>
评论: <textarea name="comment" rows="5" cols="40"><?php echo $comment; ?></textarea>
<span class="error"><?php echo $commentErr; ?></span>
<br><br>
Gender:
性别:
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">Female
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">女
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">Male
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">男
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="other") echo "checked";?> value="other">Other
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="other") echo "checked";?> value="other">其他
<span class="error">* <?php echo $genderErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
<input type="submit" name="submit" value="提交">
</form>
<style>.error { color: #FF0000; }</style>

此示例演示了如何检索数据、净化数据、验证每个字段、存储错误消息以及在出现错误时用提交的值预填充表单。htmlspecialchars($_SERVER["PHP_SELF"]) 确保表单安全地提交到当前脚本。