crmeb_pro 框架内置了一个短信服务,但是根据群评价经常有人反馈不稳定,所以自行接入阿里云
文件地址 app\services\user\LoginService.php
找到 verify
函数,对比以下代码,把自己的配置改改即可使用
接入代码是通用的,什么项目都可以用,具体看这篇文章 阿里云短信API快速接入
<?php
/**
* 发送验证码
* @param $phone
* @param $type
* @param $time
* @param $ip
* @return int
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function verify($phone, $type, $time, $ip)
{
if ($this->dao->getOne(['account' => $phone]) && $type == 'register') {
throw new ValidateException('手机号已注册');
}
$default = Config::get('sms.default', 'yunxin');
$defaultMaxPhoneCount = Config::get('sms.maxPhoneCount', 10);
$defaultMaxIpCount = Config::get('sms.maxIpCount', 50);
$maxPhoneCount = Config::get('sms.stores.' . $default . '.maxPhoneCount', $defaultMaxPhoneCount);
$maxIpCount = Config::get('sms.stores.' . $default . '.maxIpCount', $defaultMaxIpCount);
/** @var SmsRecordServices $smsRecord */
$smsRecord = app()->make(SmsRecordServices::class);
if ($smsRecord->count(['phone' => $phone, 'add_ip' => $ip, 'time' => 'today']) >= $maxPhoneCount) {
throw new ValidateException('您今日发送得短信次数已经达到上限');
}
if ($smsRecord->count(['add_ip' => $ip, 'time' => 'today']) >= $maxIpCount) {
throw new ValidateException('此IP今日发送次数已经达到上限');
}
/*-------------------------------------------------*/
/**
*
*$phon 电话号码
*$AccessKeyId 密钥
*$accessKeySecret 密匙
*$SignName 签名
*$TemplateCode 模版id
*$TemplateParam array 模版值
*
*/
function alisms($phone, $AccessKeyId, $accessKeySecret, $SignName, $TemplateCode, $TemplateParam, $domain = 'dysmsapi.aliyuncs.com') {
$apiParams["PhoneNumbers"] = $phone; //手机号
$apiParams["SignName"] = $SignName; //签名
$apiParams["TemplateCode"] = $TemplateCode; //短信模版id
$apiParams["TemplateParam"] = json_encode($TemplateParam); //模版内容
$apiParams["AccessKeyId"] = $AccessKeyId; //key
$apiParams["RegionId"] = "cn-hangzhou"; //固定参数
$apiParams["Format"] = "json"; //返回数据类型,支持xml,json
$apiParams["SignatureMethod"] = "HMAC-SHA1"; //固定参数
$apiParams["SignatureVersion"] = "1.0"; //固定参数
$apiParams["SignatureNonce"] = uniqid(); //用于请求的防重放攻击,每次请求唯一
date_default_timezone_set("GMT"); //设置时区
$apiParams["Timestamp"] = date('Y-m-d\TH:i:s\Z'); //格式为:yyyy-MM-dd’T’HH:mm:ss’Z’;时区为:GMT
$apiParams["Action"] = 'SendSms'; //api命名 固定子
$apiParams["Version"] = '2017-05-25'; //api版本 固定值
$apiParams["Signature"] = computeSignature($apiParams, $accessKeySecret); //最终生成的签名结果值
$requestUrl = "http://". $domain . "/?";
foreach ($apiParams as $apiParamKey => $apiParamValue) {
$requestUrl .= "$apiParamKey=" . urlencode($apiParamValue) . "&";
}
return curl(substr($requestUrl, 0, -1));
}
function computeSignature($parameters, $accessKeySecret) {
ksort($parameters);
$canonicalizedQueryString = '';
foreach ($parameters as $key => $value) {
$canonicalizedQueryString .= '&' . percentEncode($key) . '=' . percentEncode($value);
}
$stringToSign = 'GET&%2F&' . percentencode(substr($canonicalizedQueryString, 1));
$signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . "&", true)); ;
return $signature;
}
function percentEncode($str) {
$res = urlencode($str);
$res = preg_replace('/\+/', '%20', $res);
$res = preg_replace('/\*/', '%2A', $res);
$res = preg_replace('/%7E/', '~', $res);
return $res;
}
function curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$httpResponse=curl_exec($ch);
if($httpResponse){
return json_decode($httpResponse);
}else{
return json_decode(curl_error($ch));
}
curl_close($ch);
}
/*---------------------------------*/
if (CacheService::get('code_' . $phone))
throw new ValidateException($time . '分钟内有效');
mt_srand();
$code = rand(100000, 999999);
$data['code'] = $code;
$data['time'] = $time;
$result = alisms($phone, 'LTAI5t9XXX', 'qGNG9FTCXXX', '只只云', 'SMS_66666', ['code' => $code]);
if($result->Code == 'OK'){
return $code;
} else {
throw new ValidateException('短信平台验证码发送失败');
}
// $res = SmsJob::dispatch([$phone, $data, 'VERIFICATION_CODE_TIME']);
// if (!$res)
// throw new ValidateException('短信平台验证码发送失败');
// return $code;
}
当然,在这里处理的话是不如在任务队列处理更好的,如果用户量大还是放在队列处理,在任务队列处理的方式请看下一篇网站