手机号码绑定操作
这里我实现了一个通过发送短信绑定手机号的功能,这里主要的实现与之前发送邮箱注册差别不大,比较大的区别就是发送短信需要发送curl请求api地址,来让第三方发送我们写好的验证码。具体发送的逻辑代码差别不大,就是在发送验证码时使用redis上锁60s,在60s时间中,若验证码成功验证则将锁删除。这样就可以实现绑定手机号的操作。
控制器代码
/*
* 用户通过手机号发送短信
*/
public function bindPhone()
{
$conn = getRedis();
$conn->selectDb(0);
$data = $this->input->post();
if (empty($data['id']) || empty($data['phone'])) {
fail(400, '参数错误!');
}
$res1 = validate_phone($data['phone']);
if (!$res1) {
fail(400, '手机号码格式错误!');
}
$res2 = $this->users_model->existPhone($data['phone']);
if ($res2) {
fail(400, '该手机号码已经绑定!');
}
$res = $this->users_model->checkUser($data['id']);
if (!$res) {
fail(400, '该用户不存在!');
}
$key = $data['id'] . "_msg_".$data['phone'];
//通过手机号发送短信验证码
$code = rand_code(4);
//上锁
if (!$conn->setNx($key,$code)){
fail(400,"您操作的太快了!上个验证码还未过期!");
}
//60秒过期
$conn->expire($key,60);
$status = send_msg($data['phone'], $code);
if (!$status) {
//发送短信失败!
//删除缓存
$conn->del($key);
fail(400,'短信发送失败!');
}
success($code,"发送成功!");
}
/*
* 绑定手机号
*/
public function bindPhoneSubmit()
{
$conn = getRedis();
$conn->selectDb(0);
$data = $this->input->post();
if (empty($data['id']) || empty($data['phone']) || empty($data['code'])) {
fail(400, '参数错误!');
}
$res1 = validate_phone($data['phone']);
if (!$res1) {
fail(400, '手机号码格式错误!');
}
$res2 = $this->users_model->existPhone($data['phone']);
if ($res2) {
fail(400, '该手机号码已经绑定!');
}
$res = $this->users_model->checkUser($data['id']);
if (!$res) {
fail(400, '该用户不存在!');
}
//验证短信验证码是否正确
$key = $data['id'] . "_msg_".$data['phone'];
$code = $conn->get($key);
if (empty($code)){
fail(400,'未发送验证码!');
}
if ($code != $data['code'])
{
fail(400,'验证码错误!');
}
//执行绑定手机号操作
$res = $this->users_model->bindPhoneSubmit($data);
if (!$res){
fail(400,'操作失败!');
}
//成功将redis中的验证码删除
$conn->del($key);
success([],'绑定手机号成功');
}
发送短信操作使用的功能函数
/*
* 验证手机号码是否正确
*/
if (!function_exists('validate_phone')) {
function validate_phone($phone)
{
$rules = "/^1[34578]\d{9}$/";
return preg_match($rules, $phone);
}
}
//发送curl请求函数
if (!function_exists('curl_request')) {
function curl_request($url, $post = true, $params = array(), $https = true)
{
//初始化请求会话
$ch = curl_init($url);
if ($post) {
//设置请求方式为post
curl_setopt($ch, CURLOPT_POST, true);
//设置请求参数
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
if ($https) {
//如果是https协议,禁止服务器验证本地证书
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
//发送请求,获取返回参数
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
//关闭请求
curl_close($ch);
return $res;
}
}
/*
* 发送短信接口
*/
if (!function_exists('send_msg')) {
function send_msg($phone, $msg)
{
//这里我将一些参数写在config文件中
$app_key = config_item('msg_app_key');
$url = config_item('msg_url');
$sign = config_item('sign');
$content = "您的本次的验证码是:" . $msg . "。";
$url = $url . '?sign=' . $sign . '&mobile=' . $phone . '&content=' . $content . '&appkey=' . $app_key;
//这里因为我已经将测试次数用完所以关闭(正常需要打开)
//$data = curl_request($url,false);
//$data = json_decode($data,true);
//$data['code'] == 10000 ? $status = true : $status =false;
//测试(这里正常需要关闭)
//设置短信发送成功
$status = true;
return $status;
}
}
模型操作
public function bindPhoneSubmit($data)
{
$this->db->update('users', ['phone' => $data['phone']], ['id' => $data['id']]);
return $this->db->affected_rows() ? true : false;
}
这里我就不放运行结果了,这里的功能可以实现。