PHP表单验证最该先做三件事:①用isset($_POST['submit'])或$_SERVER['REQUEST_METHOD']==='POST'确认提交;②对每个字段用trim()去首尾空格;③用!empty(trim($_POST['name']))而非$_POST['name']!==''判断非空。

PHP 表单验证最该先做的三件事
别急着写 filter_var() 或正则,表单验证出问题,80% 是因为没做这三步:
$_POST没检查是否存在、没过滤空格、没判断请求方法。直接用
$_POST['email'] 会触发 Notice: Undefined index,更糟的是用户可能绕过前端直接发空请求。
- 用
isset($_POST['submit'])或$_SERVER['REQUEST_METHOD'] === 'POST'确认是真实提交 - 对每个字段先用
trim()去首尾空格,否则" user@example.com "会被filter_var(..., FILTER_VALIDATE_EMAIL)判为无效 - 用
!empty(trim($_POST['name']))而不是$_POST['name'] !== '',避免传入空格或null时逻辑错乱
filter_var() 验证邮箱和 URL 的坑在哪
filter_var() 看似简单,但默认行为容易误判。比如 filter_var('test@localhost', FILTER_VALIDATE_EMAIL) 返回 false,但开发环境测试时你可能真用了 localhost;又比如 filter_var('https://example.com/path?x=1#top', FILTER_VALIDATE_URL) 会通过,但如果你只打算接收域名(如 example.com),它就过度宽松了。
- 邮箱校验前加
filter_var($email, FILTER_SANITIZE_EMAIL)清理非法字符,再验证,避免test@exa这类注入式输入干扰判断 - URL 验证若只要求「有协议+域名」,建议拆解:先用
parse_url()提取host和scheme,再分别验证$parsed['scheme'] && $parsed['host'] - 不要依赖前端
type="email"—— 它只在浏览器层面拦截,禁用 JS 或用 curl 就能绕过
密码和重复密码怎么安全比对
初学者常写 if ($_POST['pass'] === $_POST['pass_confirm']),这不安全也不健壮。问题在于:没长度限制、没去除空格、没防暴力提交、没考虑大小写敏感性(其实密码应区分大小写)。
- 两次输入都必须用
trim(),否则"abc123 "和"abc123"被判不等 - 长度检查放在比对前:
strlen(trim($_POST['pass'])) ,避免用户输 3 个字符还继续走后续逻辑 - 不用
==,必须用===,防止 PHP 类型转换导致意外相等(例如"0" == "0e123"为 true) - 比对通过后,密码**不要**直接存
$_POST['pass'],立刻进password_hash(),别留明文在变量里
错误信息怎么存、怎么显示才不翻车
把错误塞进数组再循环输出,看着整洁,但新手常犯两个错:错误数组没初始化就 []=,或者模板里直接 echo $errors['email'] 却忘了这个键可能不存在 —— 导致页面报 Notice。
立即学习“PHP免费学习笔记(深入)”;
- 声明错误数组必须写全:
$errors = [];,不能只在 if 分支里定义 - 显示单个字段错误时,用
isset($errors['email']) ? $errors['email'] : '',别省略isset - 如果用了 HTML 表单重载(即验证失败后
echo $_POST['email']回填),记得对输出做htmlspecialchars(),否则 XSS 一触即发
trim() 和 isset()。











