CodeIgniter 短信类必须严格放在指定路径(CI3:application/libraries/;CI4:app/Libraries/),文件名与类名一致且首字母大写;配置需统一写入 config/sms.php,凭证、endpoint、模板审核状态须逐一验证,回调须单独控制器处理并做幂等与IP校验,日志需记录脱敏后的完整请求响应。
短信服务类必须放在
目录下
CodeIgniter 不会自动加载任意位置的类,第三方短信 SDK(比如阿里云、腾讯云官方 PHP SDK)若直接丢进
或根目录,
会报错 Class not found。正确路径只有两个:CI3 是
,CI4 是
,且文件名与类名必须严格一致、首字母大写。
常见错误现象:
,90% 是因为路径或命名不匹配;更隐蔽的是类用了命名空间但没配 Composer 自动加载——此时即使放对位置也无效,得手动
或改用无命名空间版本。
不要把整个 SDK 包原样挪进
,只提取核心发送类 + 依赖的最小工具类
如果 SDK 依赖
,别试图在 CI3 里混用 Composer 加载和
,优先改写为 cURL 实现
CI3 中
的第二个参数不是配置数组,而是“是否启用构造函数传参”的开关,真要传配置得在类内部读
这类错误基本是凭证或 endpoint 配错了
阿里云短信 SDK 报这个错,往往不是网络问题,而是
、
或
填错,或者 endpoint 写成测试环境地址却用了正式密钥。腾讯云同理,
多半是
/
权限不足或签名时间戳偏差超 5 分钟。
实操建议:
先用 Postman 手动调通官方文档里的 HTTP 示例请求,确认凭证可用,再贴到 CI 里
把密钥信息从控制器里剥离,统一写进
:
,然后在类中用
加载
endpoint 必须带协议和端口,比如阿里云是
,少个
或漏掉
都会触发底层连接异常而非业务错误
异步回调验证逻辑不能写在短信发送类里
短信服务本身不提供回调,但你对接的「短信平台」(如聚合数据、容联云)可能有送达回执或上行短信回调。这类接口必须单独建控制器处理,比如
,而不是塞进
类里——否则无法被外部 HTTP 请求访问,也违反单一职责。
典型陷阱:
微信接口库:PHPToQyWeixin PHP调用企业微信API接口底层类库
下载
用
读取回调参数时,没检查
,导致 JSON 格式回调体读成空
阿里云回传签名是
字段,但你代码里写成
,校验永远失败
没做 IP 白名单校验,任何人都能伪造回调请求,触发重复发券或状态误更新
回调处理耗时超过 3 秒,部分平台(如腾讯云)会重试,没加幂等判断就可能发两条短信
日志必须记录原始请求和响应,不能只记成功/失败
短信发不出去时,
毫无调试价值。真正有用的是完整请求 URL、header、body 和平台返回的 raw response。CI 默认日志不存这些,得自己补。
做法很简单,在发送方法末尾加:
注意三点:
别用
,生产环境默认不记录 debug 级别
敏感字段如
必须脱敏,记录时替换成
响应体可能含二进制或不可见字符,
更安全
最常被忽略的是:没验证短信模板 Code 是否已在平台审核通过。错误信息里藏在 response 的
字段,但如果你只看
==
就认为成功,实际发出去的是乱码或拦截提示。
application/libraries/vendor/$this->load->library('AliyunSms')application/libraries/AliyunSms.phpapp/Libraries/AliyunSms.phpUnable to load the requested class: AliyunSmsrequire_onceapplication/libraries/guzzlehttp/guzzle$this->load->library()$this->load->library('AliyunSms', $config)$this->config->item('aliyun_sms')AlibabaCloud\Tea\Exception\TeaExceptionaccess_key_idaccess_key_secretregion_idTencentCloud\Common\Exception\TencentCloudSDKExceptionSecretIdSecretKeyapplication/config/sms.php$config['aliyun_access_key_id'] = 'LTAI...';$this->CI->config->load('sms')https://dysmsapi.aliyuncs.comshttps://SmsCallbackAliyunSms$this->input->post()Content-Type: application/jsonSignaturesignSuccess: falselog_message('error', 'SMS request: ' . json_encode([
'url' => $url,
'headers' => $headers,
'body' => $params,
'response' => $response
]));log_message('debug')access_key_secret***json_encode($response, JSON_UNESCAPED_UNICODE)MessageCodeOK