php批量发短信需用服务商批量api或异步队列,禁用同步for循环;templatecode和templateparam须严格匹配审核内容;手机号须为+86前缀或纯数字json数组;必须解析sendstatuses逐条校验结果。

PHP 调用短信接口发多条,别直接 for 循环 file_get_contents
批量发短信不是把号码塞进循环里挨个调一次接口就完事。高频并发下,file_get_contents 或 curl_exec 同步阻塞会拖垮响应时间,还容易触发运营商限频或被网关拒绝。真实生产环境必须异步化或批量化。
- 优先走服务商提供的「批量发送」API(比如阿里云的
/json/sms/batchSendSms、腾讯云的SendSms支持PhoneNumberSet数组) - 若只能单条发,务必加连接复用:
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Connection: keep-alive']),并重用$ch句柄 - 别在 Web 请求中同步发几百条——改用队列(如 Redis + Laravel Horizon 或纯 PHP 的
pcntl_fork子进程)
签名、模板、变量怎么填才不被驳回 TemplateCode 和 TemplateParam
90% 的群发失败不是代码问题,是审核卡在模板上。服务商对 TemplateCode 和 TemplateParam 校验极严,且大小写、空格、JSON 结构全敏感。
-
TemplateCode必须和后台审核通过的完全一致,包括前缀(如SMS_123456789),不能手敲、不能从数据库字段拼接 -
TemplateParam是 JSON 字符串,不是数组:传'{"code":"1234","product":"XX"},不是['code' => '1234'] - 签名(
SmsSign)必须已通过审核,且与模板绑定的签名一致;测试期别用「测试」字样,会被拒
手机号格式不对直接 400 错误,PhoneNumberSet 不是逗号分隔字符串
阿里云等平台的批量接口要求 PhoneNumberSet 是标准 JSON 数组,不是字符串拼接。常见错误是传 "13800138000,13900139000" 导致整个请求 400。
- 正确写法:
["13800138000","13900139000"](注意双引号、无空格、无中文逗号) - 国内号码必须带 +86 前缀或去掉 0 开头(如
"13800138000",不是"013800138000") - 批量上限看服务商限制(阿里云单次最多 100 个,腾讯云 200 个),超了得拆包,别硬塞
没处理 SendStatuses 返回结果,等于没发
批量接口返回的 SendStatuses 是每个号码的独立状态,不是整体成功/失败。忽略它,你就永远不知道哪几条丢了、哪几条被拦截、哪几条因余额不足没发出去。
立即学习“PHP免费学习笔记(深入)”;
- 必须遍历
SendStatuses数组,检查每个Code字段:"OK"才算成功,"isv.BALANCE_NOT_ENOUGH"或"isv.MOBILE_NUMBER_ILLEGAL"都要记录告警 - 别只看顶层
Code === "OK"—— 这只是请求被网关接收,不代表短信发出去了 - 建议把失败号码+错误码写入日志或 DB,并触发重试(但别无限重试,避免重复计费)
真正难的不是调通接口,是把每一条失败路径都捞出来、分类、可追溯。模板驳回、签名不匹配、号码格式错、余额扣光、返回没解析——这些点漏掉一个,群发就变成“以为发了,其实没发”。











