php没有内置短信接口,需调用阿里云等第三方http api;失败主因是未按规则生成签名、时间戳超差或参数不匹配,须用sdk安全调用并校验ca证书。

PHP 本身没有内置的“短信接口”,所谓“开通 PHP 短信接口”,实际是调用第三方短信服务商(如阿里云、腾讯云、华为云、容联云等)的 HTTP API,再用 PHP 发起请求。不存在 PHP 官方或语言层面上的“开通”动作。
为什么 file_get_contents 或 curl_init 直接发请求会失败
多数人卡在这一步:写了几行 PHP 调用 URL,返回空、403、401 或 “签名错误”。根本原因不是代码写错,而是没理解短信接口的鉴权逻辑。
- 所有正规服务商都要求:每次请求必须带
AccessKeyId、Signature(签名)、Timestamp、Nonce等参数,且Signature需按特定规则拼接字符串后 HMAC-SHA256 加密 -
file_get_contents无法自动构造签名,硬拼 URL 会因时间戳/随机数/签名不匹配被直接拒绝 - 服务商控制台生成的
AccessKeySecret绝对不能写死在前端或日志里,PHP 后端也需通过环境变量或配置文件加载
阿里云 SMS 的 SendSms 接口怎么安全调用
以最常用的阿里云为例,它不提供原生 PHP SDK 的 Composer 包(官方已归档),但推荐用其新版 AlibabaCloud\TeaOpenApi + AlibabaCloud\Dysmsapi 组合,而非手写 cURL。
- 先执行
composer require alibabacloud/dysmsapi(注意不是aliyun-openapi-php-sdk,那个已废弃) - 初始化客户端时,
accessKeyId和accessKeySecret必须从$_ENV或.env读取,禁止明文写在代码里 - 发送时,
PhoneNumbers字段必须是字符串格式(如"13812345678"),不能是整数,否则触发 400 错误 - 模板
TemplateCode必须和控制台里审核通过的完全一致,大小写、下划线都不能错
$client = \AlibabaCloud\Dysmsapi\V20170525\Dysmsapi::create($config)
->withRegion('cn-shanghai');
$response = $client->sendSms([
'PhoneNumbers' => '13812345678',
'SignName' => '你的备案签名',
'TemplateCode' => 'SMS_123456789',
'TemplateParam'=> json_encode(['code' => '1234'], JSON_UNESCAPED_UNICODE)
]);
本地测试时 cURL error 60 或证书报错怎么办
这是 macOS / WAMP / 某些 Docker 环境常见问题,本质是 PHP 的 cURL 缺少可信 CA 证书,导致 HTTPS 请求失败,和短信逻辑无关。
立即学习“PHP免费学习笔记(深入)”;
- 不要改
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false)—— 这等于关掉 HTTPS 校验,生产环境绝对禁止 - 正确做法:下载最新
ca-bundle.crt(如从 https://curl.se/ca/cacert.pem),路径存入 php.ini 的curl.cainfo和openssl.cafile - 验证是否生效:运行
php -r "print_r(openssl_get_cert_locations());",看default_cert_file是否指向你刚配置的路径 - 如果用 Swoole 或 Hyperf,还要检查
co\http\Client是否继承了这个配置,它默认不读 php.ini
真正难的从来不是“怎么发一条短信”,而是签名生成逻辑是否严格对齐文档、时间戳是否与服务器误差在 15 分钟内、模板变量类型是否和审核时声明的一致——这些细节出错,返回的错误信息往往很模糊,比如只说 “InvalidParameter”。











