ZendFramework2学习笔记 验证码

zf2提供了图片验证码Zend\Captcha\Image和符号字符验证码Zend\Captcha\Figlet,图片验证码是网站应用中见得比较多的一种验证码,本文以图片验证码为例。

如果用session来临时保存生成的验证码,就需要先配置session。

session的参数配置:

// /config/autoload/local.php

return array(
    'session' => array(
        'config' => array(
            'class' => 'Zend\Session\Config\SessionConfig',
            'options' => array(
                'name' => 'zf2ttttt',
            ),
        ),
        'storage' => 'Zend\Session\Storage\SessionArrayStorage',
        'validators' => array(
            'Zend\Session\Validator\RemoteAddr',
            'Zend\Session\Validator\HttpUserAgent',
        ),
    ),
);

Application启动后调用session_start:

// /module/Application/Module.php

namespace Application;

use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;

use Zend\Session\SessionManager;
use Zend\Session\Container;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);

	//为表单验证对象设置默认的语言翻译器,以便验证码验证不通过时用默认语言提示用户
       \Zend\Validator\AbstractValidator::setDefaultTranslator($e->getApplication()->getServiceManager()->get('translator'));
       //启动session
       $this->bootstrapSession($e);
    }

    public function bootstrapSession($e){
        $session = $e->getApplication()->getServiceManager()->get('Zend\Session\SessionManager');
        $session->start();
    }

    //SessionManager工厂
    public function getServiceConfig() {
        return array(
            'factories' => array(
                'Zend\Session\SessionManager' => function ($sm) {
                    $config = $sm->get('config');
                    if (isset($config['session'])){
                        $session = $config['session'];

                        $sessionConfig = null;
                        if (isset($session['config'])){
                            $class = isset($session['config']['class']) ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
                            $options = isset($session['config']['options']) ? $session['config']['options'] : array();
                            $sessionConfig = new $class;
                            $sessionConfig->setOptions($options);
                        }

                        $sessionStorage = null;
                        if (isset($session['storage'])){
                            $class = $session['storage'];
                            $sessionStorage = new $class;
                        }

                        $sessionSaveHandler = null;
                        if (isset($session['save_handler'])){
                            $sessionSaveHandler = $sm->get($session['save_handler']);
                        }

                        $sessionManager = new SessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);
                    } else {
                        $sessionManager = new SessionManager();
                    }
                    Container::setDefaultManager($sessionManager);
                    return $sessionManager;
                },
            ),
        );
    }
}

表单Form中添加验证码输入:验证码就是一张图片,可以在表单中用一个text让用户输入验证码,text旁显示验证码图片:

// /module/Test/src/Test/Form/TestForm.php

namespace Test\Form;

......

use Test\Form\MyImgCaptchaValidator;//自定义的验证码检验类

class TestForm extends Form  implements InputFilterProviderInterface{

    ......

    public function __construct($name = null) {

        ......

        //添加验证码输入框
        $this->add(array(
            'name' => 'cv',
            'type' => 'Text',
            'options' => array(
                'label' => '请输入检验码:',
            ),
            'attributes' => array(
                'size' => 20,
                'maxlength' => 4,
            ),
        ));

        ......
    }

    public function getInputFilterSpecification() {

        ......

        //自定义的验证码检验对象
        $captchaValidator = new MyImgCaptchaValidator();

        ......

        return array(
            ......

            'cv' => array(
                'required' => true,
                'filters'  => array(
                    array('name' => 'StringTrim'),
                    array('name' => 'StringToLower'),
                ),
                'validators' => array(
                    array('name' => 'NotEmpty'),
                    array(
                        'name'    => 'StringLength',//本例将验证码长度限制为4字符
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 4,
                            'max'      => 4,
                        ),
                    ),
                $captchaValidator,
                ),
            ),
        );
    }
}

自定义的验证码验证类:

// /module/Test/src/Test/Form/MyImgCaptchaValidator.php

namespace Test\Form;

use Zend\Validator\AbstractValidator;
use Zend\Session\Storage\SessionArrayStorage;

class MyImgCaptchaValidator extends AbstractValidator {

    const DIFFERENT = 'different';
    protected $messageTemplates = array(
        self::DIFFERENT => "Capthca inputted is different !",//此处为字符串的key,如果语言文件配置了该字符串,并且为validator设置了默认的tranlaotr,validator基类会自动翻译该字符串
    );

