php表单安全需三重防护:①输入过滤用filter_input()替代$_post/$_get,禁用已废弃的filter_sanitize_*;②sql注入须用pdo预处理语句,禁用mysqli_real_escape_string();③输出时htmlspecialchars()必须指定ent_quotes|ent_html5和utf-8编码。

PHP接收表单数据前必须过滤 $_POST 和 $_GET
直接用 $_POST['username'] 或 $_GET['id'] 是最常见也最危险的起点。这些超全局变量不经过任何校验,可能含恶意脚本、SQL 片段、路径遍历字符(如 ../../etc/passwd)或过长字符串引发 DoS。
实操建议:
- 永远不用
$_POST/$_GET原值参与数据库查询、文件操作、HTML 输出或系统命令调用 - 优先用
filter_input()替代直接访问:例如filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL),它比trim()+htmlspecialchars()组合更语义明确 - 对数字型字段,强制用
FILTER_VALIDATE_INT或filter_var($id, FILTER_VALIDATE_INT),失败时返回false而非转换为 0 —— 后者容易掩盖空值或非法输入 - 注意
FILTER_SANITIZE_*系列在 PHP 8.1+ 已被标记为废弃,生产环境应改用FILTER_VALIDATE_*+ 显式清理逻辑(如正则替换非预期字符)
防止 SQL 注入不能只靠 mysqli_real_escape_string()
这个函数只对单引号、反斜杠等做转义,但无法防御宽字节注入、十六进制绕过或预处理语句未启用时的多语句攻击(如 ; DROP TABLE users;)。它本质是“补丁式防护”,不是设计层面的安全。
实操建议:
- 一律使用 PDO 预处理语句,参数绑定才是根本解法:
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?"); $stmt->execute([$email]); - 若必须用 MySQLi,确保开启
MYSQLI_OPT_LOCAL_INFILE以外的严格模式,并用mysqli_prepare()+mysqli_stmt_bind_param() - 禁止拼接 SQL 字符串,哪怕你“确认这个变量只来自内部表单”——权限提升、日志注入、缓存污染都可能让“内部”变“外部”
- 数据库连接需设置
PDO::ATTR_EMULATE_PREPARES = false,否则 PDO 会在客户端模拟预处理,失去服务端参数隔离能力
htmlspecialchars() 输出前必须指定 ENT_QUOTES 和字符编码
漏掉参数会导致单引号不转义(' → '),在属性上下文中(如 <input value="...">)可能被用于闭合标签并注入 JS;不声明编码则可能触发浏览器自动识别错误,导致 UTF-7 或混合编码 XSS。
实操建议:
- 始终写全参数:
htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8'),ENT_HTML5比默认的ENT_COMPAT更兼容现代 HTML 标准 - 不要依赖 ini 设置(如
default_charset),显式传参避免跨环境差异 - 对 JSON 输出场景,用
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG),而非先htmlspecialchars()再json_encode()—— 后者会双重编码引号 - 富文本内容不能仅靠
htmlspecialchars(),需用专用库如HTMLPurifier或DOMDocument白名单清洗
CSRF 防护不能只靠 session token 检查
很多项目只在表单里加 <input type="hidden" name="token" value="<?= $_SESSION['csrf_token'] ?>">,但忽略验证时机、Token 生命周期和存储方式,导致重放攻击或并发失效。
实操建议:
- 生成 Token 必须用加密安全随机数:
bin2hex(random_bytes(32)),禁用mt_rand()或时间戳拼接 - 验证后立即销毁当前 Token 并生成新 Token(“一次一换”),避免重复提交或跨标签页冲突
- 将 Token 存在服务器端 session 中,且与用户 IP、User-Agent 做弱绑定(非强校验,防简单盗用),不存于 Cookie 或 localStorage
- 敏感操作(如密码修改、支付)需额外二次验证(如短信/邮箱验证码),CSRF Token 只是第一道防线
表单安全真正的复杂点不在某一行代码,而在于所有环节是否形成闭环:输入过滤、存储隔离、输出转义、状态同步、错误反馈不泄露信息。任何一个环节松动,其他环节的防护效果都会断崖式下降。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











