PHP后端必须严格校验小程序参数,使用filter_var()等内置函数进行类型过滤、白名单校验、JSON安全解析、签名防篡改,并覆盖空值/类型混淆等边界场景。

小程序前端传来的参数不能直接信,PHP 后端必须做严格校验——否则轻则逻辑错乱,重则被刷接口、越权访问、SQL 注入或 XSS。
用 filter_var() 做基础类型和格式过滤
别一上来就写正则或手动 is_numeric() 判断,PHP 内置的 filter_var() 更安全、语义清晰,且支持批量过滤。
-
filter_var($id, FILTER_VALIDATE_INT)比is_int($id)可靠:后者对字符串"123"返回false,而前者能正确识别并可配options限定范围(如['min_range' => 1, 'max_range' => 99999]) - 手机号用
filter_var($phone, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^1[3-9]\d{9}$/']]),比裸写preg_match()少一层错误处理 -
邮箱必须用
FILTER_VALIDATE_EMAIL,但注意它不验证域名是否存在,仅校验格式;若需更高强度,再加 DNS 查询或发验证码 - 对
$_POST或 JSON 解析后的数组,用filter_var_array()一次性过滤多个字段,避免漏掉某个 key
用 in_array() 和白名单限制枚举类参数
小程序常传 type=video、status=1 这类控制行为的字段,后端绝不能只检查是否为数字或非空,必须明确限定可选值。
- 错误做法:
if ($type !== '') { ... }——攻击者可传type=../../etc/passwd触发路径遍历 - 正确做法:
if (!in_array($type, ['image', 'video', 'audio'], true)) { throw new InvalidArgumentException('非法 type'); },true启用严格比较,防止'0' == false类型混淆 - 状态码、分页
order(asc/desc)、性别等所有“有限集合”字段,都应预先定义白名单数组,而非硬编码在 if 条件里 - 注意:白名单数组建议定义为
const或配置项,避免散落在多处导致不一致
警惕 JSON 输入中的类型陷阱与嵌套污染
小程序调用 wx.request() 传 JSON 时,Content-Type: application/json 是常见场景,但 PHP 的 json_decode($_POST['data'], true) 容易埋雷。
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
立即学习“PHP免费学习笔记(深入)”;
- 默认
json_decode()不校验 UTF-8 编码,恶意构造的畸形 Unicode 可能绕过后续正则匹配;建议加JSON_THROW_ON_ERROR标志,让解析失败直接抛异常 - 深层嵌套对象(如
{"user": {"profile": {"name": "xxx"}}})需逐层判断键存在性,用isset($data['user']['profile']['name'])而非直接取值,否则触发 Notice - 禁止将用户输入的 key 当作数组下标直接拼接,例如
$config[$user_input_key]—— 若$user_input_key是../../../../etc/passwd,可能引发变量覆盖或路径泄露 - 对 JSON 中的 URL、HTML 片段等高危字段,必须二次过滤:
filter_var($url, FILTER_SANITIZE_URL)或htmlspecialchars($html, ENT_QUOTES, 'UTF-8')
签名验证是防篡改的第一道防线
小程序前端可任意修改请求参数,光靠字段校验无法防止中间人重放或篡改。必须配合服务端签名校验(如 HMAC-SHA256)。
- 小程序调用前,用约定密钥 + 参数排序 + 时间戳生成签名,例如:
hash_hmac('sha256', $sorted_query_string . $timestamp, $secret) - PHP 后端收到请求后,用相同逻辑重算签名,并严格比对(用
hash_equals()防时序攻击) - 必须校验
timestamp是否在允许窗口内(如 ±300 秒),防止重放攻击 - 签名原文中务必包含不可预测因子(如随机 nonce 或 openid),否则固定参数组合会导致签名可复用
- 注意:签名密钥绝不能硬编码在前端或小程序代码里,应由后端下发临时 token 或通过登录态关联
参数校验不是加个 isset() 就完事,真正容易出问题的是边界场景:空字符串 vs null、0 vs "0"、JSON 中的浮点数精度丢失、大小写混用的枚举值。这些地方不写测试用例,上线后基本靠日志抓 bug。










