短信验证码在目前大多数web应用中都会有,本文介绍一个基于Yii2 Validator方式的验证码验证方式。
在其他文章中看到的方式大多比较难做到一次封装,多次重用。
使用此方式的好处自然不用多说,Validator支持在Model和Form中使用,使用的时候只需要在rules中添加一条验证规则即可。 第一步: 准备数据表,用来存储短信验证码 CREATE TABLE `tbl_sms_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`to` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`usage` varchar(20) NOT NULL DEFAULT '' COMMENT '用途',
`code` varchar(6) DEFAULT NULL COMMENT '验证码',
`result` varchar(80) DEFAULT '' COMMENT '发送结果',
`error_code` varchar(255) DEFAULT '' COMMENT '错误码',
`error_msg` varchar(255) DEFAULT '' COMMENT '错误信息',
`used` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否使用',
`use_time` int(11) DEFAULT '0' COMMENT '使用时间',
`create_time` int(11) DEFAULT '0' COMMENT '发送时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;
表结构可根据项目实际场景进行细节调整。
创建好数据表之后, 再使用Gii生成对应的Model类app\models\SmsLog 第二步: 创建短信验证码验证器, app\validators\SmscodeValidator namespace app\validators; use app\models\SmsLog;
use yii\validators\Validator; /**
* 短信验证码验证器
* Class SmscodeValidator
*/
class SmscodeValidator extends Validator
{
/**
* 对应Smslog表中的usage字段,用来匹配不同用途的验证码
* @var string sms code type
*/
public $usage;
/**
* Model或者form中提交的手机号字段名称
* @var string
*/
public $phoneAttribute = 'cellphone';
/**
* 验证码过期时间
* @var int
*/
public $expireTime = 10800; /**
* @param \yii\base\Model $model
* @param string $attribute
*/
public function validateAttribute($model, $attribute)
{
$fieldName = $this->phoneAttribute;
$cellPhone = $model->$fieldName; $smsLog = SmsLog::find()->where([
'to' => $cellPhone,
'usage' => $this->usage
])->orderBy('create_time DESC')->one(); /** @var $smsLog SmsLog */
$time = time();
if(
is_null($smsLog) ||
($smsLog->code != $model->$attribute) ||
($smsLog->create_time > $time || $time > ($smsLog->create_time + $this->expireTime) )
) {
$this->addError($model, $attribute,'验证码有误');
}else{
$smsLog->used = 1;
$smsLog->use_time = $time;
$smsLog->save();
}
} } 第三步: 使用方法, 在Model或者Form中添加Rules 例如, 在用户注册使用,前端通过ajax请求后台向指定手机号,发送了验证码
在验证的时候只需要添加一条rule:
['verifyCode', '\app\validators\SmscodeValidator', 'usage' => 'userRegister' ], 完整的rule,可以覆盖SmscodeValidator中的三个属性的值
['verifyCode', '\app\validators\SmscodeValidator', 'usage' => 'userRegister', 'phoneAttribute' => '手机号字段名称', 'expireTime' => '短信验证码有效时间' ], RegisterForm.php namespace mobile\models; use yii; class RegisterForm extends AjaxForm
{
const VERCODE_USAGE = 'userRegister';
public $cellphone;
public $verifyCode;
public $password; public function rules()
{
return [
[['cellphone', 'verifyCode', 'password'], 'required'],
['verifyCode', '\common\validators\SmscodeValidator', 'usage' => self::VERCODE_USAGE ],
['password' , 'string', 'min' => 6, 'max' => 32], ['cellphone', 'filter', 'filter' => 'trim'],
['cellphone', 'match', 'pattern'=>'/^1[34578][0-9]{9}$/','message'=>'请输入正确的手机号'],
['cellphone', 'unique', 'targetClass' => '\mobile\models\User', 'message' => '此手机号已经被注册'],
];
} /**
* 用户注册
* @return User|null
*/
public function register()
{
if($this->validate()) {
$user = new User();
$user->cellphone = $this->cellphone;
$user->username = $this->cellphone;
$user->setPassword($this->password);
$user->cellphone_verified = 1;
$user->create_from = Yii::$app->id;
$user->create_ip = Yii::$app->request->getUserIP();
$user->create_time = time();
if($user->save()) {
return $user;
}
}
return null;
} public function attributeLabels()
{
return [
'truename' => '真实姓名',
'cellphone' => '手机号码',
'verifyCode' => '验证码',
'password' => '密码',
'repassword' => '确认密码'
];
}
} 当然, 首先你得利用自己的方式(比如,前端点击form中按钮,利用Ajax请求后台发送验证码)发送验证码。
本文的主要目的是能让大家能够通过一条rule快捷实现短信验证的目的。

  

Yii2在Form中处理短信验证码的Validator,耦合度最低的短信验证码验证方式的更多相关文章

  1. iOS中打电话、打开网址、发邮件、发短信等

    常用小功能 小功能简介 iOS中的很多小功能都是非常简单的,几行代码就搞定了,比如打电话.打开网址.发邮件.发短信等 打电话-方法1 最简单最直接的方式:直接跳到拨号界面 NSURL *url = [ ...

  2. C#调用SMS短信接口,轻松搞定发送短信的任务。。。。

    首先我们需要去这里http://sms.webchinese.cn/申请一个账号和短信接口秘钥,在该网址下有许多语言的demo介绍,下面我主要为大家贴一个C#中的Helper类: using Syst ...

  3. ABP框架中短信发送处理,包括阿里云短信和普通短信商的短信发送集成

    在一般的系统中,往往也有短信模块的需求,如动态密码的登录,系统密码的找回,以及为了获取用户手机号码的短信确认等等,在ABP框架中,本身提供了对邮件.短信的基础支持,那么只需要根据自己的情况实现对应的接 ...

  4. VB短信猫开发包,支持超长短信

    一.短信猫开发包(长短信/异步调用)说明:   短信猫开发包以OCX控件的形式提供,支持Windows平台下常用的开发工具:如VB.VB.net.VC++.Power Builder.C#.DELPH ...

  5. form中button特殊功能

    描述:写弹窗的时候发现,form中的button,不对它进行什么设置,它会有默认的操作,点击“发送验证码”或者“提交申请”,它都会退出弹窗(取消遮罩层) 解决:button有不同的type属性,只需要 ...

  6. ligerui_实际项目_003:form中添加数据,表格(grid)里面显示,最后将表格(grid)里的数据提交到servlet

    实现效果: "Form"中填写数据,向本页"Grid"中添加数据,转换成Json数据提交,计算总和,Grid文本框可编辑,排序 图片效果: 总结: //disp ...

  7. 为Form中的控件增加自适应功能 转

    创建一个基于Custom的类resizeable,并新建属性和方法程序,其说明如下: a) 新建属性: posiTyperList 可调整位置的控件类型列表sizeTypeList 可调整大小的控件类 ...

  8. HTML 之 Web页面表单form中只有一个input的text元素,按回车默认提交

    WEB开发中,如果页面的 form 中只有一个input元素,在该input元素的输入框中按回车(注:此时并没有写对应的onkeydown等事件处理),则浏览器会默认提交表单,请看如下代码: < ...

  9. Oracle Developer Form中Block的重新查询

    Form中某些按钮可能调用了Package对表中某些字段进行更新,但是数据库中字段的修改不会马上反映到form的界面上,所以要进行重新查询,但是用户可能使用了查询窗口进行查询之后然后再点击按钮动作,如 ...

随机推荐

  1. 一张图看懂高通QC1.0-QC4.0快充进化之路!QC2.0跟QC3.0充电区别

    快充技术日新月异,快充市场百家争鸣的今天,高通QC快充依然主导着市场.如今QC快充已发展到第四代,每一代都有着革命性的进步.从QC1.0到QC4.0更新换代时间之短,不免让广大人民群众抱怨. “啥?老 ...

  2. scp 远程复制

    1. 上传本地文件到远程机器指定目录 命令: scp /opt/soft/nginx-0.5.38.tar.gz root@192.168.120.204:/opt/soft/scptest 上传本地 ...

  3. 【转】C#事件、委托、回调的用法与区别

    原文地址:http://blog.csdn.net/huang9012/article/details/38753305 事件包括:事件发送者.事件接收者和事件处理程序.关于事件,我们首要知道的是事件 ...

  4. 如何卸载windows的服务?卸载服务?

    前面小编给大家介绍过如何禁用一些不需要的服务: 但是哪些多余的服务其实完成时可以直接卸载掉的: 所以今天小编将指导大家如何卸载一些不需要的服务: 切记请一定要确认卸载的是不需要的服务哦: 工具/原料 ...

  5. c++ 字符输入读取

    cin.clear()重置输入流 cin.get()锁住屏幕直到获取输入 while(cin) cin.get(ch) 方法返回的是一个cin对象,istream类提供了可以将istream对象转换为 ...

  6. Tomcat官方文档关于数据源配置的内容

    虽然有网上有网友自己总结的文章,但说明得总是不够清晰,还是参考官方文档理解得比较透彻: http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html h ...

  7. Latex编译后Yap查看报错Not all fonts could be loaded

    在用Latex写中文大论文时,编译后,用Yap查看DVI文件,打开时,Yap报错: "Not all fonts could be loaded. See 'File->Documen ...

  8. 模板导入 {include 模块名}

    模板导入可以和上面讲的模板继承一起使用, 可以使用模板的批量复制和导入 下面举一个例子 我们先写一个需要导入模块的html  tp1 {% extends 'master.html' %} {% bl ...

  9. Python基础补充(二) 多核CPU上python多线程并行的一个假象【转】

    在python上开启多个线程,由于GIL的存在,每个单独线程都会在竞争到GIL后才运行,这样就干预OS内部的进程(线程)调度,结果在多核CPU上: python的多线程实际是串行执行的,并不会同一时间 ...

  10. PHP - 用户异常断开连接,脚本强制继续执行,异常退出回调

    试想如下情况.如果你的用户正在执行一个需要非常长的执行时间的操作.他点了执行了之后,浏览器就开始蛋疼地转.如果执行5分钟,你猜他会干啥,显然会觉得什么狗屎垃圾站,这么久都不响应,然后就给关了.当然这个 ...