PHP中的会话问题-尝试创建一个简单的验证码

时间:2014-04-01 作者:mathiregister

我在我的网站上找到了一个自制联系人表单的验证码脚本。

在我的主题文件夹中,我有一个名为captcha_code_file.php:

<?php 
/*
*
* this code is based on captcha code by Simon Jarvis 
* http://www.white-hat-web-design.co.uk/articles/php-captcha.php
*
* This program is free software; you can redistribute it and/or 
* modify it under the terms of the GNU General Public License 
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details: 
* http://www.gnu.org/licenses/gpl.html
*/

session_start();

//Settings: You can customize the captcha here
$image_width = 110;
$image_height = 35;
$characters_on_image = 6;
$font = \'./monofont.ttf\';

//The characters that can be used in the CAPTCHA code.
//avoid confusing characters (l 1 and i for example)
$possible_letters = \'23456789bcdfghjkmnpqrstvwxyz\';
$random_dots = 0;
$random_lines = 20;
$captcha_text_color="0x#B9B098";
$captcha_noice_color = "0x#CEC7BA";

$code = \'\';


$i = 0;
while ($i < $characters_on_image) { 
$code .= substr($possible_letters, mt_rand(0, strlen($possible_letters)-1), 1);
$i++;
}


$font_size = $image_height * 0.75;
$image = @imagecreate($image_width, $image_height);


/* setting the background, text and noise colours here */
$background_color = imagecolorallocate($image, 255, 255, 255);

