|
本帖最后由 88646958@qq.com 于 2016-11-19 14:31 编辑
手册我们看到的验证码辅助函数,在我们生成验证码图片的时候实际上是一张png的图片,并且保存在了自己的配置目录里面。手册中提议说可以把验证码放进数据库,可是更多人可能愿意放进session里面。
综合上面两点可能有人就不愿意用这个验证码类了,然后就找找其他的验证码类来用。
其实我们可以扩展下这个captcha类,没用必要去弄些其他的验证类。而且我们扩展的这个类完全不比其他的差。
那我们来扩展下这个captcha验证码类。
如何修改?
首先我们遵循CI原则不破坏原始的类进行扩展,先system的helper复制captcha.php一份在自己的应用目录helper,然后重新命名MY_captcha_helper.php(当然MY_可以自己修改)
打开文件修改以下两处, 注释掉
大概在111行,图片存储的目录。
PHP复制代码
if ($img_path === '' OR $img_url === ''
OR ! is_dir($img_path) OR ! is_really_writable ($img_path)
OR ! extension_loaded('gd'))
{
return FALSE;
}
// -----------------------------------
// Remove old images
// -----------------------------------
$now = microtime(TRUE);
$current_dir = @opendir($img_path);
while ($filename = @readdir($current_dir))
{
if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now)
{
@unlink($img_path.$filename);
}
}
@closedir($current_dir);
复制代码
当然如果你需要把验证码生成的时间放到session里面那么这个不要注释掉。
然后注释掉,图片生成的url地址。大概在336行
PHP复制代码
$img_url = rtrim($img_url, '/').'/';
if (function_exists('imagejpeg'))
{
$img_filename = $now.'.jpg';
imagejpeg($im, $img_path.$img_filename);
}
elseif (function_exists('imagepng'))
{
$img_filename = $now.'.png';
imagepng($im, $img_path.$img_filename);
}
else
{
return FALSE;
}
$img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_url.$img_filename.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />';
复制代码
然后在底部加上,大概像下面这样。
PHP复制代码 header("Content-Type:image/png"); //加入图片格式header头
imagepng($im);
ImageDestroy($im);
return array('word' => $word , 'time' => $now /*,'image' => $img, 'filename' => $img_filename */);
复制代码
这时候函数返回的是一个数组,我们把函数的返回值的 image和filename注释啊掉。 我们只返回word和time两个值就可以了。如果不要时间 可以直接return $word
这里我们可以看到我们把图片存储的路径灭了,生成的图片地址也给灭了。这样我们可以把默认的两个必须的参数img_path,img_url变成不是必须的了。 其实咱们可以在函数里面直接把这两个参数也给灭掉。
大概像下面这样的
PHP复制代码
function create_captcha ($data = '', /* $img_path = '', $img_url = '', */ $font_path = '')
{
$defaults = array(
'word' => '',
/* 'img_path' => '',
'img_url' => '', */
'img_width' => '150',
'img_height' => '30',
.....
复制代码
到此已经修改完毕。
如何使用?
在控制器,大概下面这样,看代码
PHP复制代码
public function captcha ()
{
$this->load->library('session');
$this->load->helper('captcha');
$vals = array(
'word' => rand_chr (6), // 这里用了自己的随机字符串库。
'font_path' => BASEPATH .'fonts/DetailBETA.ttf', // 定义自己的验证码字体
'img_width' => '150',
'img_height' => 39,
'expiration' => 300,
'word_length' => 8,
'font_size' => 16,
'colors' => array(
'background' => array(255, 255, 255),
'border' => array(255, 255, 255),
'text' => array(40, 40, 40),
'grid' => array(255, 40, 40)
)
);
$cap = create_captcha ($vals);
$this->session->set_userdata('code', $cap); //如果只存验证码 到session 用$cap['word'] ,此处存进session的是数组。
} 复制代码
然后可以自己测试下。在浏览器地址输出 http://localhost/ci/index.php/控制器/captcha 就可以看到漂亮的验证码了。这里要配置好你自己的session, 然后我们在session目录可以看到自己存进去的验证码信息了。
我们打开session的存储目录打开session文件可以看到类似下面这样的东西
PHP复制代码 __ci_last_regenerate|i:1479522546;code|a:2:{s:4:"word";s:6:"3L2TPH";s:4:"time";d:1479522549.0557859;} 复制代码
当然如果你喜欢默认的,完全可以自己配置你任何你喜欢的验证码。当然如果你不喜欢默认的字符串,你可以用自己的字符串库 。这里用了rand_chr(), 当你配置了 'word'后 'word_length'就不生效了。
下面是自己写的一个随机字符串函数,我把放进captcha扩展里面,其实遵循CI原则,应该尽量在字符串副主函数里面扩展,这里偷简单就直接放在captcha扩展里面了。
PHP复制代码 if ( ! function_exists('rand_chr'))
{
function rand_chr ($length)
{
$str = '234578ZYACEFGHJKLMNPRSTUVW'; //自己定义喜欢的字符串
$str = str_shuffle($str);
return substr($str,0,$length);
}
} 复制代码
接下来怎么读验证码
PHP复制代码
$this->session->code['word'];
$this->session->code['time'];//如果你要读取验证码生成存储的时间
复制代码
在登录控制器我们在填写的验证码和 到session里面读取的验证码进行比较, 就可以这样使用了。
是不是这样扩展后用起来就很爽了!!!
总结:
我个人认为CI 默认的验证码类其实是最安全有效的。个人推荐不要修改,直接用默认的即使麻烦了点。
|
评分
-
查看全部评分
|