PHP 表单 - 必需字段
Which fields are required, how to mark them, and how to report errors kindly.
Marking required fields
Use the required attribute for client hints and a * in the label. The server must still check.
<form method="post" action="submit.php">
<label>姓名 <span style="color:red">*</span></label>
<input type="text" name="name" required><br>
<label>邮箱 <span style="color:red">*</span></label>
<input type="text" name="email" required><br>
<label>网址</label>
<input type="text" name="website"><br>
<label>评论</label>
<textarea name="comment"></textarea><br>
<label>性别 <span style="color:red">*</span></label>
<input type="radio" name="gender" value="female">女
<input type="radio" name="gender" value="male">男<br>
<input type="submit" value="提交">
</form>Required validation
<?php
$fields = [
"name" => "姓名",
"email" => "邮箱",
"gender" => "性别",
];
$optional = ["website", "comment"];
$errors = [];
$data = [];
foreach ($fields as $key => $label) {
$v = trim($_POST[$key] ?? "");
if ($v === "") {
$errors[$key] = "$label 是必填项";
} else {
$data[$key] = $v;
}
}
foreach ($optional as $key) {
$data[$key] = trim($_POST[$key] ?? "");
}
if ($errors) {
foreach ($errors as $e) {
echo "错误: $e\n";
}
} else {
echo "全部通过\n";
print_r($data);
}全部通过
Array
(
[name] => Tom
[email] => tom@example.com
[gender] => male
[website] =>
[comment] =>
)$data too, so downstream code never checks key existence. A uniform shape beats saving lines.Rendering errors back
On failure keep what the user typed. Echo $data back into value so only the wrong field needs editing.
<?php
$errors = ["email" => "邮箱 是必填项"];
$data = ["name" => "Tom", "email" => ""];
function val(array $d, string $k): string {
return htmlspecialchars($d[$k] ?? "", ENT_QUOTES, "UTF-8");
}
?>
<form method="post">
<input name="name" value="<?= val($data, "name") ?>">
<?php if (isset($errors["name"])): ?>
<span class="err"><?= val($errors, "name") ?></span>
<?php endif; ?>
<input name="email" value="<?= val($data, "email") ?>">
<?php if (isset($errors["email"])): ?>
<span class="err"><?= val($errors, "email") ?></span>
<?php endif; ?>
<button>提交</button>
</form><form method="post">
<input name="name" value="Tom">
<input name="email" value="">
<span class="err">邮箱 是必填项</span>
<button>提交</button>
</form>Always pass all three arguments: ENT_QUOTES escapes single quotes too, UTF-8 pins the charset.
Required is not valid
Filled and correct are two gates, in this order:
- Required ——
trim($v) !== '' - Format —— email, URL, number, date
- Range —— length, numeric bounds, allowed values
- Business —— username taken, coupon valid
Steps one and two belong to the form layer; three and four usually hit the database and belong in a service.
标记必填
HTML 里用 required 属性做前端提示,同时在标签上加 * 让用户知道。但后端必须再验一次。
<form method="post" action="submit.php">
<label>姓名 <span style="color:red">*</span></label>
<input type="text" name="name" required><br>
<label>邮箱 <span style="color:red">*</span></label>
<input type="text" name="email" required><br>
<label>网址</label>
<input type="text" name="website"><br>
<label>评论</label>
<textarea name="comment"></textarea><br>
<label>性别 <span style="color:red">*</span></label>
<input type="radio" name="gender" value="female">女
<input type="radio" name="gender" value="male">男<br>
<input type="submit" value="提交">
</form>必填校验
<?php
$fields = [
"name" => "姓名",
"email" => "邮箱",
"gender" => "性别",
];
$optional = ["website", "comment"];
$errors = [];
$data = [];
foreach ($fields as $key => $label) {
$v = trim($_POST[$key] ?? "");
if ($v === "") {
$errors[$key] = "$label 是必填项";
} else {
$data[$key] = $v;
}
}
foreach ($optional as $key) {
$data[$key] = trim($_POST[$key] ?? "");
}
if ($errors) {
foreach ($errors as $e) {
echo "错误: $e\n";
}
} else {
echo "全部通过\n";
print_r($data);
}全部通过
Array
(
[name] => Tom
[email] => tom@example.com
[gender] => male
[website] =>
[comment] =>
)trim() 后存进 $data,这样后面的代码不用到处判断「这个键在不在」。统一结构比省几行代码重要。错误回显到表单
校验失败时不要清空用户已填的内容。把 $data 回填到 value 里,用户只需改错的那一项。
<?php
$errors = ["email" => "邮箱 是必填项"];
$data = ["name" => "Tom", "email" => ""];
function val(array $d, string $k): string {
return htmlspecialchars($d[$k] ?? "", ENT_QUOTES, "UTF-8");
}
?>
<form method="post">
<input name="name" value="<?= val($data, "name") ?>">
<?php if (isset($errors["name"])): ?>
<span class="err"><?= val($errors, "name") ?></span>
<?php endif; ?>
<input name="email" value="<?= val($data, "email") ?>">
<?php if (isset($errors["email"])): ?>
<span class="err"><?= val($errors, "email") ?></span>
<?php endif; ?>
<button>提交</button>
</form><form method="post">
<input name="name" value="Tom">
<input name="email" value="">
<span class="err">邮箱 是必填项</span>
<button>提交</button>
</form>htmlspecialchars($v, ENT_QUOTES, "UTF-8") 三个参数都要写全:ENT_QUOTES 连单引号一起转,UTF-8 明确字符集。只写第一个参数在旧版本里可能按 ISO-8859-1 处理。
必填不等于合法
「填了」和「填对了」是两道关卡,顺序不能颠倒:
- 必填 ——
trim($v) !== '' - 格式 —— 邮箱、URL、数字、日期
- 范围 —— 长度、数值区间、枚举值
- 业务 —— 用户名是否已存在、优惠码是否有效
前两步在表单层做完,第三、四步往往要查库,通常放到服务层。混在一起写会让控制器越来越胖。