zendframework form with captcha(Base on ZendFrameWork2.4)

1.首先扩展ZendCaptchaImage,重写一下图片生成过程:

<?php

namespace TestCaptche;

use ZendCaptchaExceptionNoFontProvidedException;
use ZendCaptchaImage;


/**
 * Class ImageCaptche
 *
 * @package TestCaptche
 * @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);
    }
  public function isValid($value,$context=null){
    $bool = parent::isValid
($value,$context);
    $this->setWord($this->generateWord());
    return $bool;
  }
}

2.创建登录表单LoginForm

<?php
namespace TestModel;

use ZendCaptchaAdapterInterface as CaptchaAdapter;
use ZendFormElement;
use ZendFormForm;

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'       => 'ZendFormElementCaptcha',
                'name'       => 'captcha',
                'options'    => array(
                    'label'   => '输入验证码',
                    'captcha' => $this->captcha,
                ),
                'attributes' =>
                    [
                        'class' => 'form-control',
                        'id'    => 'login-captcha'
                    ]
            )
        );
        $this->add(new ElementCsrf('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 ZendViewRendererPhpRenderer $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 endFormViewHelperCaptchaImage $helper */
            $helper = $this->plugin($captcha->getCaptcha()->getHelperName());

            $helper->setCaptchaPosition(endFormViewHelperCaptchaAbstractWord::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.效果图:

原文地址:https://www.cnblogs.com/flytome/p/4705478.html