ThinkPHP短信接口报错主因是底层支撑失效而非代码错误:Session未真实启动、跨子域导致验证码不一致、密钥泄露、cURL请求未发出或SSL配置不当、签名参数排序/格式/时间戳/密钥使用错误。

ThinkPHP短信接口调用报错,90%不是代码写错了,而是底层支撑断了——比如Session没真正启动、跨子域导致验证码存查不一致、密钥硬编码泄露、或请求根本没发出去。重点不在“怎么写”,而在“怎么跑通”。
检查Session是否真实生效
TP6默认注释了\think\middleware\SessionInit::class,必须手动在app/middleware.php中启用;仅调用session('key', 'val')不等于Session已启动。验证方式:在接口开头加var_dump(session_id());,前后端输出ID必须完全一致。若前端是www.example.com、后端接口走api.example.com,需统一配置session.cookie_domain = '.example.com'。
确认验证码是否已被消耗或未校验
- captcha_check()成功后会自动清除原始值,重复提交或刷新页面重填旧码必然失败
- 校验前先打印session('captcha')看是否存在,不存在就别进发送逻辑
- 图形验证码必须在短信接口调用前完成校验闭环,不能只生成图片、不验证token
排查cURL请求是否真正发出
返回空、curl_exec()为false,大概率是请求卡在了底层:
- 漏设CURLOPT_RETURNTRANSFER => true,响应被直接输出,后续PHP可能因header已发送而中断
- URL末尾多了一个斜杠(如/send/),触发301重定向但未开启CURLOPT_FOLLOWLOCATION
- 生产环境误加CURLOPT_SSL_VERIFYPEER => false,反而导致SSL握手失败
- 用curl_getinfo($ch, CURLINFO_HTTP_CODE)查真实状态码,非200要立刻停掉流程
核对参数与签名细节
返回{"code":1001,"msg":"签名错误"}类提示,别急着改算法——先比对这些:
立即学习“PHP免费学习笔记(深入)”;
- 参数是否严格按文档要求的字典序排序?ksort($params, SORT_STRING)不能少
- 空格、换行、等号前后是否有隐藏字符?把待签名字符串原样echo出来逐字符比对
- timestamp字段是否为秒级整数?(int)time()强转,避免microtime(true)带小数点
- 别混淆AccessKeyID和AccessKeySecret,签名用的是后者



















