zendframework form with captcha(Base on ZendFrameWork2.4)

1.首先扩展Zend\Captcha\Image,重写一下图片生成过程:

<?php

namespace Test\Captche;

use Zend\Captcha\Exception\NoFontProvidedException;
use Zend\Captcha\Image;

/**
 * Class ImageCaptche
 *
 * @package Test\Captche
 * @author  Xuman
 * @version $Id$
 */
class ImageCaptche extends Image
{
    protected $width = 130;
    protected $height = 40;
    protected $wordlen = 5;
    protected $code;
    protected $img;
    protected $fonts = array();
    //生成背景
    private function createBg()
    {
        $this->img = imagecreatetruecolor($this->width, $this->height);
        $color     = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
        imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $color);
    }
    public function getFont()
    {
        return $this->fonts[array_rand($this->fonts)];
    }
    //生成文字
    private function createFont($word)
    {
        $_x = $this->width / $this->wordlen;
        for ($i = 0; $i < $this->wordlen; $i++) {
            $fcolor = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
            imagettftext(
                $this->img, $this->fsize, mt_rand(-30, 30), $_x * $i + mt_rand(1, 5), $this->height / 1.4,
                $fcolor, $this->getFont(), $word[$i]
            );
        }
    }

    //生成线条、雪花
    private function createLine()
    {
        for ($i = 0; $i < 6; $i++) {
            $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
            imageline(
                $this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width),
                mt_rand(0, $this->height), $color
            );
        }
        for ($i = 0; $i < 100; $i++) {
            $color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
            imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), ‘*‘, $color);
        }
    }
    protected function generateImage($id, $word)
    {
        if (empty($this->fonts)) {
            throw new NoFontProvidedException(‘Image CAPTCHA requires font‘);
        }

        $imgFile = $this->getImgDir() . $id . $this->getSuffix();

        $this->createBg();
        $this->createLine();
        $this->createFont($word);

        imagepng($this->img, $imgFile);
        imagedestroy($this->img);
    }
} 

2.创建登录表单LoginForm

<?php
namespace Test\Model;

use Zend\Captcha\AdapterInterface as CaptchaAdapter;
use Zend\Form\Element;
use Zend\Form\Form;

class LoginForm extends Form
{
    protected $captcha;

    public function __construct(CaptchaAdapter $captcha)
    {

        parent::__construct();

        $this->captcha = $captcha;

// add() can take either an Element/Fieldset instance,
// or a specification, from which the appropriate object
// will be built.

        $this->add(
            array(
                ‘name‘       => ‘account‘,
                ‘options‘    => array(
                    ‘label‘ => ‘用户名‘,
                ),
                ‘type‘       => ‘Text‘,
                ‘attributes‘ =>
                    [
                        ‘class‘ => ‘form-control‘
                    ]
            )
        );
        $this->add(
            array(
                ‘name‘       => ‘password‘,
                ‘options‘    => array(
                    ‘label‘ => ‘密码‘,
                ),
                ‘type‘       => ‘Password‘,
                ‘attributes‘ =>
                    [
                        ‘class‘ => ‘form-control‘
                    ]
            )
        );
        $this->add(
            array(
                ‘type‘       => ‘Zend\Form\Element\Captcha‘,
                ‘name‘       => ‘captcha‘,
                ‘options‘    => array(
                    ‘label‘   => ‘输入验证码‘,
                    ‘captcha‘ => $this->captcha,
                ),
                ‘attributes‘ =>
                    [
                        ‘class‘ => ‘form-control‘,
                        ‘id‘    => ‘login-captcha‘
                    ]
            )
        );
        $this->add(new Element\Csrf(‘security‘));
        $this->add(
            array(
                ‘name‘       => ‘send‘,
                ‘type‘       => ‘Submit‘,
                ‘attributes‘ => array(
                    ‘value‘ => ‘登录‘,
                    ‘class‘ => ‘btn btn-success‘
                ),
            )
        );

// We could also define the input filter here, or
// lazy-create it in the getInputFilter() method.
    }
}

3.编写Action代码,testFormAction

public function testFormAction()
    {
        $captche = new ImageCaptche(
            [
                ‘name‘    => ‘test‘,
                ‘wordLen‘ => ‘4‘,
                ‘timeout‘ => 600,
                ‘height‘  => 36,
                ‘width‘   => 100,
                ‘fsize‘   => 18,
                ‘fonts‘   => array(‘data/font/CooperBlackStd.otf‘, ‘data/font/BOOKOSB.TTF‘, ‘data/font/BOOKOSI.TTF‘)
            ]
        );
        $this->layout(‘layout/layout‘);
        $form = new LoginForm($captche);
        if ($this->request->isPost()) {
            $form->setData($this->request->getPost());
            if ($form->isValid()) {
                return $this->redirect()->toRoute(‘test‘);
            }
        }
        return [‘form‘ => $form];
    }

4.编写test-form.phtml

<?php

$title = ‘Test Form‘;
/** @var Zend\View\Renderer\PhpRenderer $this */
$this->headTitle($title);
// within a view script
$form->prepare();

// Assuming the "contact/process" route exists...
$form->setAttribute(‘action‘, ‘‘);

// Set the method attribute for the form
$form->setAttribute(‘method‘, ‘post‘);

