给ThinkPHP5增长验证码功能

就在这几天,TP5进行的RC3的大规模更新,虽然咱们都狠狠地骂了一百遍,可是个人心里是无比的激动,TP终于走上了“上流社会”的模式:composer!
为何说composer是上流社会呢?由于 本身去 Bing 一下,为何不是百度呢?

废话很少说了,今天要为你们讲的是若是给TP5加上图片验证码。

首先我在GITHUB上面找了一个看似还能够的图片验证码 https://github.com/Gregwar/Captcha,而后咱们把她安装到咱们TP5框架中去php

  1. composer require gregwar/captcha

而后,我再 application\common\helper 下面建立了一个 VerifyHelper.php 咱们的验证码助手类(为何个人目录这么自由,由于我是主流,O(∩_∩)O~)

而后咱们根据这个图片验证码的说明为verifyHelper.php 填充了两个方法前端

  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  * User: 申法宽
  5.  * Date: 16/4/25
  6.  * Time: 13:19
  7.  * Email: sfk@live.cn
  8.  * File: VerifyHelper.php
  9.  */
  10. namespace app\common\helper;
  11. use Gregwar\Captcha\CaptchaBuilder;
  12. class VerifyHelper
  13. {
  14.     /**
  15.      * 生成验证码
  16.      */
  17.     public static function verify()
  18.     {
  19.         $builder = new CaptchaBuilder();
  20.         $builder->build()->output();
  21.         session('verify_code', $builder->getPhrase());
  22.     }
  23.     /**
  24.      * 检测验证码是否正确
  25.      * @param $code
  26.      * @return bool
  27.      */
  28.     public static function check($code)
  29.     {
  30.         return ($code == session('verify_code') && $code != '') ? true : false;
  31.     }
  32. }

 

好了,你们须要的验证码类已经搞定了!额~~~ 抱歉,没有给你们演示前端效果呢

--------------------------------------------------------------------------------------------------------------
接下来咱们在控制器中重建一个verify的方法( 注意,这里VerifyHelper的命名空间PHPstorm在上面已经给我use 过了,若是你要纯手工的去敲代码,那么你可不要弄错哦 )git

  1.     /**
  2.      * 显示验证码图片
  3.      */
  4.     public function verify()
  5.     {
  6.         VerifyHelper::verify();
  7.     }

咱们在页面中添加以下代码(注意,个人src是通过路由的,你须要本身对应到刚刚verify方法的控制器,或者本身写路由吧)github

  1. {extend name="base" /}
  2. {block name="title"}图片验证码{/block}
  3. {block name="main"}
  4. <div class="row">
  5.     <div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 center-block">
  6.         <form class="form-horizontal" id="tg-register-form" data-toggle="validator" action="{:url('/do_register')}"
  7.               method="post">
  8.             <div class="form-group">
  9.                 <label for="inputVerify" class="col-xs-2 control-label">验证码</label>
  10.                 <div class="col-xs-10">
  11.                     <input class="form-control" id="inputVerify" name="verify" placeholder="验证码" type="text"
  12.                            data-error="验证码错误" required>
  13.                     <img class="verifyimg reloadverify" src="{:url('/verify')}" alt="">
  14.                 </div>
  15.                 <div class="col-xs-offset-2 col-xs-10 help-block with-errors"></div>
  16.             </div>
  17.         </form>
  18.     </div>
  19. </div>
  20. {/block}

 

好啦,前端工做作完,那么如今展现效果的时候到了





怎么样,还不错吧,你想点击图片就更换验证码?好的下面贴出代码来thinkphp

  1. <script>
  2.     $(function(){
  3.         // 刷新验证码
  4.         var verifyimg = $(".verifyimg").attr("src");
  5.         $(".reloadverify").click(function(){
  6.             if( verifyimg.indexOf('?')>0){
  7.                 $(".verifyimg").attr("src", verifyimg+'&random='+Math.random());
  8.             }else{
  9.                 $(".verifyimg").attr("src", verifyimg.replace(/\?.*$/,'')+'?'+Math.random());
  10.             }
  11.         });
  12.     })
  13. </script>

 

额,貌似又忘了,那么我怎么去验证用户输入的验证码是否正确呢?还记得咱们在填充VerifyHelper.php类的时候有一个check 方法吗?没错,就是这个方法用来检测用户输入的验证码和session中存在的验证码是否一致了!

