給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.         }
相關文章
相關標籤/搜索