Yii框架短信验证码核心难点是签名模板须过审、动态参数不可遗漏、内容编码须统一;阿里云SDK要求templateParam键名与模板变量${code}严格一致且大小写敏感,中文需复制控制台值,gmars包ALIYUN模式须用accessKeyId/accessKeySecret,自定义请求需同步生成time和password并确保UTF-8编码。

Yii 框架里实现短信验证码,核心不是“选哪个库”,而是「签名和模板必须先过审」「动态密码或时间戳参数漏掉就 401 或 500」「内容编码不统一直接被截断」。这三个点卡住 80% 的人。
阿里云 SDK 直接调用时 content 编码和 templateParam 必须严格匹配
阿里云短信要求模板内容里的变量名(如 ${code})和 $templateParam 数组的键完全一致,且大小写敏感。常见错误是模板写成 ${CODE},但代码传的是 ['code' => '123456'],结果返回 InvalidTemplateParam。
- 模板中变量必须用英文大括号:正确是
${code},不能写成【code】或[code] -
$templateParam必须是关联数组,键名与模板中变量名逐字符一致 - 如果模板含中文,
$signName和$templateCode都要从阿里云控制台复制,不要手动输入——中文全角空格、标点会触发签名不匹配 - 本地测试时,
require_once路径若用相对路径(如../../extensions/alisms/...),上线后容易因部署结构变化导致Class not found
使用 gmars/yii2-sms 包时 ALIYUN 和 ALIDAYU 参数名不兼容
gmars/yii2-sms 包对阿里大鱼(ALIDAYU)和阿里云(ALIYUN)用了两套参数名:appkey/secretkey 仅对 ALIDAYU 有效;换成 ALIYUN 时,必须改用 accessKeyId/accessKeySecret,否则报 InvalidAccessKeyId。
- ALIDAYU 模式:
new \gmars\sms\Sms('ALIDAYU', ['appkey' => 'xxx', 'secretkey' => 'yyy']) - ALIYUN 模式:
new \gmars\sms\Sms('ALIYUN', ['accessKeyId' => 'xxx', 'accessKeySecret' => 'yyy']) - 该包不自动处理签名加签逻辑,
send()前需确保signname已在阿里云审核通过,且与控制台显示的**完全一致**(包括空格、括号) - 发送失败时,
$smsObj->send()返回布尔值,错误详情藏在$smsObj->getError(),不是异常抛出,容易忽略
自定义 HTTP 请求发短信时 time 参数和 password 动态签名必须同步生成
像互亿无线这类用 MD5 动态签名的平台,password 不是固定密钥,而是 md5($apiKey . $time),且 $time 是当前 Unix 时间戳(10 位整数)。前后端时间差超 300 秒即拒收。
- PHP 中必须用
time()获取时间戳,不能用date('U')(虽等效但易混淆) - 拼接签名前,
$time不能四舍五入或转字符串再转回整型,必须保持原生整数类型 -
content字段需urlencode(),但注意:如果内容含中文,应先mb_convert_encoding($str, 'UTF-8', 'auto')再 urlencode,否则乱码被截断 - GET 请求 URL 长度限制约 2048 字符,
content超长时强制改 POST,且 header 必须带Content-Type: application/x-www-form-urlencoded
真正难的从来不是调通一次请求,而是下次换平台时,把签名逻辑、模板变量绑定、时区/编码/HTTP 方法这些隐性约束重新对齐一遍。别信“封装好就能跑”,每个平台的 password 含义、time 精度、signName 校验强度都不同,硬套会反复踩坑。











