应使用 jacobcyl/aliyunsms 而非 aliyun/aliyun-openapi-php-sdk,因其专为 laravel 设计,支持 .env 配置、服务提供者和队列,避免签名失败、参数校验错误及初始化问题。

直接用 aliyun/aliyun-openapi-php-sdk 在 Laravel 里发短信,大概率会卡在签名失败、参数校验不通过、或 SDK 初始化报错——不是 Laravel 不兼容,而是阿里云新版 OpenAPI SDK(v2+)默认不支持 Laravel 的自动加载和配置管理方式。
为什么不能直接 composer require aliyun/aliyun-openapi-php-sdk
这个 SDK 是面向传统 PHP 脚本设计的,依赖全局 require_once 和手动实例化客户端,没有服务提供者、不读取 .env、也不适配 Laravel 的容器绑定。强行引入会导致:
-
AlibabaCloud\Client\AlibabaCloud类找不到(autoload 未注册) - 每次发短信都要重复写 endpoint、accessKeyId、accessKeySecret,无法复用配置
- 签名算法用的是旧版
ACS,而阿里云短信新控制台强制要求RPC风格 +V2签名
推荐方案:用 aliyun-dysms-php + 自定义 Facade
这是目前最轻量、最稳定、且适配 Laravel 8+ 的选择。它只封装短信核心逻辑,不带 SDK 依赖,所有参数走 config() 和 .env,还能无缝接入队列。
操作步骤:
- 执行
composer require jacobcyl/aliyunsms(注意作者是jacobcyl,不是官方包) - 发布配置:运行
php artisan vendor:publish --provider="Jacobcyl\AliyunSms\AliyunSmsServiceProvider" - 在
.env中填入:ALIYUN_SMS_ACCESS_KEY_ID=xxx、ALIYUN_SMS_ACCESS_KEY_SECRET=yyy、ALIYUN_SMS_REGION_ID=cn-hangzhou、ALIYUN_SMS_SIGN_NAME="你的签名"、ALIYUN_SMS_TEMPLATE_CODE="SMS_123456789" - 发短信示例:
$result = \AliyunSms::sendSms('13800138000', ['code' => '1234'], 'SMS_123456789');返回数组含Code、Message、BizId,不用再手动解析 XML/JSON
发送失败常见错误及对应处理
实际部署时最常遇到三个报错,都跟配置或环境强相关:
-
InvalidAccessKeyId.NotFound:检查ALIYUN_SMS_ACCESS_KEY_ID是否复制了空格,是否用了 RAM 子账号但没给AliyunDysmsFullAccess权限 -
isv.BUSINESS_LIMIT_CONTROL:新申请的 AccessKey 默认有流控(1 条/秒),测试期建议先在阿里云控制台把短信模板设置为“测试模板”,或提交工单提额 -
SignatureDoesNotMatch:90% 是因为ALIYUN_SMS_REGION_ID写成了https://dysmsapi.aliyuncs.com这种完整 URL,它只要区域 ID,比如cn-hangzhou
如果必须用官方 SDK(比如要同时调用 OSS + 短信)
可以保留 aliyun/aliyun-openapi-php-sdk,但得绕过它的 autoload 机制,手动引入关键类:
- 下载 SDK 源码,把
aliyun-openapi-php-sdk/aliyun-openapi-php-sdk/aliyun-php-sdk-core和aliyun-openapi-php-sdk/aliyun-openapi-php-sdk/aliyun-php-sdk-dysmsapi复制到app/Services/Aliyun/ - 在
AppServiceProvider::boot()中加:require_once app_path('Services/Aliyun/core/Config.php');<br>require_once app_path('Services/Aliyun/dysmsapi/Dysmsapi.php'); - 构造客户端时显式指定
RegionId和Endpoint:$client = new DefaultAcsClient(\Aliyun\Core\Profile\DefaultProfile::getProfile(<br> config('aliyun_sms.region_id'),<br> config('aliyun_sms.access_key_id'),<br> config('aliyun_sms.access_key_secret')<br>));<br>$client->setEndpoint('https://dysmsapi.aliyuncs.com');
这种做法维护成本高,升级 SDK 就得重新复制文件,仅建议已有项目深度耦合官方 SDK 的场景。










