PHP CI框架中的验证码点击更新

CI本身自带验证码,载入视图必须传参,不能够写成函数进行调用。而且图片点击更新实在不会实现。

花了一天找相关的视频和资料,整理了下,大部分属摘抄。


一、CI验证码函数的使用

加载辅助函数

用下面的代码加载验证码辅助函数:

$this->load->helper('captcha');

可用的函数如下:

create_captcha($data)

根据你指定的一系列参数创建验证码图像, 返回值是一个包含此图像数据的数组.

[array]
(
  'image' => IMAGE TAG
  'time' => TIMESTAMP (毫秒)
  'word' => CAPTCHA WORD
)

"image"是实际存在image标记:
<img src="http://example.com/captcha/12345.jpg" width="140" height="50" />

这里的"time"是一个毫秒级的时间戳,作为图片文件名(不包含扩展名). 就像这样: 1139612155.3422

"word"是验证码, 如果不提供, 将是一个随机字符串.

使用验证码辅助函数:

加载后你可以向这样产生一个验证码:

$vals = array(
    'word' => 'Random word',
    'img_path' => './captcha/',
    'img_url' => 'http://example.com/captcha/',
    'font_path' => './path/to/fonts/texb.ttf',
    'img_width' => '150',
    'img_height' => 30,
    'expiration' => 7200
    );

$cap = create_captcha($vals);
echo $cap['image'];

验证码辅助函数必须需要GD库.
  • 只有 img_path 和 img_url 参数是必须的.
  • 如果"word"未提供, 将自动产生一个ASCII字符串. 你也可以使用自己的词库,从里面随机挑选.
  • 如果未提供TRUE TYPE字体的路径, 将会使用GD自带的字体.
  • "captcha" 目录必须可写(666, or 777)
  • "expiration" (秒) 指定了验证码图片的超时删除时间. 默认是2小时.

二、函数调用显示验证码

1、controller文件

