星期三, 11月 17, 2010

Zend Captcha

  1. ASCII captcha (最簡單的用法)
    ex.

    $captcha = new Zend_Form_Element_Captcha( 'captcha', array(
      'label' => 'Please enter the 5 letters displayed below:',
      'name' => 'captcha', //回傳post欄位的名稱
      'required' => true,
      'captcha' => array('captcha' => 'Figlet', 'wordLen' => 5, 'timeout' => 300)
    ));
    echo captcha;

    判斷是否正確
    $captcha = $request->getPost('captcha');
    $captchaId = $captcha['id'];
    // And here's the user submitted word...
    $captchaInput = $captcha['input'];
    // We are accessing the session with the corresponding namespace
    // Try overwriting this, hah!
    $captchaSession = new Zend_Session_Namespace('Zend_Form_Captcha_'.$captchaId);
    // To access what's inside the session, we need the Iterator
    // So we get one...
    $captchaIterator = $captchaSession->getIterator();
    // And here's the correct word which is on the image...

    $captchaWord = $captchaIterator['word'] ;
    // Now just compare them...
    if ($captchaInput == $captchaWord)
    echo "valid";
    else
    echo "invalid";


  2. 圖文表示
    ex.

    注意事項
    • 要給ttf字型檔
    $this->view->captcha = new Zend_Form_Element_Captcha(
      'captcha', // This is the name of the input field
      array('label' => 'Write the chars to the field',
       'captcha' => array( // Here comes the magic...
       // First the type...
       'captcha' => 'Image',
       // Length of the word...
       'wordLen' => 4,
       // Captcha timeout, 5 mins
       'timeout' => 300,
       // What font to use...
       'font' => 'captcha/arial.ttf',
       // Where to put the image
       'imgDir' => 'captcha/tmp/',
       //<img src="?" > 的位置
       'imgUrl' => 'http://' . $this->_request->getHttpHost() . $this->_request->getBaseUrl() . '/captcha/tmp/'
       )
      )
    );
  3. 自定背景
    ex.

    注意事項
    由於預設會將底色用白,所以直接改圖沒用
    到/library/Zend/Captcha/Image.php改程式碼
    p.s. 因為機車johnny又在唸不喜歡彎彎的字及干擾的點及線,因此順便把扭曲的程式碼拿掉了

    不要點及線只要在建構子下...
    $captcha = new Zend_Form_Element_Captcha(
    'captcha', // This is the name of the input field
    array(
    ...
    'lineNoiseLevel' => 0,
    'dotNoiseLevel' => 0,
    ...
    )
    )
    );


    如果不要扭曲的字型,那就把_generateImage方法的內容改成以下程式碼
    protected function _generateImage($id, $word)
    {
      if (!extension_loaded("gd")) {
       require_once 'Zend/Captcha/Exception.php';
       throw new Zend_Captcha_Exception("Image CAPTCHA requires GD extension");
      }

      if (!function_exists("imagepng")) {
       require_once 'Zend/Captcha/Exception.php';
       throw new Zend_Captcha_Exception("Image CAPTCHA requires PNG support");
      }

      if (!function_exists("imageftbbox")) {
       require_once 'Zend/Captcha/Exception.php';
       throw new Zend_Captcha_Exception("Image CAPTCHA requires FT fonts support");
      }

      $font = $this->getFont();

      if (empty($font)) {
       require_once 'Zend/Captcha/Exception.php';
       throw new Zend_Captcha_Exception("Image CAPTCHA requires font");
      }

      $w = $this->getWidth();
      $h = $this->getHeight();
      $fsize = $this->getFontSize();

      $img_file = $this->getImgDir() . $id . $this->getSuffix();
      if(empty($this->_startImage)) {
       $img = imagecreatetruecolor($w, $h);
      } else {
       $img = imagecreatefrompng($this->_startImage);
       if(!$img) {
        require_once 'Zend/Captcha/Exception.php';
        throw new Zend_Captcha_Exception("Can not load start image");
       }
       $w = imagesx($img);
       $h = imagesy($img);
      }
      $text_color = imagecolorallocate($img, 255, 255, 255);
      //$bg_color = imagecolorallocate($img, 255, 255, 255);
      //imagefilledrectangle($img, 0, 0, $w-1, $h-1, $bg_color);
      $textbox = imageftbbox($fsize, 0, $font, $word);
      $x = ($w - ($textbox[2] - $textbox[0])) / 2;
      $y = ($h - ($textbox[7] - $textbox[1])) / 2;
      imagefttext($img, $fsize, 0, $x, $y, $text_color, $font, $word);
      imagepng($img, $img_file);
    }
  4. 自定captcha版面格式
    很機車的johnny不喜歡預設拆成兩行的樣子,硬要我併成一行
    只好硬著頭皮又去改原碼了
    有2個地方要改
    1.到fucntion render()
    public function render(Zend_View_Interface $view = null, $element = null)
    {
      return '<img alt="'.$this->getImgAlt().'" height="'.$this->getHeight().'" src="' . $this->getImgUrl() . $this->getId() . $this->getSuffix() . '" width="'.$this->getWidth().'" /><br>'; //將br拿掉
    }

    另外如果還要拿掉dt,dd等,則需要下個步驟

    2.到library/form/Element/Zend_Form_Element_Captcha.php 改function loadDefaultDecorators()

References
Zend Reference Guide - Captcha Operation
A Zend_Captcha example
Captcha problem
Zend_Form_Element_Captcha

沒有留言: