thinkphp5实现短线验证注册,
思路:
1、一个表单,表单中要有一个手机字段,和密码。
2、在提交验证码添加点击事件,触发ajax,请求后台,发送短信。
3、后台中编写控制器方法, 一个ajax请求发送短信,一个表单验证成功条页面。
4、在config.php中输入、短信接口,和appkey。我使用的是京东万象,因为有免费的短信的测试,虽然就几条但是还是很开心。
5、在common.php中编写函数,一个发送短信的函数,一个是curl发送请求。
开始代码:
骨架和内容:html:这里我就写了一个简单的正则匹配手机号,和验证码,因为不使用正则, 他直接就进入后台控制器方法,所以正则匹配,在前端简单阻拦一下。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{$title}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSsMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<style>
.error{
line-height: 30px;
color:#ff0000;
}
</style>
</head>
<body>
<div style="margin:50px auto;width: 1200px;">
<h1>用户注册</h1>
<br>
<form class="form-horizontal" method="post" action="{:url('index/login/regOk')}">
{:token()}
<div class="form-group">
<label for="name" class="col-sm-2 control-label">昵称</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="username" id="name" placeholder="请输入昵称">
</div>
<span class="error"></span>
</div>
<div class="form-group">
<label for="phone" class="col-sm-2 control-label">手机号</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="phone" id="phone" placeholder="请输入手机号">
</div>
<span class="error"></span>
</div>
<div class="form-group">
<label for="code" class="col-sm-2 control-label">验证码</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="code" id="code" maxlength="4" placeholder="请输入验证码">
<button type="button" id = "btnsend" style="margin-top:15px;">发送验证码</button>
</div>
<span class="error"></span>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="password" id="password" placeholder="请输入密码">
</div>
<span class="error"></span>
</div>
<div class="form-group">
<label for="repassword" class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-3">
<input type="text" name="repassword" class="form-control" id="repassword" placeholder="请确认密码">
</div>
<span class="error"></span>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default">确认注册</button>
</div>
</div>
</form>
</div>
<script>
// 发送短信验证
$("#btnsend").click(function(){
// 手机号检测
if($("#phone").val() == ""){
$("#phone").closest(".form-group").find(".error").html("手机号不允许为空");
flag = false;
}else if(!/^1[3-9]\d{9}$/.test($("#phone").val())){
$("#phone").closest(".form-group").find(".error").html("手机号格式不正确");
flag = false;
}else{
$("#phone").closest(".form-group").find(".error").html("");
}
var data = {"phone":$("#phone").val()};
$.ajax({
url:"{:url('index/login/sendcode')}",
data:data,
dataType:'json',
success:function(res){
if(res.code != 10000){
alert("发送短信失败,请重新使用");
return;
}
}
})
})
// 表单提交验证
$(".btn").click(function(){
flag = true;
// 用户名检测
if($("#name").val() == ""){
$("#name").closest(".form-group").find(".error").html("用户名不能为空");
flag = false;
}else{
$("#name").closest(".form-group").find(".error").html("");
}
// 手机号检测
if($("#phone").val() == ""){
$("#phone").closest(".form-group").find(".error").html("手机号不允许为空");
flag = false;
}else if(!/^1[3-9]\d{9}$/.test($("#phone").val())){
$("#phone").closest(".form-group").find(".error").html("手机号格式不正确");
flag = false;
}else{
$("#phone").closest(".form-group").find(".error").html("");
}
// 验证码检测
if($("#code").val() == ""){
$("#code").closest(".form-group").find(".error").html("验证码不能为空");
flag = false;
}else if(!/^\d{4}$/igm.test($("#code").val())){
$("#code").closest(".form-group").find(".error").html("验证码格式不正确");
flag = false;
}else{
$("#code").closest(".form-group").find(".error").html("");
}
// 密码检测
if($("#password").val() == ""){
$("#password").closest(".form-group").find(".error").html("密码不能为空");
flag = false;
}else{
$("#password").closest(".form-group").find(".error").html("");
}
if($("#repassword").val() == ""){
$("#repassword").closest(".form-group").find(".error").html("确认密码不能为空");
flag = false;
}else{
$("#repassword").closest(".form-group").find(".error").html("");
}
if(flag){
$(".form-horizontal").submit();
}
})
</script>
</body>
</html>
然后配置config.php,
在最下面添加就可以
// 短信配置
'msg' => [
// 这个是我请求的短信接口地址
'gateway' => 'https://way.jd.com/chonry/voice',
'appkey' => '你的appkey'
],
开始控制器方法:
两个方法,ajax请求对象方法,和表单验证成功提交方法。
// 用户注册成功
public function regOk(Request $request)
{
$data = $request->param();
// 数据验证
$rule = [
'username' => 'require|token',
'phone' => 'require|number',
'code' => 'require|number|max:4',
'password' => 'require|confirm:repassword',
];
$msg = [
'username.require' => "姓名不允许为空",
'username.token' => "重复提交了哦",
'phone.require' => "手机号不允许为空",
'phone.number' => "手机号格式不正确,必须都要为数字",
'code.require' => "验证码不允许为空",
'code.number' => "验证码格式不正确,必须都要为数字",
'code.max' => "验证码最多为4位",
'password.require' => "密码不允许为空",
'password.confirm' => '密码不一致'
];
$validate = new \think\Validate($rule,$msg);
if(!$validate->check($data)){
$error = $validate->getError();
$this->error($error);
}
// 判断数据库中是否存在手机号
$result = \app\index\model\Index::where("usernum",'=',$data['phone'])->find();
if(isset($result)){
$res = [
'code' => 10002,
'msg' => "数据库存在"
];
return json($res);
}
// 获取存储在缓存中的验证码,并且判断和用户输入的是否一致
$code = cache("code");
if($code != $data['code']){
$this->error("验证码错误");
}
// 因为我的表名和数据库值 所以我就添加个字段传递过去
$data['usernum'] = $data['phone'];
// 这个是我使用的一个加密函数 默认密码可以直接使用md5加密
$data['password'] = md5passeword($data['password']);
// 到这一步说明上方的已经全部成功,所以直接入库
\app\index\model\Index::create($data,true);
//然后跳转到登陆页,
return $this->success("注册成功,请登录","index/login/index");
}
// 发送短信验证码 ajax请求的方法地址
public function sendcode(int $phone)
{
// 首先判断一下当前的手机号不允许为空
if(empty($phone)){
return "手机号不允许为空";
}
// 随机4位验证码
$code = mt_rand(1000,9999);
// 模板文件
$content = $code;
// 调用请求方法
$flag = sendmsg($phone,$content);
// 开发测试阶段 可以先不要发送出去,因为免费的比较少
# $flag = true;
if($flag === true){
cache("code",$code,120);
// 在这里可以输出一下
// echo $code;
$data = [
'code' => 10000,
'msg' => "成功"
];
return json($data);
}else{
$data = [
'code' => 10001,
'msg' => "发送短信失败",
];
return json($data);
}
}
开始编写重要的两个函数方法,一个是获取cofing配置中的路径,然后将这个路径通过curl的方式去请求接口。先判断是否有这个函数然后在创建函数,这个函数方法我是写在common.php方法中。
// 设置请求对象
if(!function_exists("sendmsg")){
// 短线验证函数
function sendmsg($phone,$content)
{
// 获取请求路径
$gateway = config('msg.gateway');
$appkey = config("msg.appkey");
// 拼接url
$url = $gateway."?mobile=".$phone."&voiceCode=".$content."&appkey=".$appkey;
// 调用curl 发送请求
$res = sendcurl($url,false,[],true);
if(!$res){
return false;
}
// 将获取到的请求信息转换成数组
$arr = json_decode($res,true);
if($arr['code'] != 10000){
return $arr['msg'];
}
return true;
}
}
// 设置curl发送请求
if(!function_exists("sendcurl")){
function sendcurl($url,$post=false,$param=[],$https = false)
{
// 初始化 curl请求
$cn = curl_init($url);
// 判断请求
if($post){
curl_setopt($cn,CURLOPT_PORT,true);
curl_setopt($cn,CURLOPT_POSTFIELDS,$param);
}
// 判断https请求
if($https){
curl_setopt($cn,CURLOPT_SSL_VERIFYPEER,false);
}
// 配置项,返回最后内容
curl_setopt($cn,CURLOPT_RETURNTRANSFER,true);
//发送请求
$res = curl_exec($cn);
// 关闭请求
curl_close($cn);
// 返回请求信息
return $res;
}
}
最后添一下我的数据表格式:
其实写到最后,逻辑通了就好写,优化的地方还有很多,同时这个功能,我感觉最难的应该就是curl请求方法,别的其实都还好。