阿里云短信服务已取代阿里大于,CodeIgniter接入须用新版OpenAPI v2及V20220518 SDK,禁用alidayu旧接口;需正确配置AccessKey、模板与签名,规避超时、异常捕获、参数结构等三大坑,并通过Redis实现验证码频率限制与存储校验。

阿里大于 已于 2017 年正式升级为 阿里云短信服务(SMS),原 alidayu 接口域名、SDK 和认证方式全部停用。现在在 CodeIgniter 中接入,必须使用阿里云新版 SMS API(基于 OpenAPI v2)和对应的 PHP SDK,否则请求会直接返回 InvalidAccessKeyId.NotFound 或 SignatureDoesNotMatch。
确认你用的是阿里云新版短信 SDK(不是 alidayu)
老项目里如果还引用着 TopClient、RequestCheckUtil、alibaba.aliqin.fc.sms.num.send 这类关键词,说明你正在调用已下线的阿里大于接口 —— 这类代码在 2026 年已完全不可用。
正确路径是:
- 去 阿里云短信控制台 →「国内消息」→「API 调用」获取
AccessKeyId、AccessKeySecret、RegionId(如cn-hangzhou) - 下载最新版
aliyun-openapi-php-sdk(非alidayu-php-sdk),推荐用 Composer 安装:composer require aliyuncs/aliyun-openapi-php-sdk - 核心类名是
AlibabaCloud\SDK\Sms\V20220518\SmsClient(注意版本号V20220518),不是TopClient
CodeIgniter 中封装短信发送类要避开三个硬坑
很多 CI 项目把短信逻辑写进控制器或模型里,导致复用性差、测试困难、密钥硬编码。更关键的是,容易踩这些坑:
-
没做异常捕获:阿里云 SDK 抛出的是
AlibabaCloud\Tea\Exception\TeaException,不是Exception,用catch (\Exception $e)会漏掉真实错误 -
没设超时时间:默认 HTTP 超时可能长达 30 秒,用户点击“获取验证码”后卡住,应显式设置
timeout=5 - 模板参数传错结构:阿里云要求模板变量必须是 JSON 字符串,比如
{"code":"1234","product":"MyApp"},而不是 PHP 数组;传数组会返回InvalidParams.Malformed
建议封装成 Library(如 application/libraries/AliyunSms.php),构造函数注入配置,send() 方法只接收 $phone、$template_code、$params 三个参数,并统一返回 ['success'=>true, 'message'=>''] 结构。
验证码发送前必须做的三件事(绕不开)
短信只是通道,验证码业务逻辑必须由你自己闭环,CI 框架不提供内置支持:
-
频率限制:同一个手机号 60 秒内不能重复发送,用 Redis 存
sms:limit:$phone,值为时间戳,SET sms:limit:138****1234 1744995480 EX 60 NX -
验证码存储与校验:不能只存在 session(无状态部署失效),推荐存 Redis,key 为
sms:code:$phone,过期时间设为 5 分钟(EX 300) -
模板与签名强绑定:阿里云要求每个
$template_code必须对应一个已审核通过的SMSSignName,且发送时两个参数都得传;填错任意一个都会返回TemplateOrSignError
别依赖“测试模板”走通流程就上线 —— 线上环境模板未审核通过,send() 会静默失败(返回成功但实际没发出去)。
调试时最该盯住的返回字段
阿里云新版 API 返回 JSON,关键字段不是 result 或 status,而是:
-
Code:字符串,OK才算真正成功;isv.BUSINESS_LIMIT_CONTROL是限流,isv.INVALID_TEMPLATE_CODE是模板 ID 错 -
Message:人类可读提示,但中文乱码常见于未设Accept: application/json或响应未 utf-8 解码 -
BizId:唯一请求 ID,出问题时必须带上它找阿里云工单
CI 中建议在日志里记录完整请求体 + 响应体(脱敏手机号),否则出问题只能干瞪眼。
真正麻烦的从来不是“怎么发”,而是“发没发成”“谁发的”“什么时候该删”——这些细节不落地,上线后查日志比写代码还累。


















