将相关代码整理出来,可以直接调取引用
华为云短信的参数需要自己去注册华为云账号,然后去购买套餐,相关参数里面都有,获取并不复杂
class HuaWeiSMS
{const APP_KET = 'xxxxxxxxxxxxx';//APP_Keyconst APP_SECRET = 'xxxxxxxxxxxxxxx';//APP_Secretconst URL = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1';//APP接入地址(在控制台"应用管理"页面获取)+接口访问URIconst SIGN = 'xxxxxxx'; //模板签名const SENDER = '00000000000'; //国内短信签名通道号public function sendSmsCode($phone, $code){//必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔$phone = $this->formatPhone($phone);//请求Body$data = http_build_query(['from' => self::SENDER,'to' => $phone,'templateId' => '64df850d86194e1088b817513bf4ed7b', //模板ID'templateParas' => '["'.$code.'"]', //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。,'statusCallback' => '', //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告'signature' => self::SIGN //使用国内短信通用模板时,必须填写签名名称]);$contextOptions = ['http' => ['method' => 'POST', 'header'=> $this->setRequestHeader(), 'content' => $data, 'ignore_errors' => true],'ssl' => ['verify_peer' => false, 'verify_peer_name' => false] //为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题];$response = file_get_contents(self::URL, false, stream_context_create($contextOptions));if(empty($response)) throw new Exception('发送失败',0);$response = json_decode($response,true);if(empty($response['code']) || $response['code'] != "000000") throw new Exception('发送失败',0);return $response;}protected function setRequestHeader(){//构造X-WSSE参数值date_default_timezone_set('Asia/Shanghai');$now = date('Y-m-d\TH:i:s\Z'); //Created$nonce = uniqid(); //Nonce$base64 = base64_encode(hash('sha256', ($nonce . $now . self::APP_SECRET))); //PasswordDigest$xWsse = sprintf("UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"",self::APP_KET, $base64, $nonce, $now);$headers = ['Content-Type: application/x-www-form-urlencoded','Authorization: WSSE realm="SDP",profile="UsernameToken",type="Appkey"','X-WSSE: ' . $xWsse];return $headers;}protected function formatPhone($phoneStr){$resPhone = '';$phoneList = explode(',', $phoneStr);foreach ($phoneList as $phone) {$resPhone .= '+86' . $phone . ',';}$resPhone = trim($resPhone, ',');return $resPhone;}
}
然后是调取的controller类
//发送手机验证码
public function send_sms()
{$data = $this->request->param();$phone = $data['phone'];if(!preg_match("/^1[34578]\d{9}$/", $phone)){throw new Exception('手机号格式错误!',300);}$code = rand(100000,999999);(new SMSExport())->sendSmsCode($phone, $code);//具体引入路径,看自己放置发送短信类的放置路径Cache::set($phone,$code);
}
这里采用的是tp5自带的缓存进行存储的,也可以用数据库存储,存最后一次的验证码,然后,取数据库的字段进行验证,但是不如这个缓存更快捷一些。
验证方法(仅供参考)
//验证手机验证码并修改密码public function check_sms(){$data = $this->request->param();$code1 = intval($data['code']);$phone = $data['phone'];$password = $data['password'];$code2 = Cache::get($phone);if($code1 !== $code2){throw new Exception('验证码不正确',300);}else{$value['password'] = md5($password);$value['password2'] = $password;$res = Db::name('shop_admin')->where(['phone'=>$phone])->update($value);if ($res) {return Json::success();}else{throw new Exception('修改失败',300);}}}