下载源码包:

https://github.com/top-think/think-captcha

字体库:

源文件路径:

//代码中字体路径,背景路径已经修改。

<?php
class Vcode
{
protected $config = [
'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
// 验证码字符集合
'expire' => 1800,
// 验证码过期时间(s)
'useZh' => false,
// 使用中文验证码
'zhSet' => '们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自
// 中文验证码字符串
'useImgBg' => false,
// 使用背景图片
'fontSize' => 20,
// 验证码字体大小(px)
'useCurve' => true,
// 是否画混淆曲线
'useNoise' => true,
// 是否添加杂点
'imageH' => 40,
// 验证码图片高度
'imageW' => 180,
// 验证码图片宽度
'length' => 5,
// 验证码位数
'fontttf' => '',
// 验证码字体,不设置随机获取
'bg' => [243, 251, 254],
// 背景颜色
'reset' => true,
// 验证成功后是否重置
]; private $code = 'default'; // 生成的验证码字符串 private $im = null; // 验证码图片实例
private $color = null; // 验证码字体颜色 /**
* 架构方法 设置参数
* @access public
* @param array $config 配置参数
*/
public function __construct($config = [])
{ $this->config = array_merge($this->config, $config);
} /**
* 使用 $this->name 获取配置
* @access public
* @param string $name 配置名称
* @return mixed 配置值
*/
public function __get($name)
{ return $this->config[$name];
} /**
* 设置验证码配置
* @access public
* @param string $name 配置名称
* @param string $value 配置值
* @return void
*/
public function __set($name, $value)
{
if (isset($this->config[$name])) {
$this->config[$name] = $value;
}
} /**
* 检查配置
* @access public
* @param string $name 配置名称
* @return bool
*/
public function __isset($name)
{ return isset($this->config[$name]);
} /**
* 输出验证码并把验证码的值保存的session中
* 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间');
* @access public
* @param string $id 要生成验证码的标识
* @return \think\Response
*/
public function entry($id = '')
{
// 图片宽(px)
$this->imageW || $this->imageW = $this->length * $this->fontSize * 1.5 + $this->length * $this->fontSize / 2;
// 图片高(px)
$this->imageH || $this->imageH = $this->fontSize * 2.5;
// 建立一幅 $this->imageW x $this->imageH 的图像
$this->im = imagecreate($this->imageW, $this->imageH);
// 设置背景
imagecolorallocate($this->im, $this->bg[0], $this->bg[1], $this->bg[2]); // 验证码字体随机颜色
$this->color = imagecolorallocate($this->im, mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150));
// 验证码使用随机字体
$ttfPath = 'assets/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/'; if (empty($this->fontttf)) {
$dir = dir($ttfPath);
$ttfs = [];
while (false !== ($file = $dir->read())) {
if ('.' != $file[0] && substr($file, -4) == '.ttf') {
$ttfs[] = $file;
}
}
$dir->close();
$this->fontttf = $ttfs[array_rand($ttfs)];
}
$this->fontttf = $ttfPath . $this->fontttf; if ($this->useImgBg) {
$this->background();
} if ($this->useNoise) {
// 绘杂点
$this->writeNoise();
}
if ($this->useCurve) {
// 绘干扰线
$this->writeCurve();
} // 绘验证码
$code = []; // 验证码
$codeNX = 0; // 验证码第N个字符的左边距
if ($this->useZh) {
// 中文验证码
for ($i = 0; $i < $this->length; $i++) {
$code[$i] = iconv_substr($this->zhSet, floor(mt_rand(0, mb_strlen($this->zhSet, 'utf-8') - 1)), 1, 'utf-8');
imagettftext($this->im, $this->fontSize, mt_rand(-40, 40), $this->fontSize * ($i + 1) * 1.5, $this->fontSize + mt_rand(10, 20), $this->color, $this->fontttf, $code[$i]);
}
} else {
for ($i = 0; $i < $this->length; $i++) {
$code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet) - 1)];
$codeNX += mt_rand($this->fontSize * 1.2, $this->fontSize * 1.6);
imagettftext($this->im, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize * 1.6, $this->color, $this->fontttf, $code[$i]);
}
} $this->code = $code; ob_start();
// 输出图像
imagepng($this->im);
$content = ob_get_clean();
imagedestroy($this->im); ob_clean(); header('Content-Type:image/png');
header('Content-Length:' . strlen($content));
echo $content;
} /**
* 获取生成的验证码文本
* @return [type] [description]
*/
public function getCode()
{ return empty($this->code) ? ' ' : $this->code;
} /**
* 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)
*
* 高中的数学公式咋都忘了涅,写出来
* 正弦型函数解析式:y=Asin(ωx+φ)+b
* 各常数值对函数图像的影响:
* A:决定峰值(即纵向拉伸压缩的倍数)
* b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
* φ:决定波形与X轴位置关系或横向移动距离(左加右减)
* ω:决定周期(最小正周期T=2π/∣ω∣)
*
*/
private function writeCurve()
{
$px = $py = 0; // 曲线前部分
$A = mt_rand(1, $this->imageH / 2); // 振幅
$b = mt_rand(-$this->imageH / 4, $this->imageH / 4); // Y轴方向偏移量
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量
$T = mt_rand($this->imageH, $this->imageW * 2); // 周期
$w = (2 * M_PI) / $T; $px1 = 0; // 曲线横坐标起始位置
$px2 = mt_rand($this->imageW / 2, $this->imageW * 0.8); // 曲线横坐标结束位置 for ($px = $px1; $px <= $px2; $px = $px + 1) {
if (0 != $w) {
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
$i = (int) ($this->fontSize / 5);
while ($i > 0) {
imagesetpixel($this->im, $px + $i, $py + $i, $this->color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
$i--;
}
}
} // 曲线后部分
$A = mt_rand(1, $this->imageH / 2); // 振幅
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量
$T = mt_rand($this->imageH, $this->imageW * 2); // 周期
$w = (2 * M_PI) / $T;
$b = $py - $A * sin($w * $px + $f) - $this->imageH / 2;
$px1 = $px2;
$px2 = $this->imageW; for ($px = $px1; $px <= $px2; $px = $px + 1) {
if (0 != $w) {
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
$i = (int) ($this->fontSize / 5);
while ($i > 0) {
imagesetpixel($this->im, $px + $i, $py + $i, $this->color);
$i--;
}
}
}
} /**
* 画杂点
* 往图片上写不同颜色的字母或数字
*/
private function writeNoise()
{
$codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
for ($i = 0; $i < 10; $i++) {
//杂点颜色
$noiseColor = imagecolorallocate($this->im, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225));
for ($j = 0; $j < 5; $j++) {
// 绘杂点
imagestring($this->im, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor);
}
}
} /**
* 绘制背景图片
* 注:如果验证码输出图片比较大,将占用比较多的系统资源
*/
private function background()
{
$path = 'assets/bgs/';
$dir = dir($path); $bgs = [];
while (false !== ($file = $dir->read())) {
if ('.' != $file[0] && substr($file, -4) == '.jpg') {
$bgs[] = $path . $file;
}
}
$dir->close(); $gb = $bgs[array_rand($bgs)]; list($width, $height) = @getimagesize($gb);
// Resample
$bgImage = @imagecreatefromjpeg($gb);
@imagecopyresampled($this->im, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height);
@imagedestroy($bgImage);
}
}

  

  

