会话的最终解决方案是。。不要使用会话。
作为表单中的示例,您可以输出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.