public function login(){
	#调用函数生成验证码
		
	$vals = array(
    'word' => 'Random word',//random(1000,9999)
    'img_path' => './captcha/',
    'img_url' => base_url() . '/517/captcha/',
    'img_width' => '150',
    'img_height' => 30,
    'expiration' => 7200
    );
	$cap = create_captcha($vals);
	 echo $cap['image'];
	#输出验证码
	$this->load->view('login.html',$cap);
2、view文件

<p>E-mail:<input type="text" class="input" name="email" id="email"></p>
<p>验证码:<input type="text" name="captcha" class="capital" /><div id= test>
<?php echo $image;?> 

问题:

1、.生成这么多的图片,如何清理,create_captcha函数在生成验证码的同时,会去检查是否有过期的验证码图片,如果有,则删除之。其中过期时间由expiration来指定,默认是2个小时。

2.captcha默认是生成8个长度字符串的验证码,有没有办法来控制其输出的字符。

3、我们需要的是可以点击验证码再次刷新,该怎么办?

一般而言,对于验证码,我们只需要用一次就行,所有没有必要生成图片文件,直接输出即可,然后将其作为img 标签的 src属性。

三、优化(函数调用)

1、先复制system/helper 下面的captcha_helper.php 到application/helper 中,更名为MY_captcha_helper.php。

我们只需要输出图片即可,去掉和目录操作有关的代码

	
if ($img_path == '' OR $img_url == '')
		{
			return FALSE;
		}

		if ( ! @is_dir($img_path))
		{
			return FALSE;
		}

		if ( ! is_writable($img_path))
		{
			return FALSE;
		}



增加验证码字符串个数配置,默认4个

		$defaults = array('word' => '', 'word_length' => 4, 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);

在生成验证码时,使用该配置

	   if ($word == '')
	   {
			$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

			$str = '';
			for ($i = 0; $i < $word_length; $i++)
			{
				$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
			}

			$word = $str;
	   }

验证码在生成同时,还需要保存其生成的字符串

	header("Content-Type:image/jpeg");
		imagejpeg($im);

定义一个方法,用于生产验证码图片

在视图文件中用法如下:

<img alt="" src="<?php echo site_url('denglu_ctl/code');?>"   οnclick= this.src="<?php echo site_url('denglu_ctl/code').'/'?>"+Math.random() style="cursor: pointer;" title="看不清?点击更换另一个验证码。"/>
返回生成的验证码字符串
		#直接输出
		header("Content-Type:image/jpeg");
		imagejpeg($im);

  		ImageDestroy($im);
		#返回生成的验证码字符串
		return $word;


关于MY_captcha_helper.php的加载,尝试在构造函数中加载但并未成功。不知道是什么原因,后来也是在自动加载配置文件中加载的。


四、配置文件

autoload.php

$autoload['helper'] = array('url','MY_captcha');

config.php

$config['subclass_prefix'] = 'MY_';

五、MY_captcha_helper文件
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter CAPTCHA Helper
 *
 * @package		CodeIgniter
 * @subpackage	Helpers
 * @category	Helpers
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/helpers/xml_helper.html
 */

// ------------------------------------------------------------------------

/**
 * Create CAPTCHA
 *
 * @access	public
 * @param	array	array of data for the CAPTCHA
 * @param	string	path to create the image in
 * @param	string	URL to the CAPTCHA image folder
 * @param	string	server path to font
 * @return	string
 */
if ( ! function_exists('create_captcha'))
{
	function create_captcha($data = '', $font_path = '')
	{
		$defaults = array('word' => '', 'word_length' => 4, 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);

		foreach ($defaults as $key => $val)
		{
			if ( ! is_array($data))
			{
				if ( ! isset($$key) OR $$key == '')
				{
					$$key = $val;
				}
			}
			else
			{
				$$key = ( ! isset($data[$key])) ? $val : $data[$key];
			}
		}
/*
		if ($img_path == '' OR $img_url == '')
		{
			return FALSE;
		}

		if ( ! @is_dir($img_path))
		{
			return FALSE;
		}

		if ( ! is_writable($img_path))
		{
			return FALSE;
		}

		if ( ! extension_loaded('gd'))
		{
			return FALSE;
		}

		// -----------------------------------
		// Remove old images
		// -----------------------------------

		list($usec, $sec) = explode(" ", microtime());
		$now = ((float)$usec + (float)$sec);

		$current_dir = @opendir($img_path);

		while ($filename = @readdir($current_dir))
		{
			if ($filename != "." and $filename != ".." and $filename != "index.html")
			{
				$name = str_replace(".jpg", "", $filename);

				if (($name + $expiration) < $now)
				{
					@unlink($img_path.$filename);
				}
			}
		}

		@closedir($current_dir);

*/		// -----------------------------------
		// Do we have a "word" yet?
		// -----------------------------------

	   if ($word == '')
	   {
			$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

			$str = '';
			for ($i = 0; $i < $word_length; $i++)
			{
				$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
			}

			$word = $str;
	   }

		// -----------------------------------
		// Determine angle and position
		// -----------------------------------

		$length	= strlen($word);
		$angle	= ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
		$x_axis	= rand(6, (360/$length)-16);
		$y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);

		// -----------------------------------
		// Create image
		// -----------------------------------

		// PHP.net recommends imagecreatetruecolor(), but it isn't always available
		if (function_exists('imagecreatetruecolor'))
		{
			$im = imagecreatetruecolor($img_width, $img_height);
		}
		else
		{
			$im = imagecreate($img_width, $img_height);
		}

		// -----------------------------------
		//  Assign colors
		// -----------------------------------

		$bg_color		= imagecolorallocate ($im, 255, 255, 255);
		$border_color	= imagecolorallocate ($im, 153, 102, 102);
		$text_color		= imagecolorallocate ($im, 204, 153, 153);
		$grid_color		= imagecolorallocate($im, 255, 182, 182);
		$shadow_color	= imagecolorallocate($im, 255, 240, 240);

		// -----------------------------------
		//  Create the rectangle
		// -----------------------------------

		ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);

		// -----------------------------------
		//  Create the spiral pattern
		// -----------------------------------

		$theta		= 1;
		$thetac		= 7;
		$radius		= 16;
		$circles	= 20;
		$points		= 32;

		for ($i = 0; $i < ($circles * $points) - 1; $i++)
		{
			$theta = $theta + $thetac;
			$rad = $radius * ($i / $points );
			$x = ($rad * cos($theta)) + $x_axis;
			$y = ($rad * sin($theta)) + $y_axis;
			$theta = $theta + $thetac;
			$rad1 = $radius * (($i + 1) / $points);
			$x1 = ($rad1 * cos($theta)) + $x_axis;
			$y1 = ($rad1 * sin($theta )) + $y_axis;
			imageline($im, $x, $y, $x1, $y1, $grid_color);
			$theta = $theta - $thetac;
		}

		// -----------------------------------
		//  Write the text
		// -----------------------------------

		$use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE;

		if ($use_font == FALSE)
		{
			$font_size = 5;
			$x = rand(0, $img_width/($length/3));
			$y = 0;
		}
		else
		{
			$font_size	= 16;
			$x = rand(0, $img_width/($length/1.5));
			$y = $font_size+2;
		}

		for ($i = 0; $i < strlen($word); $i++)
		{
			if ($use_font == FALSE)
			{
				$y = rand(0 , $img_height/2);
				imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);
				$x += ($font_size*2);
			}
			else
			{
				$y = rand($img_height/2, $img_height-3);
				imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));
				$x += $font_size;
			}
		}


		// -----------------------------------
		//  Create the border
		// -----------------------------------

		imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);

		// -----------------------------------
		//  Generate the image
		// -----------------------------------

		// $img_name = $now.'.jpg';

		// ImageJPEG($im, $img_path.$img_name);

		// $img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";
		#直接输出
		header("Content-Type:image/jpeg");
		imagejpeg($im);

  		ImageDestroy($im);
		#返回生成的验证码字符串
		return $word;
		// return array('word' => $word, 'time' => $now, 'image' => $img);
	}
}

// ------------------------------------------------------------------------

/* End of file captcha_helper.php */
/* Location: ./system/heleprs/captcha_helper.php */


整理来源:

1、CI手册

2、CI快速开发商城(传智播客)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值