用户
 找回密码
 入住 CI 中国社区
搜索
查看: 10013|回复: 8
收起左侧

[程序 App] 验证码模型 For CodeIgniter

[复制链接]
发表于 2008-9-22 20:55:59 | 显示全部楼层 |阅读模式
例子:

准备工作

在 system\application\models 下建立文件  vcode_model.php
内容如下
PHP复制代码
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
/**
* by frank
* qq 108818
**/

 
Class Vcode_model extends Model
{
public $width  = 57; //宽度
public $height = 20; //高度
public $len    = 4;  //字符长度
public $backcolor  = '#FFFFFF' ;  //背景色
public $bordercolor = null;   //边框色
public $noisenum  = NULL ;  //杂点数量
 
public $textsize = 10;    //字体大小
public $font = "04b_08.ttf" ;    //自定义字体
public $imagename ;
protected $image ;   //图片变量
protected $backcolorRGB ;  //背景色RGB
protected $bordercolorRGB = null;   //边框色
protected $size;   //每个字符的宽度(px)
protected $sizestr2str;  //字符间距
public $vcode  = NULL; //验证码内容(数字)
function __construct()
{
  parent::Model();
 
 
}
public function show_img()
{
  header("Content-type: image/png");
  //$this->imagename = 'vcode/'.md5(date("YmdHis").$this->vcode).'.png';
  //imagePng($this->image,$this->imagename);
  imagePng($this->image);
  imagedestroy($this->image);
}
 
public function make_img()
{
  $this->image = imageCreate($this->width, $this->height); //创建图片
  $this->backcolorRGB = $this->getcolor($this->backcolor);   //将#ffffff格式的背景色转换成RGB格式
  imageFilledRectangle($this->image, 0, 0, $this->width, $this->height, $this->backcolorRGB); //画一矩形 并填充
  $this->size = $this->width/$this->len; //宽度除以字符数 = 每个字符需要的宽度
  if($this->size>$this->height) $this->size=$this->height; //如果 每个字符需要的宽度 大于图片高度 则 单字符宽度=高度(正方块)
  $this->sizestr2str = $this->size/10 ; //以每个字符的1/10宽度为 字符间距
  $left = ($this->width-$this->len*($this->size+$this->sizestr2str))/$this->size;   // (验证码图片宽度 - 实际需要的宽度)/每个字符的宽度 = 距离左边的宽度
  for ($i=0; $i<$this->len; $i++)
  {
   $randtext = rand(0, 9);  //验证码数字 0-9随机数
   $this->vcode .= $randtext; //写入session的数字
   $textColor = imageColorAllocate($this->image, rand(50, 155), rand(50, 155), rand(50, 155)); //图片文字颜色
   if (!isset($this->textsize) ) $this->textsize = rand( ($this->size-$this->size/10), ($this->size + $this->size/10) ); //如果未定义字体大小 则取随机大小
   $location = $left + ($i*$this->size+$this->size/10);
   imagettftext($this->image, $this->textsize, rand(-18,18), $location, rand($this->size-$this->size/10, $this->size+$this->size/10), $textColor, $this->font, $randtext); //生成单个字体图象
  }
  if( isset($this->noisenum)) $this->setnoise(); //杂点处理
  $_SESSION['vcode'] = $this->vcode; //写入session
 
  if(isset($this->bordercolor)) //边框处理
  {
   $this->bordercolorRGB = $this->getcolor($this->bordercolor);
   imageRectangle($this->image, 0, 0, $this->width-1, $this->height-1, $this->bordercolorRGB);
  }
 
}
 
protected function getcolor($color)
{
  $color = eregi_replace ("^#","",$color);
  $r = $color[0].$color[1];
  $r = hexdec ($r);
  $b = $color[2].$color[3];
  $b = hexdec ($b);
  $g = $color[4].$color[5];
  $g = hexdec ($g);
  $color = imagecolorallocate ($this->image, $r, $b, $g);
  return $color;
}
protected function setnoise()
{
  for ($i=0; $i<$this->noisenum; $i++)
  {
   $randColor = imageColorAllocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
   imageSetPixel($this->image, rand(0, $this->width), rand(0, $this->height), $randColor);
  }
}
}
复制代码
在 system\application\controllers 下建立 文件 vcode.php