// Get the form label plugin
$formLabel = $this->plugin(‘formLabel‘);
?>
<div class="container">
    <div class="panel">

        <?php
        // Render the opening tag

        echo $this->form()->openTag($form);
        ?>
        <div class="form_element form-group">
            <?php
            $name = $form->get(‘account‘);
            //$name->setAttribute(‘class‘, ‘form-control‘);
            echo $formLabel->openTag() . $name->getOption(‘label‘);
            echo $this->formInput($name);
            echo $this->formElementErrors($name);
            echo $formLabel->closeTag();
            ?>
        </div>

        <div class="form_element form-group">
            <?php
            $subject = $form->get(‘password‘);
            echo $formLabel->openTag() . $subject->getOption(‘label‘);
            echo $this->formPassword($subject);
            echo $this->formElementErrors($subject);
            echo $formLabel->closeTag();
            ?>
        </div>

        <div class="form_element form-group">
            <?php
            $captcha = $form->get(‘captcha‘);
            echo $formLabel->openTag() . $captcha->getOption(‘label‘);
            echo $formLabel->closeTag();
            ?>
            <br>
            <?php
            /** @var \Zend\Form\View\Helper\Captcha\Image $helper */
            $helper = $this->plugin($captcha->getCaptcha()->getHelperName());

            $helper->setCaptchaPosition(\Zend\Form\View\Helper\Captcha\AbstractWord::CAPTCHA_PREPEND);
            //$helper->setSeparator(‘<span class="input-group-addon">‘);
            echo $helper($captcha);
            //echo $this->formCaptcha();
            ?>

            <?php
            echo $this->formElementErrors($captcha);

            ?>
        </div>

        <?php echo $this->formElement($form->get(‘security‘)) ?>
        <?php echo $this->formElement($form->get(‘send‘)) ?>

        <?php echo $this->form()->closeTag() ?>

    </div>
</div>
<style>
#login-captcha{
    display: inline;
    width: 100px;
}
</style>

5.css支持:bootstrap

6.效果图:

时间: 2024-10-23 20:43:48

zendframework form with captcha(Base on ZendFrameWork2.4)的相关文章

Codeforces 91C Ski Base 加边求欧拉回路数量

题目链接:点击打开链接 题意: 给出n个点m条无向边的图 开始图里没有边,每次加一条边,然后输出图里欧拉回路的条数. 思路: We will count the number of ski bases including the base consisted of empty subset of edges (before printing just subtract one). In the beginning the number of bases is equal to 1. If we

C#: 启动画面设计

Windows Form经常会在启动主界面的时候预先有启动画面,这也是因为用户体验的需要,用户知道已经启动application,而不是在load resource的时候等待.因此这里不能用单线程的思路,单单只是设计一个界面而已,而需要在splash画面的时候同时Load resource.那么这个技术有两个线程,一个是splash画面,二是load resource.搜了一些资料,下面进行一些总结: 1 using System; 2 using System.Collections.Gene

屏幕 Dynpro

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4292250.html 对话屏幕Dynpro(SE51). 11 屏幕元素... 11 屏幕属性... 11 PAI事件的触发.屏幕元素Function Code设置... 12 屏幕流逻辑Screen Flow Logic. 12 对话屏幕

GAS Syntax

GAS or?GNU as?syntax is a different form of syntax for assembly language files, known also as AT&T syntax after the original style. It is commonly used by other versions of GAS for other architectures (i.e. non-x86). This guide is not a complete refe

最近遇到的若干Web前端问题:disable和readonly,JqueryEasyUI,KindEditor

最近项目中用到了Jquery Easyui和KindEditor等框架组件,问题真不少啊~  一些看起来很简单理所当然的事情,竟然花费了不少时间,才解决好~  1.readonly和disable的区别  readonly:只读,不可编辑,提交表单时,值会提交到后端.  disable:禁止(包含了"只读"和"不可编辑"),提交表单时,值不会提交到后端.      如果需要提交到后端,在表单提交之前,手动把disable修改为false.    text叫只读,se

nginx静态分离后的一些小事故,给出处理方法

最近发现将nginx跟php放在同一台服务器上压力挺大的.于是就做了个动静分离,把nginx和php分别部署在两台服务器上. 好景不长,发现后台验证码,死活刷不出来,只有一个裂图. 想了想该不会是动静分离的原因吧.登上服务器一看,果然nginx服务器上并没有生成这个图片,图片都存在了php服务器上. 这样想着,有没有什么办法能直接获取到后端呢.想着用proxy_pass代理到后端看看 location ~* /media/captcha/([a-z]*)/(.*)$ {             

科技文献检索

The Fundamentals of Three-Phase Power Measurements Application Note Introduction Although single-phase electricity is used to supply common domestic and office electrical appliances, three-phase alternating current (a.c.) systems are almost universal

ASP.NET技巧:教你制做Web实时进度条

网上已经有很多Web进度条的例子,但是很多都是估算时间,不能正真反应任务的真实进度.我自己结合多线程和ShowModalDialog制做了 一个实时进度条,原理很简单:使用线程开始长时间的任务,定义一个Session,当任务进行到不同的阶段改变Session的值,线程开始的同时使用 ShowModalDialog打开一个进度条窗口,不断刷新这个窗口获取Session值,反应出实时的进度.下面就来看看具体的代码:(文章结尾处下 载源代码) 先新建一个Default.aspx页面,客户端代码: <b

程序单一实例实现 z

不少应用程序有单一实例的需求,也就是同时只能开启一个实例(一般也就是一个进程). 实现的方式可能有判断进程名字,使用特殊文件等等,但是最靠谱的方式还是使用系统提供的 Mutex 工具. Mutex是互斥体,命名的互斥体可以跨进程使用,所以可以用以实现程序单一实例这个需求.相关的例子网上应该不少,不过很多给出的例子中并没有注意到一些细节,这里就完整总结下. 命名Permalink Mutex 需要一个名字,这个名字需要唯一,一般的方式是使用一个固定的 GUID 作为名字. 对于 .NET 应用,可