    public function isValid($value) {

        $this->setValue($value);

        $isValid = true;

        $sessionKey_Capthca = 'sesscaptcha';
        $sessionStorage = new SessionArrayStorage();
        $captchaWord = $sessionStorage->offsetGet($sessionKey_Capthca);//获取session临时保存的验证码
        $wd = $captchaWord;
        if ($wd != $value){//比较输入的验证码和生成的验证码
            $this->error(self::DIFFERENT);//输入不正确,则设置错误消息
            $isValid = false;
        }
        return $isValid;
    }

}

在视图中输出验证码输入框和验证码图片:

// /module/Test/src/view/test/test/testform.phtml

echo '<div>';

$captcha = $this->tform->get('cv');//获取验证码输入框表单元素

echo $formLabel->openTag().$captcha->getOption('label');

echo $this->formInput($captcha);//显示验证码输入框

echo '<img src="'.$imgSrc.'"></div>';//显示验证码图片,$imgSrc为控制器传过来

echo $this->formElementErrors($captcha);//显示错误消息

echo $formLabel->closeTag();

echo '</div>';

控制器代码:

// /module/Test/src/Test/Controller/TestController.php

namespace Test\Controller;

use Zend\Captcha\Image;
use Zend\Session\Storage\SessionArrayStorage;

class TestController extends AbstractActionController {

    public function testformAction() {
        ......
        if ($this->getRequest()->isPost()){//用户提交了表单,处理表单数据
            $postData = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );

            $form->setData($postData);
            if ($form->isValid()) {//表单检验成功
                .....
            }
            ......
        }

	//session
        $sessionStorage = new SessionArrayStorage();

        //创建验证码
        $sessionKey_Capthca = 'sesscaptcha';
        $icv = new \Zend\Captcha\Image();//zf2只支持生成*.png格式图片
        $icv->setFont('public/fonts/arial.ttf');//指定字体文件,可以从windows系统文件夹"WINDOWS\Fonts"下拷贝一个“arial.ttf”文件到/public/fonts目录下
        $icv->setFontSize(14);
        $icv->setHeight(30);
        $icv->setWidth(80);
        $icv->setDotNoiseLevel(20);//添加像素点的干扰,默认值100
        $icv->setLineNoiseLevel(2);//添加像素线的干扰,默认值5
        $icv->setImgDir('public/captcha/'); //特别需要注意的是,imgDir和imgUrl这2个参数,如果设置不当,很容易出现无法创建图片文件或者无法显示图片文件的问题。
                                                    //下面对这2个参数的设置和默认值做了以下整理:
                                                    //imgDir:默认值是public/images/captcha。
                                                    //imgUrl:默认值是/images/capthca。
                                                    //可见,默认值是按照网站把/public设置为web根目录来定的。
                                                    //setImgDir:如果是以根目录符"/"开头,则认为是绝对路径,例如,setImgDir('/public/captcha/');则图片保存路径为/public/capthca/asdfas.png;
                                                    //           如果不是以根目录符"/"开头,则以网站根目录为根,设置的值为网站根目录下的子目录,例如,setImgDir('public/captcha/');则图片保存路径为WebRoot/public/capthca/asdfas.png(WebRoot为网站web根目录);
                                                    //setImgUrl:如果是以根目录符"/"开头,则以网站根目录为根,例如,setImgUrl('/public/captcha/');则图片URL为http://xxxx/public/capthca/asdfas.png;
                                                    //           如果不是以根目录符"/"开头,则以当前route为为根,例如,假设当前表单URL为http://x/test/testform,那么调用setImgUrl('public/captcha/');则图片URL为http://x/test/public/capthca/asdfas.png;
                                                    //综上所述,正确的设置这2个参数的方法是,setImgDir的参数“不要”以“/”开头,setImgUrl的参数“要”以“/”开头。
        $icv->setImgUrl('/public/captcha/');
        $icv->setWordlen(4);//设置字符个数,默认是8个字符
        //创建新的验证码的值
        $icv->generate();
        //验证码图片的URL
        $imgSrc = $icv->getImgUrl().'/'.$icv->getId().$icv->getSuffix();
        //验证码的字符串
        $captchaWord = $icv->getWord();

        //验证码保存到session
        $sessionStorage->offsetSet($sessionKey_Capthca, $captchaWord);   

        return array(
            'tform'     => $form,
            'imgSrc' => $imgSrc,//将验证码图片的url传给视图
        );
    }

}

另外,由于自定义验证码验证类使用了一个字符串"Capthca inputted is different !",因此,需要在语言文件中配置一下该字符串的中文信息。

添加语言文件配置:

// /module/Test/config/module.config.php

