PHP 完整表单实例
在本章节中,我们将创建一个完整的PHP表单实例,包含各种常见的表单字段类型、验证规则和数据处理逻辑。这个实例将演示如何构建一个功能齐全的用户注册表单。
完整表单功能概述
我们将创建一个包含以下功能的完整表单:
- 用户基本信息(姓名、电子邮箱、密码)
- 联系方式(电话号码、网站)
- 用户偏好(性别、兴趣爱好)
- 详细信息(关于我)
- 完整的服务器端验证
- 友好的错误提示和成功反馈
- 表单数据的安全处理和展示
表单HTML结构
以下是表单的HTML结构:
<!DOCTYPE html>
<html>
<head>
<style>
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #333;
}
.form-control {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.3s ease;
}
.form-control:focus {
border-color: #4F46E5;
outline: none;
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
}
.error {
color: #DC2626;
font-size: 12px;
margin-top: 4px;
display: block;
}
.form-check {
margin-bottom: 10px;
}
.form-check input {
margin-right: 8px;
}
.btn {
padding: 10px 20px;
background-color: #4F46E5;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s ease;
}
.btn:hover {
background-color: #4338CA;
}
.success-message {
color: #059669;
background-color: #d1fae5;
padding: 12px;
border-radius: 4px;
margin-bottom: 20px;
}
.form-row {
display: flex;
gap: 20px;
}
.form-col {
flex: 1;
}
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
}
</style>
</head>
<body>
<h2>用户注册表单</h2>
<?php if (!empty($successMessage)): ?>
<div class="success-message"><?php echo $successMessage; ?></div>
<?php endif; ?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<div class="form-row">
<div class="form-col">
<div class="form-group">
<label for="firstName">名字 *</label>
<input type="text" class="form-control" id="firstName" name="firstName" value="<?php echo $firstName;?>">
<span class="error"><?php echo $firstNameErr;?></span>
</div>
</div>
<div class="form-col">
<div class="form-group">
<label for="lastName">姓氏 *</label>
<input type="text" class="form-control" id="lastName" name="lastName" value="<?php echo $lastName;?>">
<span class="error"><?php echo $lastNameErr;?></span>
</div>
</div>
</div>
<div class="form-group">
<label for="email">电子邮箱 *</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo $email;?>">
<span class="error"><?php echo $emailErr;?></span>
</div>
<div class="form-group">
<label for="password">密码 *</label>
<input type="password" class="form-control" id="password" name="password">
<span class="error"><?php echo $passwordErr;?></span>
</div>
<div class="form-group">
<label for="confirmPassword">确认密码 *</label>
<input type="password" class="form-control" id="confirmPassword" name="confirmPassword">
<span class="error"><?php echo $confirmPasswordErr;?></span>
</div>
<div class="form-group">
<label for="phone">电话号码</label>
<input type="tel" class="form-control" id="phone" name="phone" value="<?php echo $phone;?>" placeholder="+86 123 4567 8901">
<span class="error"><?php echo $phoneErr;?></span>
</div>
<div class="form-group">
<label for="website">个人网站</label>
<input type="url" class="form-control" id="website" name="website" value="<?php echo $website;?>" placeholder="https://www.example.com">
<span class="error"><?php echo $websiteErr;?></span>
</div>
<div class="form-group">
<label>性别</label>
<div class="form-check">
<input type="radio" id="male" name="gender" value="male" <?php if ($gender == "male") echo "checked";?>>
<label for="male">男</label>
</div>
<div class="form-check">
<input type="radio" id="female" name="gender" value="female" <?php if ($gender == "female") echo "checked";?>>
<label for="female">女</label>
</div>
<div class="form-check">
<input type="radio" id="other" name="gender" value="other" <?php if ($gender == "other") echo "checked";?>>
<label for="other">其他</label>
</div>
</div>
<div class="form-group">
<label>兴趣爱好</label>
<div class="form-check">
<input type="checkbox" id="coding" name="interests[]" value="coding" <?php if (in_array("coding", $interests)) echo "checked";?>>
<label for="coding">编程</label>
</div>
<div class="form-check">
<input type="checkbox" id="reading" name="interests[]" value="reading" <?php if (in_array("reading", $interests)) echo "checked";?>>
<label for="reading">阅读</label>
</div>
<div class="form-check">
<input type="checkbox" id="music" name="interests[]" value="music" <?php if (in_array("music", $interests)) echo "checked";?>>
<label for="music">音乐</label>
</div>
<div class="form-check">
<input type="checkbox" id="sports" name="interests[]" value="sports" <?php if (in_array("sports", $interests)) echo "checked";?>>
<label for="sports">运动</label>
</div>
</div>
<div class="form-group">
<label for="about">关于我</label>
<textarea class="form-control" id="about" name="about" rows="5"><?php echo $about;?></textarea>
</div>
<div class="form-group">
<input type="checkbox" id="agreeTerms" name="agreeTerms" <?php if ($agreeTerms) echo "checked";?>>
<label for="agreeTerms">我同意网站的<a href="#">服务条款</a>和<a href="#">隐私政策</a> *</label>
<span class="error"><?php echo $agreeTermsErr;?></span>
</div>
<p><span class="error">* 必填字段</span></p>
<button type="submit" class="btn" name="submit">提交注册</button>
</form>
</body>
</html>
PHP表单验证和处理
以下是完整的PHP表单验证和处理代码:
<?php
// 定义变量并设置为空值
$firstName = $lastName = $email = $phone = $website = $gender = $about = "";
$password = $confirmPassword = "";
$agreeTerms = false;
$interests = array();
// 错误信息变量
$firstNameErr = $lastNameErr = $emailErr = $passwordErr = $confirmPasswordErr = "";
$phoneErr = $websiteErr = $agreeTermsErr = "";
$successMessage = "";
// 检查表单是否已提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 验证名字
if (empty($_POST["firstName"])) {
$firstNameErr = "名字是必填的";
} else {
$firstName = test_input($_POST["firstName"]);
// 检查名字是否只包含字母和空格
if (!preg_match("/^[a-zA-Z\s]+$", $firstName)) {
$firstNameErr = "名字只能包含字母和空格";
}
}
// 验证姓氏
if (empty($_POST["lastName"])) {
$lastNameErr = "姓氏是必填的";
} else {
$lastName = test_input($_POST["lastName"]);
// 检查姓氏是否只包含字母和空格
if (!preg_match("/^[a-zA-Z\s]+$", $lastName)) {
$lastNameErr = "姓氏只能包含字母和空格";
}
}
// 验证电子邮件
if (empty($_POST["email"])) {
$emailErr = "电子邮箱是必填的";
} else {
$email = test_input($_POST["email"]);
// 检查电子邮件格式
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "无效的电子邮箱格式";
}
}
// 验证密码
if (empty($_POST["password"])) {
$passwordErr = "密码是必填的";
} else {
$password = $_POST["password"];
// 密码强度验证(至少8位,包含字母和数字)
if (strlen($password) < 8 || !preg_match("/[a-zA-Z]/", $password) || !preg_match("/[0-9]/", $password)) {
$passwordErr = "密码至少需要8位,并且包含字母和数字";
}
}
// 验证确认密码
if (empty($_POST["confirmPassword"])) {
$confirmPasswordErr = "请确认您的密码";
} else {
$confirmPassword = $_POST["confirmPassword"];
// 检查两次密码是否一致
if ($password != $confirmPassword) {
$confirmPasswordErr = "两次输入的密码不一致";
}
}
// 验证电话号码
if (!empty($_POST["phone"])) {
$phone = test_input($_POST["phone"]);
// 简单的电话号码验证(支持国际格式)
if (!preg_match("/^[+]?[0-9\s\-\(\)]{7,20}$/", $phone)) {
$phoneErr = "无效的电话号码格式";
}
}
// 验证网站URL
if (!empty($_POST["website"])) {
$website = test_input($_POST["website"]);
// 检查URL是否包含协议,如果没有则添加http://
if (!preg_match("/^https?:\/\//", $website)) {
$website = "http://" . $website;
}
// 验证URL格式
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = "无效的网站URL格式";
}
}
// 获取性别
if (isset($_POST["gender"])) {
$gender = test_input($_POST["gender"]);
}
// 获取兴趣爱好
if (isset($_POST["interests"])) {
$interests = array_map('test_input', $_POST["interests"]);
}
// 获取关于我
if (!empty($_POST["about"])) {
$about = test_input($_POST["about"]);
}
// 验证是否同意条款
if (!isset($_POST["agreeTerms"])) {
$agreeTermsErr = "您必须同意服务条款和隐私政策";
} else {
$agreeTerms = true;
}
// 如果没有错误,处理表单数据
if (empty($firstNameErr) && empty($lastNameErr) && empty($emailErr) &&
empty($passwordErr) && empty($confirmPasswordErr) && empty($phoneErr) &&
empty($websiteErr) && empty($agreeTermsErr)) {
// 这里可以添加数据库存储逻辑
// 为了示例,我们将简单地显示成功消息
// 在实际应用中,您应该:
// 1. 对密码进行哈希处理
// $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// 2. 将数据插入数据库
// $sql = "INSERT INTO users (firstName, lastName, email, password, ...) VALUES (?, ?, ?, ?, ...)";
$successMessage = "注册成功!欢迎加入我们," . $firstName . "!";
// 重置表单数据(可选)
// $firstName = $lastName = $email = $phone = $website = $gender = $about = "";
// $password = $confirmPassword = "";
// $agreeTerms = false;
// $interests = array();
}
}
// 清理输入数据的函数
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
完整的PHP表单代码
将上述HTML和PHP代码组合在一起,就得到了完整的PHP表单实例:
<?php
// 定义变量并设置为空值
$firstName = $lastName = $email = $phone = $website = $gender = $about = "";
$password = $confirmPassword = "";
$agreeTerms = false;
$interests = array();
// 错误信息变量
$firstNameErr = $lastNameErr = $emailErr = $passwordErr = $confirmPasswordErr = "";
$phoneErr = $websiteErr = $agreeTermsErr = "";
$successMessage = "";
// 检查表单是否已提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 验证名字
if (empty($_POST["firstName"])) {
$firstNameErr = "名字是必填的";
} else {
$firstName = test_input($_POST["firstName"]);
// 检查名字是否只包含字母和空格
if (!preg_match("/^[a-zA-Z\s]+$", $firstName)) {
$firstNameErr = "名字只能包含字母和空格";
}
}
// 验证姓氏
if (empty($_POST["lastName"])) {
$lastNameErr = "姓氏是必填的";
} else {
$lastName = test_input($_POST["lastName"]);
// 检查姓氏是否只包含字母和空格
if (!preg_match("/^[a-zA-Z\s]+$", $lastName)) {
$lastNameErr = "姓氏只能包含字母和空格";
}
}
// 验证电子邮件
if (empty($_POST["email"])) {
$emailErr = "电子邮箱是必填的";
} else {
$email = test_input($_POST["email"]);
// 检查电子邮件格式
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "无效的电子邮箱格式";
}
}
// 验证密码
if (empty($_POST["password"])) {
$passwordErr = "密码是必填的";
} else {
$password = $_POST["password"];
// 密码强度验证(至少8位,包含字母和数字)
if (strlen($password) < 8 || !preg_match("/[a-zA-Z]/", $password) || !preg_match("/[0-9]/", $password)) {
$passwordErr = "密码至少需要8位,并且包含字母和数字";
}
}
// 验证确认密码
if (empty($_POST["confirmPassword"])) {
$confirmPasswordErr = "请确认您的密码";
} else {
$confirmPassword = $_POST["confirmPassword"];
// 检查两次密码是否一致
if ($password != $confirmPassword) {
$confirmPasswordErr = "两次输入的密码不一致";
}
}
// 验证电话号码
if (!empty($_POST["phone"])) {
$phone = test_input($_POST["phone"]);
// 简单的电话号码验证(支持国际格式)
if (!preg_match("/^[+]?[0-9\s\-\(\)]{7,20}$/", $phone)) {
$phoneErr = "无效的电话号码格式";
}
}
// 验证网站URL
if (!empty($_POST["website"])) {
$website = test_input($_POST["website"]);
// 检查URL是否包含协议,如果没有则添加http://
if (!preg_match("/^https?:\/\//", $website)) {
$website = "http://" . $website;
}
// 验证URL格式
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = "无效的网站URL格式";
}
}
// 获取性别
if (isset($_POST["gender"])) {
$gender = test_input($_POST["gender"]);
}
// 获取兴趣爱好
if (isset($_POST["interests"])) {
$interests = array_map('test_input', $_POST["interests"]);
}
// 获取关于我
if (!empty($_POST["about"])) {
$about = test_input($_POST["about"]);
}
// 验证是否同意条款
if (!isset($_POST["agreeTerms"])) {
$agreeTermsErr = "您必须同意服务条款和隐私政策";
} else {
$agreeTerms = true;
}
// 如果没有错误,处理表单数据
if (empty($firstNameErr) && empty($lastNameErr) && empty($emailErr) &&
empty($passwordErr) && empty($confirmPasswordErr) && empty($phoneErr) &&
empty($websiteErr) && empty($agreeTermsErr)) {
// 这里可以添加数据库存储逻辑
// 为了示例,我们将简单地显示成功消息
// 在实际应用中,您应该:
// 1. 对密码进行哈希处理
// $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// 2. 将数据插入数据库
// $sql = "INSERT INTO users (firstName, lastName, email, password, ...) VALUES (?, ?, ?, ?, ...)";
$successMessage = "注册成功!欢迎加入我们," . $firstName . "!";
// 重置表单数据(可选)
// $firstName = $lastName = $email = $phone = $website = $gender = $about = "";
// $password = $confirmPassword = "";
// $agreeTerms = false;
// $interests = array();
}
}
// 清理输入数据的函数
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册表单</title>
<style>
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #333;
}
.form-control {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.3s ease;
}
.form-control:focus {
border-color: #4F46E5;
outline: none;
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
}
.error {
color: #DC2626;
font-size: 12px;
margin-top: 4px;
display: block;
}
.form-check {
margin-bottom: 10px;
}
.form-check input {
margin-right: 8px;
}
.btn {
padding: 10px 20px;
background-color: #4F46E5;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s ease;
}
.btn:hover {
background-color: #4338CA;
}
.success-message {
color: #059669;
background-color: #d1fae5;
padding: 12px;
border-radius: 4px;
margin-bottom: 20px;
}
.form-row {
display: flex;
gap: 20px;
}
.form-col {
flex: 1;
}
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
}
</style>
</head>
<body>
<h2>用户注册表单</h2>
<?php if (!empty($successMessage)): ?>
<div class="success-message"><?php echo $successMessage; ?></div>
<?php endif; ?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<div class="form-row">
<div class="form-col">
<div class="form-group">
<label for="firstName">名字 *</label>
<input type="text" class="form-control" id="firstName" name="firstName" value="<?php echo $firstName;?>">
<span class="error"><?php echo $firstNameErr;?></span>
</div>
</div>
<div class="form-col">
<div class="form-group">
<label for="lastName">姓氏 *</label>
<input type="text" class="form-control" id="lastName" name="lastName" value="<?php echo $lastName;?>">
<span class="error"><?php echo $lastNameErr;?></span>
</div>
</div>
</div>
<div class="form-group">
<label for="email">电子邮箱 *</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo $email;?>">
<span class="error"><?php echo $emailErr;?></span>
</div>
<div class="form-group">
<label for="password">密码 *</label>
<input type="password" class="form-control" id="password" name="password">
<span class="error"><?php echo $passwordErr;?></span>
</div>
<div class="form-group">
<label for="confirmPassword">确认密码 *</label>
<input type="password" class="form-control" id="confirmPassword" name="confirmPassword">
<span class="error"><?php echo $confirmPasswordErr;?></span>
</div>
<div class="form-group">
<label for="phone">电话号码</label>
<input type="tel" class="form-control" id="phone" name="phone" value="<?php echo $phone;?>" placeholder="+86 123 4567 8901">
<span class="error"><?php echo $phoneErr;?></span>
</div>
<div class="form-group">
<label for="website">个人网站</label>
<input type="url" class="form-control" id="website" name="website" value="<?php echo $website;?>" placeholder="https://www.example.com">
<span class="error"><?php echo $websiteErr;?></span>
</div>
<div class="form-group">
<label>性别</label>
<div class="form-check">
<input type="radio" id="male" name="gender" value="male" <?php if ($gender == "male") echo "checked";?>>
<label for="male">男</label>
</div>
<div class="form-check">
<input type="radio" id="female" name="gender" value="female" <?php if ($gender == "female") echo "checked";?>>
<label for="female">女</label>
</div>
<div class="form-check">
<input type="radio" id="other" name="gender" value="other" <?php if ($gender == "other") echo "checked";?>>
<label for="other">其他</label>
</div>
</div>
<div class="form-group">
<label>兴趣爱好</label>
<div class="form-check">
<input type="checkbox" id="coding" name="interests[]" value="coding" <?php if (in_array("coding", $interests)) echo "checked";?>>
<label for="coding">编程</label>
</div>
<div class="form-check">
<input type="checkbox" id="reading" name="interests[]" value="reading" <?php if (in_array("reading", $interests)) echo "checked";?>>
<label for="reading">阅读</label>
</div>
<div class="form-check">
<input type="checkbox" id="music" name="interests[]" value="music" <?php if (in_array("music", $interests)) echo "checked";?>>
<label for="music">音乐</label>
</div>
<div class="form-check">
<input type="checkbox" id="sports" name="interests[]" value="sports" <?php if (in_array("sports", $interests)) echo "checked";?>>
<label for="sports">运动</label>
</div>
</div>
<div class="form-group">
<label for="about">关于我</label>
<textarea class="form-control" id="about" name="about" rows="5"><?php echo $about;?></textarea>
</div>
<div class="form-group">
<input type="checkbox" id="agreeTerms" name="agreeTerms" <?php if ($agreeTerms) echo "checked";?>>
<label for="agreeTerms">我同意网站的<a href="#">服务条款</a>和<a href="#">隐私政策</a> *</label>
<span class="error"><?php echo $agreeTermsErr;?></span>
</div>
<p><span class="error">* 必填字段</span></p>
<button type="submit" class="btn" name="submit">提交注册</button>
</form>
</body>
</html>
数据安全最佳实践
在处理表单数据时,请务必遵循以下安全最佳实践:
- 始终验证所有用户输入:永远不要信任用户输入的数据,始终在服务器端进行验证。
- 对密码进行哈希处理:不要以明文形式存储密码,使用
password_hash()
函数对密码进行哈希处理。 - 防止SQL注入:使用预处理语句或参数化查询来防止SQL注入攻击。
- 防止XSS攻击:使用
htmlspecialchars()
函数对用户输入进行转义,以防止跨站脚本攻击。 - 使用HTTPS:在传输敏感数据时,始终使用HTTPS协议来加密数据。
- 实施CSRF保护:使用CSRF令牌来防止跨站请求伪造攻击。
- 限制文件上传:如果表单允许文件上传,请限制文件类型和大小。
提示:在实际项目中,您可能需要将表单处理逻辑和HTML展示逻辑分离,遵循MVC(模型-视图-控制器)设计模式,这将使您的代码更加清晰、可维护和可测试。