最稳妥的PHP邮箱校验是filter_var($email, FILTER_VALIDATE_EMAIL),它经长期验证可覆盖合法变体,但仅校验格式不验证真实性;需先trim()处理空格,避免空值、null或纯空白符导致误判,且输出时必须用htmlspecialchars()防XSS。

PHP用filter_var()校验邮箱最稳妥
直接用filter_var($email, FILTER_VALIDATE_EMAIL),别自己写正则。PHP内置过滤器经过长期验证,能覆盖user+tag@example.co.uk、带Unicode域名(需额外处理)等合法变体,而手写正则容易漏掉边界情况,比如连字符在域名开头、多余点号、或忽略国际化域名(IDN)的编码要求。
注意:filter_var()只校验格式,不检查邮箱是否真实存在或可送达。它返回false表示格式非法,否则返回原字符串(不是布尔值)。
- 空字符串、
null、仅空白符都会返回false - 如果表单字段名是
email,建议先用trim($_POST['email'] ?? '')再校验,避免前后空格干扰 - 不要用
empty()代替校验——0@example.com是合法邮箱,但empty('0@example.com')为true
表单提交后立即校验,别依赖前端JavaScript
前端type="email"或JS校验只是体验优化,完全不可信。用户禁用JS、用curl/postman直发请求、或改写HTML都能绕过。PHP后端必须独立执行校验逻辑。
典型错误写法:if ($_POST['email'] && !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { /* 错!没处理空值 */ }——这里$_POST['email']为空时条件直接跳过,导致空邮箱被当作有效。
立即学习“PHP免费学习笔记(深入)”;
- 正确顺序:取值 → 去空格 → 校验 → 分支处理
- 示例片段:
$email = trim($_POST['email'] ?? '');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = '邮箱格式不正确';
} - 若需兼容国际化邮箱(如含中文域名),得先用
idn_to_ascii()转ASCII,再校验;但多数国内场景暂不需要
配合htmlspecialchars()防XSS输出错误提示
校验失败后把用户输入的邮箱原样显示在表单里(方便修改),但直接echo $_POST['email']会引发XSS风险。哪怕只是显示错误提示,也要转义。
- 输出到HTML前一律用
htmlspecialchars($email, ENT_QUOTES, 'UTF-8') - 别用
htmlentities()——它会把中文也转成实体,影响可读性 - 如果用了模板引擎(如Twig),确认其默认是否自动转义;未启用时仍需手动处理
别混淆FILTER_SANITIZE_EMAIL和校验用途
FILTER_SANITIZE_EMAIL是清理函数,不是校验函数。它会删掉所有非邮箱字符(如空格、逗号、尖括号),把"变成test@domain.com,但不会告诉你原始输入是否合法。用它替代FILTER_VALIDATE_EMAIL等于放弃校验。
- 清理和校验要分开:先校验,通过后再考虑是否清理(通常没必要)
- 常见误用:
filter_var($email, FILTER_SANITIZE_EMAIL)结果非空就认为合法——错!filter_var('abc', FILTER_SANITIZE_EMAIL)返回'abc',但它根本不是邮箱 - 真正需要清理的场景极少,比如从富文本中提取疑似邮箱再校验,而非表单直输
实际部署时最容易被忽略的是空值与空白符的联合处理,以及错误提示的HTML转义——这两处不处理,轻则表单体验断裂,重则引入安全漏洞。











