给ThinkPHP5增加验证码功能

浏览:30640 发布日期:2016/04/25 分类:ThinkPHP5专区 关键字: tp5 thinkphp5 验证码 verify
就在这几天,TP5进行的RC3的大规模更新,虽然我们都狠狠地骂了一百遍,但是我的内心是无比的激动,TP终于走上了“上流社会”的模式:composer!
为什么说composer是上流社会呢?因为 自己去 Bing 一下,为什么不是百度呢?

废话不多说了,今天要为大家讲的是如果给TP5加上图片验证码。

首先我在GITHUB上面找了一个看似还可以的图片验证码 https://github.com/Gregwar/Captcha,然后我们把她安装到我们TP5框架中去composer require gregwar/captcha然后,我再 application\common\helper 下面创建了一个 VerifyHelper.php 我们的验证码助手类(为什么我的目录这么自由,因为我是主流,O(∩_∩)O~)

然后我们根据这个图片验证码的说明为verifyHelper.php 填充了两个方法<?php
/**
 * Created by PhpStorm.
 * User: 申法宽
 * Date: 16/4/25
 * Time: 13:19
 * Email: sfk@live.cn
 * File: VerifyHelper.php
 */

namespace app\common\helper;

use Gregwar\Captcha\CaptchaBuilder;

class VerifyHelper
{
    /**
     * 生成验证码
     */
    public static function verify()
    {
        $builder = new CaptchaBuilder();
        $builder->build()->output();
        session('verify_code', $builder->getPhrase());
    }

    /**
     * 检测验证码是否正确
     * @param $code
     * @return bool
     */
    public static function check($code)
    {
        return ($code == session('verify_code') && $code != '') ? true : false;
    }
}
好了,大家需要的验证码类已经搞定了!额~~~ 抱歉,没有给大家演示前端效果呢

--------------------------------------------------------------------------------------------------------------
接下来我们在控制器中重建一个verify的方法( 注意,这里VerifyHelper的命名空间PHPstorm在上面已经给我use 过了,如果你要纯手工的去敲代码,那么你可不要弄错哦 )    /**
     * 显示验证码图片
     */
    public function verify()
    {
        VerifyHelper::verify();
    }
我们在页面中添加如下代码(注意,我的src是经过路由的,你需要自己对应到刚刚verify方法的控制器,或者自己写路由吧){extend name="base" /}
{block name="title"}图片验证码{/block}
{block name="main"}

<div class="row">
    <div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 center-block">
        <form class="form-horizontal" id="tg-register-form" data-toggle="validator" action="{:url('/do_register')}"
              method="post">
            <div class="form-group">
                <label for="inputVerify" class="col-xs-2 control-label">验证码</label>
                <div class="col-xs-10">
                    <input class="form-control" id="inputVerify" name="verify" placeholder="验证码" type="text"
                           data-error="验证码错误" required>
                    <img class="verifyimg reloadverify" src="{:url('/verify')}" alt="">
                </div>
                <div class="col-xs-offset-2 col-xs-10 help-block with-errors"></div>
            </div>
        </form>
    </div>
</div>
{/block}
好啦,前端工作做完,那么现在展示效果的时候到了





怎么样,还不错吧,你想点击图片就更换验证码?好的下面贴出代码来<script>
    $(function(){
        // 刷新验证码
        var verifyimg = $(".verifyimg").attr("src");
        $(".reloadverify").click(function(){
            if( verifyimg.indexOf('?')>0){
                $(".verifyimg").attr("src", verifyimg+'&random='+Math.random());
            }else{
                $(".verifyimg").attr("src", verifyimg.replace(/\?.*$/,'')+'?'+Math.random());
            }
        });
    })
</script>
额,貌似又忘了,那么我怎么去验证用户输入的验证码是否正确呢?还记得我们在填充VerifyHelper.php类的时候有一个check 方法吗?没错,就是这个方法用来检测用户输入的验证码和session中存在的验证码是否一致了!

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

假设我们刚刚在写验证码的时候的场景是用户注册,我们现在就写一个用户注册的验证器(ps:如果你看不懂我写的什么,那么就去看看手册吧)!<?php
/**
 * Created by PhpStorm.
 * User: 申法宽
 * Date: 16/4/21
 * Time: 16:26
 * Email: sfk@live.cn
 * File: UserValidate.php
 */

namespace app\common\validate;

use app\common\helper\VerifyHelper;

class UserValidate extends BaseValidate
{

    // 验证规则
    protected $rule = [
        ['email', 'require|email', '邮箱必须|邮箱格式不正确'],
        ['password', 'require|min:6', '密码必须|密码长度至少6位'],
        ['verify', 'check_verify:thinkphp', '验证码错误']
    ];
    protected $scene = [
        'register' => ['email', 'password','verify'],
        'login' => ['email', 'password'],
    ];

    // 自定义规则
    public function check_verify($value)
    {
        return VerifyHelper::check($value) ? true : false;
    }
}
上面代码中的check_verify就是我们要做的自定义验证:验证码验证(还是那就话,我这里phpstorm已经给我写好了命名空间了)


我们上面说了,我们假设的是用户注册场景,我们需要一个用户注册的方法(下面代码中succ 和 err 就是一个返回js的方法,你可不要说我的代码你不能用,就开始咒我啊)public function register()
    {
        if(IS_POST) {
            $data = input('post.');

            $result = $this->validate($data, 'UserValidate.register');

            if(is_array($result)) {
                return $this->err('注册失败', ['valid' => $result]);
            }
            // 判断验证码

            $user_model = new UserModel();

            if($user_model->register($data)){
                return $this->succ('注册成功', ['url' => url('/login')]);
            } else {
                return $this->err('注册失败, 邮箱已注册', ['valid' => ['email' => '该邮箱已经注册,请更换或登录']]);
            }
        }
    }
这里我就简单说一下吧, $this->validate($data, 'UserValidate.register'); 意思是告诉我们 加载了 UserValidate的注册场景!

其实到这里,我们的工作已经写完了


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

用户点击提交

提交到我们 注册方法

注册方法加载用户验证器

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

然后进行数据的写入

Done !



是不是很懵,从 TP5开始 我们就要开始 自己组装我们的框架了,不管你需要什么,去 GITHUB上面找,composer 安装,然后开始肆意的放纵吧!




对了 这里有一个问题,在我写这篇分享的时候,Model.php 的 save 方法有一个bug,在上面 注册方法中我们可以看到,我在UserModel中又写了一个注册方法到model中    /**
     * 注册
     * @param $data
     * @return int|string
     */
    public function register($data)
    {
        $user = self::db()->getByEmail($data['email']);
        if ($user) return false; //用户已经存在

        if ($this->allowField(['email', 'password'])->save($data)) {
            return $this->id;
        }
    }
代码中使用了 allowField方法过滤了 verify 字段,不然在我们save的时候tp就要去判断verify字段不存在报错了

那么 这个bug 在哪呢?(Model.php 约 223行)        // 检测字段
        if (!empty($this->field)) {
            foreach ($data as $key => $val) {
                if (!in_array($key, $this->field)) {
                    unset($data[$key]);
                }
            }
        }
我们需要改为$this->data,为什么?仔细研究一下save方法你就知道啦!        // 检测字段
        if (!empty($this->field)) {
            foreach ($this->data as $key => $val) {
                if (!in_array($key, $this->field)) {
                    unset($this->data[$key]);
                }
            }
        }
好啦,到这里分享已经写完了,说的还挺多的,谢谢观看!

最佳答案
评论( 相关
后面还有条评论,点击查看>>