CodeIgniter(3.1.4)框架中整合ThinkPHP验证码的更多相关文章

  1. 在DWZ框架中整合kindeditor复文本框控件

    今天上午在DWZ框架中整合kindeditor复文本框控件,发现上传图片是老是提示 “上传中,请稍候...”,上网查看别人说可能是文件路径问题,在想以前在其他项目中用这个控件一直没问题,到这里怎么会出 ...

  2. C#开发微信门户及应用(48) - 在微信框架中整合CacheManager 缓存框架

    在我们的很多框架或者项目应用中,缓存在一定程度上可以提高程序的响应速度,以及减轻服务器的承载压力,因此在一些地方我们都考虑引入缓存模块,这篇随笔介绍使用开源缓存框架CacheManager来实现数据的 ...

  3. CodeIgniter(3.1.4)框架中添加执行时间统计代码

    CodeIgniter(3.1.4)框架中添加,执行时间统计代码: system/core/CodeIgniter.php最后行处. /* * ---------------------------- ...

  4. 在Winform混合式框架中整合外部API接口的调用

    在我们常规的业务处理中,一般内部处理的接口多数都是以数据库相关的,基于混合式开发的Winform开发框架,虽然在客户端调用的时候,一般选择也是基于Web API的调用,不过后端我们可能不仅仅是针对我们 ...

  5. Spring框架中整合JUnit单元测试的方法

    一. 步骤: 1. 拷贝jar包: 1. JUnit-4.9.jar和spring-test-4.2.4.RELEASE.jar ; 2. 替换原来的main函数: 1. 在测试类上使用注解方式替换: ...

  6. CodeIgniter(3.1.4)框架中设置默认控制器

    创建的目录结构: 如果是以上这种目录分布结构,则在controller文件夹下没有相应的控制器文件.如果在浏览器中直接使用 [http://localhost]则找不到相应的控制器. 必须进行以下设置 ...

  7. CodeIgniter(3.1.4)框架中成功/错误跳转

    if ( ! function_exists('error')) { /** * 错误跳转 */ function error($mes, $url) { echo '<script type= ...

  8. CodeIgniter(3.1.4)框架中-使用多个公共控制器

    项目目录结构: 在core/MY_Controller.php文件下: <?php /** * Class MY_Controller * 自定义控制器 */ class MY_Controll ...

  9. CI框架中,扩展验证码类。

    使用CI框架的朋友,应该都知道CI框架的的验证码辅助函数,不太好用.它需要写入到数据库中,然后再进行比对. 大家在实际项目中,好像不会这样去使用,因为会对数据库造成一定的压力. 所以,我们还是利用se ...

随机推荐

  1. Windows CMD常用命令大全 运行命令

    http://blog.163.com/lixunhuan@126/blog/static/122060620075124142658/ CMD命令大全 net use \\ip\ipc$ " ...

  2. FreeSWITCH检测DTMF数据的方法

    一.RFC2833 1. 介绍: RFC2833为带内检测方式,通过RTP传输,由特殊的rtpPayloadType即TeleponeEvent来标示RFC2833数据包.同一个DTMF按键通常会对应 ...

  3. 获取Android运行apk的packagename 和activityname

    自动化测试中经常遇到这个问题,关于这个题目,方法众多,咱的目的是找个比较简单靠谱的: 方法一: 先进入cmd窗口,adb shell 后: cd /data/data ls 可以看到包名了吧,缺点很明 ...

  4. java mac install

    http://docs.oracle.com/javase/8/docs/technotes/guides/install/mac_jdk.html#A1096855 This page descri ...

  5. python中if __name__ == '__main__'的说明

    这个表示执行的是此代码所在的文件. 如果这个文件是作为模块被其他文件调用,不会执行这里面的代码. 只有执行这个文件时, if 里面的语句才会被执行. 这个功能经常可以用于进行测试. python中,当 ...

  6. 子墨庖丁Android的ActionBar源代码分析 (一)实例化

    假设你从事过Androidclient开发,相信你对ActionBar这套框架并不陌生,或者说你并不了解它,可是你应该时不时的要跟它打交道.抛开ActionBar的实现不说,ActionBar实际上是 ...

  7. 启动vim不加载.vimrc

    启动vim,不加载.vimrcvim -u NONE -N

  8. 强者联盟——Python语言结合Spark框架

    引言:Spark由AMPLab实验室开发,其本质是基于内存的高速迭代框架,"迭代"是机器学习最大的特点,因此很适合做机器学习. 得益于在数据科学中强大的表现,Python语言的粉丝 ...

  9. asp.net kindeditor 后台取不到数据

    今晚搞了3个小时,才搞定这个破问题. 页面上使用kindeditor,提交的时候使用了LinkButton,按钮后台事件私活娶不到kineditor里的数据. 最终一步一步测试,终于发现是LinkBu ...

  10. 程序挂在dynamic_cast<CCObject*>(pDelegate)->retain();

    CCTargetedTouchDelegate 的继承 和 dynamic_cast 想写个可以响应touch的sprite 类定义成了这个样子: class GemBoard : public CC ...