内容如下
PHP复制代码
 
<?php
/**
* by frank
* qq 108818
**/

class Index extends Controller {
function __construct()
{
  parent::Controller();
  $this->load->helper('url');
  $this->load->library('session');
  $this->vcodeimg();
 
function vcodeimg()
{
  /***验证码**/
  $this->load->model('vcode_model');
  $this->vcode_model->make_img();
  $this->session->set_userdata('vcode', $this->vcode_model->vcode);
  $this->vcode_model->show_img();
}
 
function showsession()    //这个方法可以删除 仅供debug
{
   echo '<pre>';
   var_dump($this->session->userdata);
   echo '</pre>';
}
 
}
复制代码
然后将打开

http://127.0.0.1/index.php/vcode/

看看能否正确看到验证码

需要查看 当前session中保存的数据 访问这个页面
http://127.0.0.1/index.php/vcode/showsession数组中 vcode 下面的4位 阿拉伯数字 即为验证码


如果想要在某个页面显示验证码图片
需要 在该页面所对应的视图中 增加如下代码片段
JS复制代码
function $(objectId)
{
if(document.getElementById && document.getElementById(objectId))
  {
   // W3C DOM
   return document.getElementById(objectId);
  }
  else if (document.all && document.all(objectId))
  {
   // MSIE 4 DOM
   return document.all(objectId);
  }
  else if (document.layers && document.layers[objectId])
  {
   // NN 4 DOM.. note: this won't find nested layers
   return document.layers[objectId];
  }
  else
  {
   alert('取值失败未找到对应id');
  }
}
 
function reloadvcode(obj)
{
$(obj).src="/index.php/vcode/"+Math.round(Math.random()*100000);
}
 
复制代码
HTML复制代码
<img src="/index.php/vcode" style="vertical-align:middle;" width="57" height="20" id="vcodeimg"  title="单击刷新" />
复制代码


如何验证?

比如您引用验证码的表单页面 action="/index.php/contrl/func/"

那么 在 contrl.php  这个控制器文件中的func 方法中
加入以下代码
PHP复制代码
$this->load->helper('url');
$this->load->library('session');
if ($this->session->userdata['vcode'] != $_POST['vcode'] )
  {
   show_error ('Bad news: 验证码输入不正确!');
  }
else  //校验成功
{
    //your code.....
}
复制代码
祝您好运

/////////////////////////////////
补充点 config.php 里面的
$config['sess_time_to_update']
根据自己的实际情况设置 否则session 无法更新

[ 本帖最后由 yz20sui 于 2008-9-23 01:49 编辑 ]

评分

参与人数 1威望 +5 收起 理由
Hex + 5 原创内容

查看全部评分

发表于 2008-9-23 00:04:00 | 显示全部楼层
我给楼主改了一下语法加亮!好文章,加分!
发表于 2008-9-23 10:20:18 | 显示全部楼层
感觉复杂,,我的比较简单些,
等我空了发出来..:)
发表于 2008-9-25 08:20:04 | 显示全部楼层
系统自带的也不错,哈哈
发表于 2008-9-25 17:28:45 | 显示全部楼层
楼主不错,好文章,谢谢分享
发表于 2009-7-26 15:24:00 | 显示全部楼层
谢谢楼主
发表于 2009-8-12 14:33:19 | 显示全部楼层
session值总是上一次图片中的数字?为什么啊!
发表于 2009-11-9 03:37:31 | 显示全部楼层
我用了楼主的方法,也自己写了几个,都有这个问题,session的值永远是上次图片种的数字!
发表于 2009-11-10 19:41:46 | 显示全部楼层
回复 8# chinawuyi

刚试过,没有问题,每次生成的图都不一样。

在想问题在哪。网上找来例子一试:

PHP复制代码
 
<?php
 
// Requires the GD Library
header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512) or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y=0; $y<512; $y++)
{
        for ($x=0; $x<512; $x++)
        {
                if (rand(0,1) === 1)
                {
                        imagesetpixel($im, $x, $y, $white);
                }
        }
}
imagepng($im);
imagedestroy($im);
?>
 
复制代码


在Linux上每次生成的图都不一样,在Windows上每次生成的图都一样!

问题应该是Windows上PHP的rand()函数并不随机所致。

不妨试试看!

本版积分规则