将相关代码整理出来,可以直接调取引用
华为云短信的参数需要自己去注册华为云账号,然后去购买套餐,相关参数里面都有,获取并不复杂
class HuaWeiSMS
{
const APP_KET = 'xxxxxxxxxxxxx';//APP_Key
const APP_SECRET = 'xxxxxxxxxxxxxxx';//APP_Secret
const URL = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1';//APP接入地址(在控制台"应用管理"页面获取)+接口访问URI
const 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);
}
}
}