ThinkPHP 3.2.3 自带的验证码类位于 /ThinkPHP/Library/Think/Verify.class.php,字体文件位于 /ThinkPHP/Library/Think/Verify/

可以在 Verify.class.php 文件内进行修改,也可以单独写一个类继承自带的验证码类。如果单独写一个继承的类,可以重用父类的属性和方法,但是要注意的是父类中有一些属性和方法是私有(private)的,可以修改这些私有的属性和方法为保护(protected)的,如果不希望修改框架自带的方法的话,也可以在子类中再定义这些属性和方法。

测试的控制器位于 /Application/Home/Controller/TestVerifyController.class.php

测试的试图位于 /Application/Home/View/User/verify.html

自定义的子类位于 /Applicaion/Home/Common/VerifyProcess.class.php

VerifyProcess.class.php:

namespace Home\Common;

use Think\Verify;

class VerifyProcess extends Verify {

private $_image = NULL; // 验证码图片实例

private $_color = NULL; // 验证码字体颜色

public function entryProcess($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->_image = imagecreate($this->imageW, $this->imageH);

// 设置背景

imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]);

// 验证码字体随机颜色

$this->_color = imagecolorallocate($this->_image, mt_rand(1,150),

mt_rand(1,150), mt_rand(1,150));

// 验证码使用随机字体

$ttfPath = $_SERVER['DOCUMENT_ROOT'].'/ThinkPHP/Library/Think/Verify/' .

($this->useZh ? 'zhttfs' : 'ttfs') . '/';

if(empty($this->fontttf)){

$dir = dir($ttfPath);

$ttfs = array();

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();

}

// 绘验证码

$codeNX = 0; // 验证码第N个字符的左边距

// 验证码为简单运算

$a = mt_rand(1,9);

$b = mt_rand(1,9);

$operate_array = array('+', '-', '*');

$key = mt_rand(0, count($operate_array) - 1);

if($operate_array[$key] == '+') { // 加法

$code = $a.'+'.$b.'=';

$result = intval($a + $b);

} elseif($operate_array[$key] == '-') { // 减法

$code = max($a,$b).'-'.min($a,$b).'=';

$result = intval(abs($a - $b));

} else { // 乘法

$code = $a.'*'.$b.'=';

$result = intval($a * $b);

}

$this->length = 4;

for ($i = 0; $ilength; $i++) {

$codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6);

imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40),

$codeNX, $this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]);

}

// 保存验证码

$key = $this->authcode($this->seKey);

$result = $this->authcode($result);

$secode = array();

$secode['verify_code'] = $result; // 把校验码保存到session

$secode['verify_time'] = NOW_TIME; // 验证码创建时间

session($key.$id, $secode);

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->_image);

imagedestroy($this->_image);

}

/**

* 画杂点

* 往图片上写不同颜色的字母或数字

*/

private function _writeNoise() {

$codeSet = '2345678abcdefhijkmnpqrstuvwxyz';

for($i = 0; $i < 10; $i++){

//杂点颜色

$noiseColor = imagecolorallocate($this->_image, mt_rand(150,225),

mt_rand(150,225), mt_rand(150,225));

for($j = 0; $j < 5; $j++) {

// 绘杂点

imagestring($this->_image, 5, mt_rand(-10, $this->imageW),

mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor);

}

}

}

/**

* 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)

*

* 高中的数学公式咋都忘了涅,写出来

* 正弦型函数解析式: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 ($w!=0) {

$py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;

// y = Asin(ωx+φ) + b

$i = (int) ($this->fontSize/5);

while ($i > 0) {

imagesetpixel($this->_image, $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 ($w!=0) {

$py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;

// y = Asin(ωx+φ) + b

$i = (int) ($this->fontSize/5);

while ($i > 0) {

imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color);

$i--;

}

}

}

}

/* 加密验证码 */

private function authcode($str){

$key = substr(md5($this->seKey), 5, 8);

$str = substr(md5($str), 8, 10);

return md5($key . $str);

}

/**

* 绘制背景图片

* 注:如果验证码输出图片比较大,将占用比较多的系统资源

*/

private function _background() {

$path = dirname(__FILE__).'/Verify/bgs/';

$dir = dir($path);

$bgs = array();

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->_image, $bgImage, 0, 0, 0, 0, $this->imageW,

$this->imageH, $width, $height);

@imagedestroy($bgImage);

}

}

TestVerifyController.class.php:

namespace Home\Controller;

use Think\Controller;

use Home\Common\VerifyProcess;

class TestVerifyController extends Controller {

// 界面

public function index() {

$this->display('User/verify');

}

// 验证

public function check_verify() {

$verify = new VerifyProcess();

if(!$verify->check($_POST['verify'])) {

$this->error('验证码错误');

}

}

// 显示验证码

public function verify() {

$verify = new VerifyProcess();

$verify->entryProcess();

}

}

verify.html:

Document

验证码:

style="cursor: pointer;" alt="">

更换验证码

$(function(){

$src = $("#verify").attr('src');

$("#refresh").click(function(){

change_verify();

});

$("#verify").click(function(){

change_verify();

});

function change_verify() {

$('#verify').attr('src', $src + '?' + Math.random());

}

});