$arr_text_color = hexrgb($captcha_text_color);
$text_color = imagecolorallocate($image, $arr_text_color[\'red\'], 
        $arr_text_color[\'green\'], $arr_text_color[\'blue\']);

$arr_noice_color = hexrgb($captcha_noice_color);
$image_noise_color = imagecolorallocate($image, $arr_noice_color[\'red\'], 
        $arr_noice_color[\'green\'], $arr_noice_color[\'blue\']);


/* generating the dots randomly in background */
for( $i=0; $i<$random_dots; $i++ ) {
imagefilledellipse($image, mt_rand(0,$image_width),
 mt_rand(0,$image_height), 2, 3, $image_noise_color);
}


/* generating lines randomly in background of image */
for( $i=0; $i<$random_lines; $i++ ) {
imageline($image, mt_rand(0,$image_width), mt_rand(0,$image_height),
 mt_rand(0,$image_width), mt_rand(0,$image_height), $image_noise_color);
}


/* create a text box and add 6 letters code in it */
$textbox = imagettfbbox($font_size, 0, $font, $code); 
$x = ($image_width - $textbox[4])/2;
$y = ($image_height - $textbox[5])/2;
imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $code);


/* Show captcha image in the page html page */
header(\'Content-Type: image/jpeg\');// defining the image type to be shown in browser widow
imagejpeg($image);//showing the image
imagedestroy($image);//destroying the image instance
$_SESSION[\'6_letters_code\'] = $code;

function hexrgb ($hexstr)
{
  $int = hexdec($hexstr);

  return array("red" => 0xFF & ($int >> 0x10),
               "green" => 0xFF & ($int >> 0x8),
               "blue" => 0xFF & $int);
}
?>
我似乎无法存储创建的会话。我需要做些什么才能让这一切顺利进行?如何在另一个文件中获取会话,例如。if(empty($_SESSION[\'6_letters_code\'])?

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

会话的最终解决方案是。。不要使用会话。

作为表单中的示例,您可以输出3个字段:

图像字段->验证码图像->文本字段->允许用户在隐藏字段中插入字符->包含解决方案,但使用wp_create_nonce通过这种方式,提交表单时,您可以使用wp_verify_nonce 你不用会话就可以解决你的问题。

我将在一个类中编写代码,您可以将所有代码放在一个文件中,命名它\'mycaptcha.php\' 然后将其保存在主题文件夹中,require_once 它来自functions.php.

<?php
class MyCaptcha {
  protected $code = \'\';
  protected $letters = \'23456789bcdfghjkmnpqrstvwxyz\';
  protected $chars_num;
  protected $tcolor;
  protected $ncolor;
  protected $width;
  protected $height;

  /**
   * Allow to configure some options, generate a random code and print the fields
   */
  function __construct( $args = array() ) {
    $defaults = array(
      \'chars_num\' => 6,
      \'dots\' => 0,
      \'lines\' => 20,
      \'width\' => 110,
      \'height\' => 35,
      \'tcolor\' => \'B9B098\',
      \'ncolor\' => \'CEC7BA\'
    );
    $args = wp_parse_args( $args, $defaults );
    foreach ( $args as $k => $v ) {
      $this->$k = $v;
    }
    $this->setCode();
    $this->fields();
  }

  /**
   * Print the fields
   */
  protected function fields() {
    echo $this->getHidden();
    echo $this->getImg();
    echo $this->getText();
  }

  /**
   * Generate a random code
   */    
  protected function setCode() {
    $i = 0;
    $len = strlen( $this->letters ) - 1;
    while ( $i < $this->chars_num ) { 
      $this->code .= substr( $this->letters, mt_rand( 0, $len ), 1 );
      $i++;
    }
  }

  /**
   * Print hidden field
   */ 
  protected function getHidden() {
    return wp_nonce_field( $this->code , md5(__CLASS__) . \'_n\', FALSE, FALSE );
  }

  /**
   * Print text field
   */     
  protected function getText() {
    $f = \'<label>%s<input type="text" name="%s" value="" autocomplete="off" /></label>\';
    return sprintf( $f, __(\'Type the captcha:\', \'your-textdomain\'),  md5(__CLASS__) );
  }

  /**
   * Print captcha image
   */      
  protected function getImg() {
    $f = \'<img src="%s" width="%d" height="%d" alt="" />\';
    $data = array(
      \'c\' => self::encode( $this->code ),
      \'size\' => "{$this->width}x{$this->height}",
      \'dots\' => "{$this->dots}",
      \'lines\' => "{$this->lines}",
      \'tcolor\' => "{$this->tcolor}",
      \'ncolor\' => "{$this->ncolor}"
    );
    $url = add_query_arg( $data, get_template_directory_uri() . \'/captcha_img.php\' );
    return sprintf( $f, $url, $this->width, $this->height );
  }

  /**
   * Verify the nonce
   */      
  static function verify() {
    $method = filter_input( INPUT_SERVER, \'REQUEST_METHOD\', FILTER_SANITIZE_STRING );
    $type = strtoupper( $method ) === \'GET\' ? INPUT_GET : INPUT_POST;
    $nonce = filter_input( $type, md5(__CLASS__) . \'_n\', FILTER_SANITIZE_STRING );
    $code = filter_input( $type, md5(__CLASS__), FILTER_SANITIZE_STRING );
    return ! empty($code) &&  ! empty($nonce) && wp_create_nonce( $code ) === $nonce;
  }

  /**
   * Convert an hexadecimal color to an rgb array color
   */      
  static function hexrgb( $hex ) {
    $int = hexdec( $hex );
    return array(
      "red" => 0xFF & ($int >> 0x10),
      "green" => 0xFF & ($int >> 0x8),
      "blue" => 0xFF & $int
    );
  }

  /**
   * encode the code to avoid put plan code in image url
   */
  private static function encode( $code ) {
    $iv_size = mcrypt_get_iv_size( MCRYPT_BLOWFISH , MCRYPT_MODE_ECB );
    $iv = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
    $key = md5( __CLASS__ );
    $enc = mcrypt_encrypt( MCRYPT_BLOWFISH , $key, $code, MCRYPT_MODE_ECB, $iv);
    return urlencode( base64_encode( $enc ) );
  }

  /**
   * Decode the code
   */
  static function decode( $encoded ) {
    $code = urldecode( base64_decode( $encoded ) );
    $iv_size = mcrypt_get_iv_size( MCRYPT_BLOWFISH , MCRYPT_MODE_ECB );
    $iv = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
    $key = md5( __CLASS__ );
    return mcrypt_decrypt( MCRYPT_BLOWFISH , $key, $code, MCRYPT_MODE_ECB, $iv );
  }

}
请确保有no spaces or blank lines 在strat(之前<?php) 也不在文件末尾。

该类需要主题文件夹中的另一个文件captcha_img.php 应该放在你的主题文件夹中。此文件将包含您发布的代码,只需稍作修改:

<?php 
// require the class
@require_once __DIR__ . \'/mycaptcha.php\';

// defaults
$w = 110;
$h = 35; 
$random_dots = 0;
$random_lines = 20;
$captcha_text_color = "0x#B9B098";
$captcha_noice_color = "0x#CEC7BA";

/* get code */
$code = filter_input( INPUT_GET, \'c\', FILTER_SANITIZE_STRING );
if ( empty( $code ) ) die( \'\' );
$code = MyCaptcha::decode( $code );

/* get settings */
$sizes = filter_input( INPUT_GET, \'size\', FILTER_SANITIZE_STRING );
if ( ! empty( $sizes ) ) {
  $s = explode( \'x\', $sizes );
  if ( is_numeric($s[0]) && (int) $s[0] > 0  ) $w = (int) $s[0];
  if ( isset($s[1]) && is_numeric($s[1]) && (int) $s[1] > 0  ) $h = (int) $s[1];
}
$dots = (int) filter_input( INPUT_GET, \'dots\', FILTER_SANITIZE_NUMBER_INT );
if ( $dots > 0 ) $random_dots = $dots;
$lines = (int) filter_input( INPUT_GET, \'lines\', FILTER_SANITIZE_NUMBER_INT );
if ( $dots > 0 ) $random_lines = $lines;
$tcolor = (string) filter_input( INPUT_GET, \'tcolor\', FILTER_SANITIZE_STRING );
if ( strlen($tcolor) === 6 ) $captcha_text_color = "0x#{$tcolor}";
$ncolor = (string) filter_input( INPUT_GET, \'ncolor\', FILTER_SANITIZE_STRING );
if ( strlen($ncolor) === 6 ) $captcha_noice_color = "0x#{$ncolor}";

/* prepare image */
$font = \'./monofont.ttf\';
$font_size = $h * 0.75;
$image = @imagecreate($w, $h);
$bg_color = imagecolorallocate($image, 255, 255, 255);
$arr_text_color = MyCaptcha::hexrgb($captcha_text_color);
$text_color = imagecolorallocate(
  $image,
  $arr_text_color[\'red\'], 
  $arr_text_color[\'green\'],
  $arr_text_color[\'blue\']
);
$arr_noice_color = MyCaptcha::hexrgb($captcha_noice_color);
  $image_noise_color = imagecolorallocate(
  $image,
  $arr_noice_color[\'red\'], 
  $arr_noice_color[\'green\'],
  $arr_noice_color[\'blue\']
);

/* generating dots randomly in background of image */
for( $i=0; $i < $random_dots; $i++ ) {
  imagefilledellipse(
    $image,
    mt_rand(0, $w), mt_rand(0, $h),
    2, 3,
    $image_noise_color
  );
}

/* generating lines randomly in background of image */
for( $i=0; $i < $random_lines; $i++ ) {
  imageline(
    $image,
    mt_rand(0, $w), mt_rand(0, $h),
    mt_rand(0, $w), mt_rand(0, $h),
    $image_noise_color
  );
}

/* create a text box and add 6 letters code in it */
$textbox = imagettfbbox( $font_size, 0, $font, $code ); 
$x = ( $w - $textbox[4] ) / 2;
$y = ( $h - $textbox[5] ) / 2;
imagettftext( $image, $font_size, 0, $x, $y, $text_color, $font , $code);

/* output captcha image */
header(\'Content-Type: image/jpeg\');
imagejpeg($image);
imagedestroy($image); 
再次确认no spaces or blank lines 开始时(之前<?php) 也不在文件末尾。

如何在表单简单使用中使用打印字段<?php new MyCaptcha; ?> 使用默认设置输出3个字段。

您可以自定义字母的数量、图像的宽度和高度、颜色、将参数数组传递给构造函数的线和点的数量,例如。

 <div class="my_captcha">
   <?php
   $args = array(
     \'chars_num\'=> \'8\', // number of characters
     \'tcolor\' => \'FFFFFF\', // text color
     \'ncolor\' => \'999999\', // noise color
     \'dots\' => 50, // number of dots
     \'lines\'=> 40 // number of lines,
     \'width\'=>\'220\' // number of width,
     \'height\'=>\'70\' // number of height
   );
   new MyCaptcha( $args );
   ?>
 </div>
在文件或处理表单的函数中验证,您只需使用以下方法即可验证:

$is_captcha_corrent = MyCaptcha::verify();
没什么了。当然,如果您使用外部文件来处理表单,则此文件必须引导WordPress。

这两个文件都有摘要here.

结束

相关推荐

如果$_SESSION处于活动状态,WordPress是否隐藏小工具?

我想知道,当我的网站试图显示这些小部件时,是否有一个简单的解决方案来添加一些php“if”代码,并且如果它有我在主页上设置的$\\u会话(基于它们的来源)而不显示其中一个?