return array(

    ......

     'translator' => array(
        'translation_files' => array(
            array(
                'type'     => 'phparray',
                'filename'  => __DIR__ . '/../language/my_zh_CN.php',//自己创建的语言文件my_zh_CN.php,保存在/module/Test/language/目录下
            ),
        ),
    ),

    ......

);

在语言文件中添加字符串:

// /module/Test/language/my_zh_CN.php

return array(
    "Capthca inputted is different !" => "验证码输入不正确!"
);

有时候,验证码不看不清楚的时候,可能需要点击刷新。要实现点击刷新的功能,可以对以上代码做一些如下修改。

控制器中生成验证码的部分剪切出来放在一个函数中:

// /module/Test/src/Test/Controller/TestController.php

class TestController extends AbstractActionController {

    public function createCaptcha(){
         //创建验证码
        $sessionKey_Capthca = 'sesscaptcha';
        $icv = new \Zend\Captcha\Image();//zf2只支持生成*.png格式图片
        $icv->setFont('public/fonts/arial.ttf');//指定字体文件,可以从windows系统文件夹"WINDOWS\Fonts"下拷贝一个“arial.ttf”文件到/public/fonts目录下
        $icv->setFontSize(14);
        $icv->setHeight(30);
        $icv->setWidth(80);
        $icv->setDotNoiseLevel(20);//添加像素点的干扰,默认值100
        $icv->setLineNoiseLevel(2);//添加像素线的干扰,默认值5
        $icv->setImgDir('public/captcha/'); //特别需要注意的是,imgDir和imgUrl这2个参数,如果设置不当,很容易出现无法创建图片文件或者无法显示图片文件的问题。
                                                    //下面对这2个参数的设置和默认值做了以下整理:
                                                    //imgDir:默认值是public/images/captcha。
                                                    //imgUrl:默认值是/images/capthca。
                                                    //可见,默认值是按照网站把/public设置为web根目录来定的。
                                                    //setImgDir:如果是以根目录符"/"开头,则认为是绝对路径,例如,setImgDir('/public/captcha/');则图片保存路径为/public/capthca/asdfas.png;
                                                    //           如果不是以根目录符"/"开头,则以网站根目录为根,设置的值为网站根目录下的子目录,例如,setImgDir('public/captcha/');则图片保存路径为WebRoot/public/capthca/asdfas.png(WebRoot为网站web根目录);
                                                    //setImgUrl:如果是以根目录符"/"开头,则以网站根目录为根,例如,setImgUrl('/public/captcha/');则图片URL为http://xxxx/public/capthca/asdfas.png;
                                                    //           如果不是以根目录符"/"开头,则以当前route为为根,例如,假设当前表单URL为http://x/test/testform,那么调用setImgUrl('public/captcha/');则图片URL为http://x/test/public/capthca/asdfas.png;
                                                    //综上所述,正确的设置这2个参数的方法是,setImgDir的参数“不要”以“/”开头,setImgUrl的参数“要”以“/”开头。
        $icv->setImgUrl('/public/captcha/');
        $icv->setWordlen(4);//设置字符个数,默认是8个字符
        //创建新的验证码的值
        $icv->generate();
        //验证码图片的URL
        $imgSrc = $icv->getImgUrl().'/'.$icv->getId().$icv->getSuffix();
        //验证码的字符串
        $captchaWord = $icv->getWord();

        $sessionStorage = new SessionArrayStorage();
        //验证码保存到session
        $sessionStorage->offsetSet($sessionKey_Capthca, $captchaWord);   

        return $imgSrc;
     }
}

创建一个刷新验证码图片的控制器Action:

// /module/Test/src/Test/Controller/TestController.php

class TestController extends AbstractActionController {

     public function refreshcaptchaAction() {
         $imgSrc = $this->createCaptcha();
         return new JsonModel(array(
             'imgSrc' => $imgSrc
         ));
     }
}

视图中添加刷新验证码按钮:

// /module/Test/view/test/test/testform.phtml

echo '<div>';
$captcha = $this->tform->get('cv');
echo $formLabel->openTag().$captcha->getOption('label');
echo $this->formInput($captcha);
echo '<img id=imgcaptcha src="'.$imgSrc.'"></div>';
echo $this->formElementErrors($captcha);
echo $formLabel->closeTag();

echo '<input type="button" value="刷新" onclick="javascript:refreshCaptcha();"/>';

echo '</div>';

添加刷新验证码图片的客户端脚本:

// /module/Test/view/test/test/testform.phtml

<script>

