直接在common.php写函数最轻量但需手动加载SDK、处理命名空间和错误响应;用dh2y/think-sms等Composer包更规范,支持多服务商切换与异步发送,且内置重试、限流、日志等能力。

直接在 common.php 里写函数最轻量,但必须手动加载 SDK、处理命名空间和错误响应;用 Composer 包(如 dh2y/think-sms)更规范,适合多服务商切换或需队列异步发送的场景。
把阿里云 SDK 放进 extend/ 并手动封装函数
这是 TP5 最常见的做法,不依赖 Composer 自动加载,可控性强,但容易漏掉关键步骤:
-
api_sdk解压后改名(比如alisms),放进extend/目录,不是vendor/—— TP5 的EXTEND_PATH常量只认这个位置 - 函数开头必须加
require_once EXTEND_PATH.'alisms/vendor/autoload.php';,否则Config、DefaultProfile都会报类未找到 -
SendSmsRequest类路径要显式引入:require_once EXTEND_PATH.'alisms/lib/Api/Sms/Request/V20170525/SendSmsRequest.php';,新版 SDK 中该文件不在自动加载范围内 - 模板参数必须是 JSON 字符串,且双引号要转义:
$request->setTemplateParam("{\"code\":\"{$code}\"}");,写成{'code':'{$code}'}或裸字符串会触发阿里云 400 错误
用 dh2y/think-sms 实现可切换短信服务商
当你需要支持阿里云、腾讯云甚至自建网关时,这个包能省掉大量重复胶水代码:
- 安装后要在
config/sms.php里配'class' => 'Aliyun',并填入access_key_id、access_key_secret、sign_name、template_code - 签名和模板必须已在阿里云控制台审核通过,否则返回
isv.SMS_SIGNATURE_ILLEGAL或isv.TEMPLATE_MISSING - 验证码场景文案用
SMS_SCENE配置,其中%code%是占位符,会被自动替换,不用手拼 JSON - 调用时传场景名即可:
Sms::getInstance()->sendSmsCode($phone, 'register');,内部已处理异常捕获和日志记录
为什么不能直接 require vendor 里的 SDK?
TP5.0/5.1 默认不扫描 vendor/ 下非 Composer 包的目录,即使你把 aliyun-php-sdk-core 放进去,DefaultProfile 依然找不到 —— 因为它的 autoload.php 依赖 PSR-4 规则注册,而官方 SDK 的 composer.json 没有正确声明命名空间映射。硬塞进 vendor/ 只会让 Class not found 更难排查。
发不出短信?先检查这三处
90% 的失败都卡在这几个地方:
- 阿里云 RAM 子账号没给
AliyunDysmsReadOnlyAccess或更细粒度的AliyunDysmsFullAccess权限,主账号密钥虽能用但不安全 -
region写成cn-shanghai却没在DefaultProfile::addEndpoint()里注册对应 endpoint,必须严格匹配cn-hangzhou(国内默认) - 手机号带
+86前缀或空格,setPhoneNumbers()会静默失败,只接受纯数字字符串(如13812345678)
真正麻烦的不是调通第一次,而是后续要加重试、限流、失败告警——这些在手动封装里得自己补,在 think-sms 里可以配合 think-queue + Redis 快速落地。别省那十几行代码,后期维护成本差十倍。

















