最常踩的坑是模板code、signname与控制台审核内容不一致,templateparam未json_encode且键名大小写敏感,验证码误存session而非手机号绑定缓存,accesskeysecret硬编码,服务器时间不同步,以及新签名未完成运营商实名报备。

ThinkPHP 接阿里云短信报错,多数不是代码写错了,而是几个关键配置或环境环节没对上。下面直接说最常踩的坑和对应解法。
模板 CODE 和签名名称必须一字不差
阿里云控制台审核通过的模板,会生成一个类似 SMS_123456789 的 templateCode,这个值必须原样复制,不能手写、不能改大小写、不能带空格或全角字符。常见错误提示是 InvalidTemplateCode 或 Template not found。
签名名称同理:如果控制台里填的是【我的科技公司】,代码里就必须传 【我的科技公司】,中文全角括号、标点、空格都算在内。写成“我的科技公司”或“【我的科技公司 】”都会触发 SignNameNotExists 错误。
templateParam 必须是合法 JSON 字符串
不是 PHP 数组,也不是字符串拼接。模板里写的是 ${code},你就得传 json_encode(['code' => '123456']);如果是 ${verify_code},就得用 ['verify_code' => '123456']。
常见问题:传了数组没 json_encode、键名大小写不一致(如模板用 code,你传 Code)、JSON 中有中文引号或非法字符,结果短信内容显示为 ${code} 原样未替换,或直接报参数格式错误。
验证码存储别依赖 Session
很多 TP 项目把验证码存在 session('sms_code', $code),上线后容易出问题:
- 用户换浏览器或清缓存,Session 消失,但短信已发,无法校验
- 同一设备切换手机号,旧验证码残留,导致 A 用户输 B 用户手机号+自己的验证码也能过
- Session 默认过期时间太长(如 24 小时),而短信通常只允许 5 分钟有效
推荐做法:用缓存绑定手机号,比如 cache('sms_code_' . $mobile, $code, 300)(单位秒),发送前先检查是否已有未过期记录,避免刷码;校验时也按这个 key 读取。
密钥和时间戳不能硬编码或过期
accessKeySecret 绝不能写死在控制器或模型里,哪怕临时测试也要走环境变量或配置文件。一旦泄露,等于把短信账户钥匙送人。
时间戳错误(如提示“时间戳过期”)通常是因为服务器系统时间不准。确保服务器开启了 NTP 时间同步,每次请求生成 timestamp 都用 time(),不要缓存或复用旧值。
实名报备没完成也会静默失败
新签名即使审核通过,也需完成运营商实名报备才能真正发出去。当前平均耗时 5–10 个工作日,部分通道可能更久。没报备完就发,大概率无提示、无日志、无返回,就是收不到短信。
自查路径:阿里云控制台 → 短信服务 → 签名管理 → 找到对应签名 → 点“运营商报备结果”看各运营商状态。务必用三大运营商真实手机号持续测试,观察发送成功率是否逐步上升。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