效果:

也可以点击图片更换验证码,只需要把点击事件换到图片上就行了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家,关注脚本之家公众号的更多精彩内容。

验证码加减乘PHP,ThinkPHP 3.2.3实现加减乘除图片验证码相关推荐

  1. PHP实现加减乘除图片验证码,ThinkPHP 3.2.3实现加减乘除图片验证码

    ThinkPHP 3.2.3 自带的验证码类位于 /ThinkPHP/Library/Think/Verify.class.php,字体文件位于 /ThinkPHP/Library/Think/Ver ...

  2. 验证码加减乘PHP,使用php实现加减法验证码

    这篇文章主要介绍了php实现的加减法验证码代码,可以使用10以内的加减法生成图片,需要的朋友可以参考下<?php /*图片验证码文件,加减计算方式*/ class ImageCode{ priv ...

  3. mysql实现俩个属性加减运算_SQL实现相邻两行数据的加减乘除操作

    SQL实现表里数据按一定顺序排序后,按某几个字段分组后相邻两行数据实现加减乘除运算. 思路: 1:先把表数据分组排序后打上序号标签 2:根据需求把标签字段加/减一 上代码: select distin ...

  4. 怎么做加减计算机程序vb,怎样使VB做一个加减乘除小程序,麻烦了,快点啊!!...

    繁华若梦 回答时间:2019-12-05 向TA提问 首先,创建两个文本框,命名为aTextbox和bTextbox 再创建一个文本框,命名为sumTextbox 再创建4个按钮,命名为 aButto ...

  5. 如何加减单元格指定数字_Word如何做加减乘除?你学会这个公式就会了

    嗨,各位同学们大家好,我是阿辰. 今天是[第二十二期]的教程啦,在这里给大家分享一个关于word的小知识,就是如何在word表格做加减乘除运算. 一般来说我们经常是在excel做数字运算,怎么在wor ...

  6. python 登陆网站图片验证,用python登录带弱图片验证码的网站

    上一篇介绍了使用python模拟登陆网站,但是登陆的网站都是直接输入账号及密码进行登陆,现在很多网站为了加强用户安全性和提高反爬虫机制都会有包括字符.图片.手机验证等等各式各样的验证码.图片验证码就是 ...

  7. 实现图片验证码【详细代码】

    实际开发过程中经常遇到要实现图片验证码来防止外部使用脚本刷接口,所以说图片验证码是很有必要的一个小功能. html <!--- 注册页面整增加图形验证码功能,这里为了更贴近企业级业务,我们在注册 ...

  8. 图片验证码的实现-kaptcha

    [注意]:适用与springboot项目 1.加载jar包.由于groupId的不同,图片验证码的样式会有所不同 <!--计算类型的验证码 --><dependency>< ...

  9. python+appium自动化测试获取短信+图片验证码

    本篇文章主要讲述的是如何自动获取短信验证码和如何自动获取图片验证码,并写入到对应的输入框中(以下均使用微博的找回密码作为示例) 获取短信验证码的方法有三种,如下所示: 在手机的通知栏中获取短信内容 通 ...

最新文章

  1. 2008 r2 sn sqlserver_sqlserver 下载地址(SQL Server 2008 R2 中英文 开发版/企业版/标准版 下载)...
  2. Tiny4412 Android5.0 定制:编译生成img后如何删除原厂的apk
  3. 区块链技术在出版业的三种应用
  4. Sdk Manager.exe 闪退问题的解决
  5. 浅谈RTS游戏网络同步:3种同步机制模式的实现
  6. 一个牛逼的coder是这样诞生的。
  7. 【LeetCode】【HOT】226. 翻转二叉树(递归)
  8. 数据库和python的结合_redis数据库及与python交互用法简单示例
  9. 经验的总结,需要记录。
  10. uniapp全局传值方式总结
  11. liferay录入中文乱码问题
  12. Android Studio 智能感知无效
  13. 学习 python ORM 类库 SQLAlchemy 使用
  14. java8 多行字符串_JDK8字符串拼接的正确姿势
  15. ASA virtual telnet
  16. 网站php镜像小偷,网站被镜像了怎么办?
  17. 使用 URL 读取网络资源
  18. 考研计算机专业课复试都有什么,2019计算机考研复试科目总结
  19. 错误排查:Cloudera Manager Agent 的 Parcel 目录位于可用空间小于 10.0 吉字节 的文件系统上。 /opt/cloudera/parcels...
  20. SAP中复合角色的应用实例

热门文章

  1. 浙江机器人黑匣子代理_机器人“道德黑匣子”:追踪决策记录 为机器人辩解...
  2. 对于投资者来说,什么是量化投资交易策略?
  3. golang数据结构初探之iota
  4. 关于餐饮行业环境污染现状的调研报告
  5. 可持久化线段树【主席树】可持久化并查集【主席树+并查集】
  6. 关于Java程序调用Lotus Notes邮件服务发送邮件的实现(一思路)
  7. SpatialEmbeddings-master
  8. 为什么大家都说SELECT * 效率低 ?
  9. roast和roasting区别_西餐干加热之有些小复杂的Roast
  10. Metasploit入侵win7