123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- <?php
- namespace ali;
- use app\common\model\SettingModel;
- use think\facade\Log;
- /**
- * 阿里云短信服务 PHP 示例
- *
- * 功能:
- * 1. 自动生成签名
- * 2. 支持单条短信发送
- * 3. 完善的错误处理
- * 4. 响应结果解析
- */
- class Ali
- {
- // 阿里云短信服务配置
- private $accessKeyId; // 替换为您的AccessKey ID
- private $accessKeySecret; // 替换为您的AccessKey Secret
- private $signName; // 短信签名
- private $regionId = 'cn-hangzhou'; // 区域ID
- private $endpoint = 'dysmsapi.aliyuncs.com'; // 短信服务域名
- // 发送短信
- public function send($phone, $smslog_param)
- {
- $config = SettingModel::getConfigValue(['sms_ali_accesskeyid', 'sms_ali_accesskeysecret', 'sms_ali_signname']);
- if (empty($config['sms_ali_accesskeyid']) || empty($config['sms_ali_accesskeysecret']) || empty($config['sms_ali_signname'])) {
- return ['code' => 1, 'msg' => '请绑定模板参数'];
- }
- //模板编号
- $templateCode = $smslog_param['template']['ali'];
- if (empty($templateCode)) {
- return ['code' => 1, 'msg' => '系统未配置阿里模板编号'];
- }
- $this->accessKeyId = $config['sms_ali_accesskeyid'];
- $this->accessKeySecret = $config['sms_ali_accesskeysecret'];
- $this->signName = $config['sms_ali_signname'];
- $templateParam = $smslog_param['template_param'];
- // 公共参数
- $params = [
- 'RegionId' => $this->regionId,
- 'AccessKeyId' => $this->accessKeyId,
- 'Format' => 'JSON',
- 'SignatureMethod' => 'HMAC-SHA1',
- 'SignatureVersion' => '1.0',
- 'SignatureNonce' => uniqid(),
- 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
- 'Action' => 'SendSms',
- 'Version' => '2017-05-25',
- 'PhoneNumbers' => $phone,
- 'SignName' => $this->signName,
- 'TemplateCode' => $templateCode,
- ];
- // 添加模板参数(如果有)
- if (!empty($templateParam)) {
- $params['TemplateParam'] = json_encode($templateParam);
- }
- // 生成签名
- $params['Signature'] = $this->generateSignature($params);
- // 构建请求URL
- $url = 'https://' . $this->endpoint . '/?' . http_build_query($params);
- // 发送HTTP请求
- return $this->sendRequest($url);
- }
- // 生成签名
- private function generateSignature($params)
- {
- // 参数排序
- ksort($params);
- // 构造查询字符串
- $queryString = '';
- foreach ($params as $key => $value) {
- $queryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
- }
- // 构造签名字符串
- $stringToSign = 'GET&%2F&' . $this->percentEncode(substr($queryString, 1));
- // 计算签名
- $signature = base64_encode(hash_hmac('sha1', $stringToSign, $this->accessKeySecret . '&', true));
- return $signature;
- }
- // URL编码
- private function percentEncode($str)
- {
- $res = urlencode($str);
- $res = str_replace(['+', '*'], ['%20', '%2A'], $res);
- $res = preg_replace('/%7E/', '~', $res);
- return $res;
- }
- // 发送HTTP请求
- private function sendRequest($url)
- {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- $response = curl_exec($ch);
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- if (curl_errno($ch)) {
- Log::error('短信发送失败:' . curl_error($ch));
- return ['code' => 1, 'msg' => '短信发送失败'];
- }
- curl_close($ch);
- if ($httpCode !== 200) {
- Log::error('短信发送失败,状态码:' . $httpCode);
- return ['code' => 1, 'msg' => '短信发送失败,状态码:' . $httpCode];
- }
- $res = json_decode($response, true);
- if ($res['Code'] == 'OK') {
- return ['code' => 0];
- } else {
- Log::error('短信发送失败:' . $response . "。原始参数:" . $url);
- return ['code' => 1, 'msg' => $res['Message']];
- }
- }
- }
|