好,如今咱们就说说这个验证,咱们在使用TP5的时候,会发现手册中有一个验证,没错这个东西在3.2时候咱们仍是纯纯的在model验证(我没说错吧?其实那时候我几乎不写验证的,呵呵是否是很不负责呢),那么如今我就教你们写一个验证器

假设咱们刚刚在写验证码的时候的场景是用户注册,咱们如今就写一个用户注册的验证器(ps:若是你看不懂我写的什么,那么就去看看手册吧)!session

  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  * User: 申法宽
  5.  * Date: 16/4/21
  6.  * Time: 16:26
  7.  * Email: sfk@live.cn
  8.  * File: UserValidate.php
  9.  */
  10. namespace app\common\validate;
  11. use app\common\helper\VerifyHelper;
  12. class UserValidate extends BaseValidate
  13. {
  14.     // 验证规则
  15.     protected $rule = [
  16.         ['email', 'require|email', '邮箱必须|邮箱格式不正确'],
  17.         ['password', 'require|min:6', '密码必须|密码长度至少6位'],
  18.         ['verify', 'check_verify:thinkphp', '验证码错误']
  19.     ];
  20.     protected $scene = [
  21.         'register' => ['email', 'password','verify'],
  22.         'login' => ['email', 'password'],
  23.     ];
  24.     // 自定义规则
  25.     public function check_verify($value)
  26.     {
  27.         return VerifyHelper::check($value) ? true : false;
  28.     }
  29. }

 

上面代码中的check_verify就是咱们要作的自定义验证:验证码验证(仍是那就话,我这里phpstorm已经给我写好了命名空间了)


咱们上面说了,咱们假设的是用户注册场景,咱们须要一个用户注册的方法(下面代码中succ 和 err 就是一个返回js的方法,你可不要说个人代码你不能用,就开始咒我啊)app

  1. public function register()
  2.     {
  3.         if(IS_POST) {
  4.             $data = input('post.');
  5.             $result = $this->validate($data, 'UserValidate.register');
  6.             if(is_array($result)) {
  7.                 return $this->err('注册失败', ['valid' => $result]);
  8.             }
  9.             // 判断验证码
  10.             $user_model = new UserModel();
  11.             if($user_model->register($data)){
  12.                 return $this->succ('注册成功', ['url' => url('/login')]);
  13.             } else {
  14.                 return $this->err('注册失败, 邮箱已注册', ['valid' => ['email' => '该邮箱已经注册,请更换或登陆']]);
  15.             }
  16.         }
  17.     }

这里我就简单说一下吧, $this->validate($data, 'UserValidate.register'); 意思是告诉咱们 加载了 UserValidate的注册场景!

其实到这里,咱们的工做已经写完了


流程:
用户打开注册页面
显示页面的验证码

用户点击提交

提交到咱们 注册方法

注册方法加载用户验证器

验证器验证 email password 和 verify 是否符合要求

而后进行数据的写入

Done !



是否是很懵,从 TP5开始 咱们就要开始 本身组装咱们的框架了,无论你须要什么,去 GITHUB上面找,composer 安装,而后开始肆意的放纵吧!




对了 这里有一个问题,在我写这篇分享的时候,Model.php 的 save 方法有一个bug,在上面 注册方法中咱们能够看到,我在UserModel中又写了一个注册方法到model中composer

  1.     /**
  2.      * 注册
  3.      * @param $data
  4.      * @return int|string
  5.      */
  6.     public function register($data)
  7.     {
  8.         $user = self::db()->getByEmail($data['email']);
  9.         if ($user) return false; //用户已经存在
  10.         if ($this->allowField(['email', 'password'])->save($data)) {
  11.             return $this->id;
  12.         }
  13.     }

代码中使用了 allowField方法过滤了 verify 字段,否则在咱们save的时候tp就要去判断verify字段不存在报错了

那么 这个bug 在哪呢?(Model.php 约 223行)框架

  1.         // 检测字段
  2.         if (!empty($this->field)) {
  3.             foreach ($data as $key => $val) {
  4.                 if (!in_array($key, $this->field)) {
  5.                     unset($data[$key]);
  6.                 }
  7.             }
  8.         }

咱们须要改成$this->data,为何?仔细研究一下save方法你就知道啦!dom

  1.         // 检测字段
  2.         if (!empty($this->field)) {
  3.             foreach ($this->data as $key => $val) {
  4.                 if (!in_array($key, $this->field)) {
  5.                     unset($this->data[$key]);
  6.                 }
  7.             }
  8.         }
相关文章
相关标签/搜索