function refreshCaptcha(){
    var ul = '/test/refreshcaptcha';
    //alert(ul);

    $.ajax({
        type : "GET",
        url : ul,
        dataType : "json",
        success : function(data, textStatus) {
            		$("#imgcaptcha").attr("src",data.imgSrc);
                    },
        error : function(r, t, r){

                    }
    });
}

</script>
时间: 2024-10-11 07:36:46

ZendFramework2学习笔记 验证码的相关文章

php学习笔记--验证码

php学习笔记--验证码 php培训教程中生成验证码的示例代码: <?php session_start();//生成验证码图片 Header("Content-type:image/PNG"); $im = imagecreate(44, 18); // 画一张指定宽高的图片 $back = imagecolorallocate($im, 245, 245, 245); // 定义背景颜色 imagefill($im, 0, 0, $back); //把背景颜色填充到刚刚画出来

ZendFramework2学习笔记 表单过滤、表单验证

ZF2有很多内建的Filter和Validator组件,可以方便地对表单数据进行处理. Filter的作用是过滤表单数据,例如,去除一些空格,替换一些敏感词等. Validator的作用是检验表单数据是否合规,如果不合规,则提供不合规原因的文本消息. 假设有这样一个Form: 表单数据存储到数据库之前的要求是: 用户名:过滤左右空格,字符都转换为小写,只能是由数字和字母字符组成,长度限制,数据库必须不存在该用户名. 密码:密码1和密码2必须相同,长度限制. 邮箱:必须符合密码格式,加密存储,长度

ZendFramework2学习笔记 json和ajax

要实现zf2的控制器输出json数据,主要要解决2个问题,第一个就是修改header头的Content-type部分为  'Content-Type: application/json',第二个就是输出json数据. 修改header头,可以手动修改也可以自动修改. 自动修改的方式是,使用zf2的JsonRenderer,或者json的view helper: 1)使用JsonRenderer的方法:zf2默认使用PhpRender,因此需要在项目启动的时候,修改renderer.在启动模块

ZendFramework2学习笔记 文件上传、文件上传进度

修改php.ini以适应文件的要求: //php.ini file_uploads = On post_max_size = 600M upload_max_filesize = 600M session.upload_progress.enabled = On session.upload_progress.freq = "1%" session.upload_progress.min_freq = "1" 以上我们限制了文件大小限制在不超过600MB. 关于文件

ZendFramework2学习笔记 发送email

ZF2中发送email有2种方式,一是通过系统的邮件程序发送email,二是通过smtp协议使用远程的smtp服务器发送email. 相关的类有: use Zend\Mail\Message;//email消息类 use Zend\Mail\Transport\Sendmail;//通过系统邮件程序的发送类 use Zend\Mail\Transport\Smtp;//通过smtp协议使用远程smtp服务器的发送类 use Zend\Mail\Transport\SmtpOptions;//设置

ZendFramework2学习笔记 国际化、多语言

ZF2的网站语言配置项是module.config.hp中的"translator"项: <span style="font-size:18px;"> 'translator' => array( 'locale' => 'zh_CN',//中文简体是zf_CN,英文是en_US 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir'

学习笔记:利用GDI+生成简单的验证码图片

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 学习笔记:利用GDI+生成简单的验证码图片 1 /// <summary> 2 /// 单击图片时切换图片 3 /// </summary> 4 /// <param name="sender">&

MVC学习笔记索引帖

[MVC学习笔记]1.项目结构搭建及单个类在各个层次中的实现 [MVC学习笔记]2.使用T4模板生成其他类的具体实现 [MVC学习笔记]3.使用Spring.Net应用IOC(依赖倒置) [MVC学习笔记]4.使用Log4Net来进行错误日志的记录 [MVC学习笔记]5.使用Controller来代替Filter完成登录验证(Session校验) [MVC学习笔记]6. 使用Memcache+Cookie解决分布式系统共享登录状态 [MVC学习笔记]7.使用极验验证来制作更高逼格的验证码

ID卡学习笔记

前言: 我也来篇关于当时学习ID卡的笔记.前段时间小区装门禁.一个钮扣型的ID卡就要30块.非常黑心.因为其ID卡的成本也就是1块钱以下.因此我也加入到这方面的研究.用来模拟ID卡的T5557卡成本2块钱左右.可反复写.文章想到什么就写什么.大牛可以忽视. 两天前入手了一套ID读卡器.不知型号.没有参数.没有出厂.就一小光盘.里面是CP210x驱动与读写软件. CP210x驱动可以把USB模拟成COM串口.以下是我的设备图: 虽然提供了win7驱动.但软件不能在win7下运行.所以只能在vbox