|
@@ -0,0 +1,132 @@
|
|
|
+<?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' => '请绑定模板参数'];
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->accessKeyId = $config['sms_ali_accesskeyid'];
|
|
|
+ $this->accessKeySecret = $config['sms_ali_accesskeysecret'];
|
|
|
+ $this->signName = $config['sms_ali_signname'];
|
|
|
+ $templateCode = $smslog_param['template_code'];
|
|
|
+ $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']];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|