您的位置:首页 > 编程语言 > PHP开发

PHP 验证码:扭曲+粘连+变形

2015-11-03 10:27 627 查看
一,绪论

  由于项目需要,需要加强目前的验证码,我们参照的对象是支付宝。

class VerifyCode
{

//声明图像大小
private $width = 78;
private $height = 46;

//验证码字符有限集
private $v_char = '1234567890';
private $v_code_str = '';

//验证码数量
private $v_num = 4;

// 第i个文字x轴起始位置计算公式: x轴起始坐标 = margin + padding * i
//文字内外边距
private $padding = 15;
private $margin = 3;

//字体大小
private $font_size = 30;

//字体逆时针旋转的角度
private $font_angles = array(-5, 5);

//字体名称
//private $font = 'Wattauchimma.ttf';
private $font = 'msyh.ttf';    //加上路径非常重要

//图像容器
private $img;

//颜色容器
private $colors = array();

/**
* 生成图片验证码主逻辑
* @author 冯煜博
*/
public function __construct()
{
//生成一幅图像
$this->img = imagecreate($this->width, $this->height);

//生成颜色
$this->colors['white'] =  imagecolorallocate($this->img, 255,255,255);
$this->colors['blue'] =  imagecolorallocate($this->img, 0, 47, 167);

// 生成纯白色背景
imagecolorallocate($this->img, 255,255,255);

// 设置GD库环境变量
putenv('GDFONTPATH=' . realpath('.'));

//生成验证码字符
$this->randomContent();
}

/**
* 输出验证码,返回值是验证码的字符串表示
* @author 冯煜博
* @return string
*/
public function show()
{
$this->generate();

header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header("content-type: image/png");

ImagePNG($this->img);
ImageDestroy($this->img);

return $this->v_code_str;
}

/**
* 生成随机的验证码的内容
* @author 冯煜博
* @return string
*/
private function randomContent()
{
for($i = 0; $i < $this->v_num; $i++)
{
$this->v_code_str .= $this->v_char[ rand(0, strlen($this->v_char) - 1)];
}
}

/**
* 生成验证码的图像
* @author 冯煜博
*/
private function generate()
{
//生成验证码的算法
for($i = 0; $i < $this->v_num; $i++)
{
// 下一个字符的起始x轴坐标
$x = $this->margin + $this->padding * $i;
// 下一个字符的起始y轴坐标
$y = 38;

imagettftext(
$this->img,
$this->font_size,
$this->font_angles[ rand(0, count($this->font_angles) - 1) ],
$x, $y,
$this->colors['blue'],
APPPATH.'libraries/'.$this->font,    //加上了字体的相对路径
$this->v_code_str[ $i ]
);
}

$dst = imagecreatetruecolor($this->width, $this->height);
$dWhite = imagecolorallocate($dst, 255, 255, 255);
imagefill($dst,0,0,$dWhite);

//扭曲,变形
for($i = 0; $i < $this->width; $i++)
{
// 根据正弦曲线计算上下波动的posY

$offset = 4; // 最大波动几个像素
$round = 2; // 扭2个周期,即4PI
$posY = round(sin($i * $round * 2 * M_PI / $this->width ) * $offset); // 根据正弦曲线,计算偏移量

imagecopy($dst, $this->img, $i, $posY, $i, 0, 1, $this->height);
}

$this->img = $dst;
}

public function __destruct()
{
unset($this->colors);
}
}


View Code

三,CI 框架内的写法

  比如在 VCode 控制器内的 show 方法中,调用:

class VCode extends CI_Controller
{
/*
*    显示验证码的网页实际上是异步进行加载的,也就是先后发起两次请求。
*    第一次加载HTML页面;
*    第二次加载图片
*/
public function show()
{

$this->load->library('VerifyCode');

$this->load->library('session');
$this->session->set_flashdata('vcode', $this->verifycode->show());

//session_start();
//$_SESSION['vcode'] = $this->verifycode->show();
}

}


四,THML调用代码

  我们知道,只要访问 {$domain}index.php/vcode/show 就可以看到一张验证码图片。

  所以在HTML的 img src属性中填写上面的URL就可以。    

<html>
<body>

<img src="index.php/vcode/show" />

<br/>

<?php echo form_open('vcode/verify') ?>
<input name="codeStr" />
<input type="submit" name="submit" value="verify" />
</form>

</body>
</html>


五,生成的验证码效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: