zoukankan      html  css  js  c++  java
  • PHP实现图片验证码功能

    验证码: captcha, 是一种用于区别人和电脑的技术
    原理(Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)

    如何区分计算机和人类?
    只要是文字性的内容,计算机一定可以识别; 计算机是不能识别图片内容的, 但是人眼非常容易识别图片中的内容.

    验证码本质: 将文字性的内容印在图片上, 用来实现计算机和人类的区别.

    一、图片扩展了解

    PHP本身无法操作图片.
    PHP但是可以利用提供的图片扩展操作图片.

    图片扩展有很多: 常用的是GD

    加载GD扩展: 所有的GD扩展函数image开头

    二、PHP操作图片

    1.增加画布(创建画布)

    图片资源 imagecreatetruecolor(宽,高);

    2.在画布上增加内容(文字)

    a)给将要在图片上添加的内容分配颜色: 先将颜色关联到图片资源,然后才可以使用
    颜色句柄[整型] imagecolorallocate(图片资源,红色,绿色,蓝色); //颜色可以使用数字0-255或者使用十六进制#十六进制

    b)写文字: 只能写英文(ASCII码表上的内容)
    布尔 imagestring(图片资源,文字大小,起始X坐标,起始Y坐标,写内容,颜色);
    字体大小: 1-5

    3.保存输出

    imagepng(图片资源[,保存位置]);

    4.释放资源(资源建议释放)

    布尔结果 imagedestroy(图片资源);

    //1.    创建画布
    $img = imagecreatetruecolor(200,200);
    //var_dump($img);
    
    //2.    作画
    //2.1   给画布分配颜色
    $color = imagecolorallocate($img,255,255,255);
    //echo $color;
    
    //2.2   写入文字
    $true = imagestring($img,5,50,90,'hello world',$color);
    //var_dump($true);
    
    //3.    保存输出内容
    //3.1   输出
    //告诉浏览器,内容是图片
    //header('Content-type:image/png');
    //imagepng($img);
    
    //3.2   保存图片
    imagepng($img,'hello.png'); // 保存到当前目录
    
    //4.    释放资源
    $res = imagedestroy($img);
    var_dump($res);

    三、验证码图片

    1.生成随机验证码数据

    2.创建画布

    3.填充背景色: imagefill(图片资源,起始位置X,起始位置Y,颜色句柄); //imagefill: 找到一个像素点之后, 如果发现周围相邻的像素点与当前像素点颜色一样(全部黑色)就会被自动渲染.

    4.添加文字内容: 先分配颜色

    5.保存输出: 验证码都是输出

    6.释放资源

    //制作验证码图片
    
    //获取验证码字符串
    $captcha = '';
    for($i = 0;$i < 4;$i++){
        //chr: 将数字转换成对应的字符(ASCII)
        switch(mt_rand(0,2)){
            case 0: //数字
                $captcha .= chr(mt_rand(49,57));
                break;
            case 1:    //大写字母
                $captcha .= chr(mt_rand(65,90));
                break;
            case 2: //小写字母
                $captcha .= chr(mt_rand(97,122));
                break;
        }
    }
    //echo $captcha;
    
    //创建画布
    $img = imagecreatetruecolor(200,200);
    
    //给背景分配颜色
    $bg = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
    
    //填充背景色
    imagefill($img,0,0,$bg);
    
    //循环写入
    for($i = 0;$i < 4;$i++){
        //分配文字颜色
        $txt = imagecolorallocate($img,mt_rand(50,150),mt_rand(50,150),mt_rand(50,150));
    
        //写入文字
        imagestring($img,mt_rand(1,5),60 + $i*20,90,$captcha[$i],$txt);
    }
    
    //输出
    header('Content-type:image/png');
    imagepng($img);
    
    //释放资源
    imagedestroy($img);

    四、中文验证码

    两个注意点
    获取随机中文: 在PHP中都是以字节为单位操作数据,中文在不同字符集中有不同字节数
    中文写入函数: imagettftext(图片资源,字体大小, 字体旋转角度, 字体的起始X,字体起始Y, 字体文件,内容, 颜色);

    1.创建画布: 填充背景色

    2.获取随机中文

    3.将中文写入到图片

    4.保存输出图片

    5.销毁资源

    //中文验证码
    header('Content-type:text/html;charset=utf-8');
    
    //创建画布
    $img = imagecreatetruecolor(200,200);
    //给背景分配颜色
    $bg = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
    //填充背景色
    imagefill($img,0,0,$bg);
    
    //写入内容
    for($i = 0;$i < 4;$i++){
        //分配颜色
        $txt = imagecolorallocate($img,mt_rand(50,150),mt_rand(50,150),mt_rand(50,150));
    
        //获取随机中文
        $string = "今天我寒夜里看雪飘过怀着冷却了的心窝飘远方";
        
        $pos = mt_rand(0,strlen($string) - 1);
        $start = $pos - $pos % 3;        //utf-8取模3,GBK取模2
    
        //取三个长度(字符串截取)
        $target = substr($string,$start,3);
    
        //写入中文
        imagettftext($img,mt_rand(20,40),mt_rand(-45,45),40 + $i * 30, mt_rand(80,120),$txt,'simple.ttf',$target);
    
    }
    
    //输出图片
    header('Content-type:image/png');
    imagepng($img);
    
    //销毁资源
    imagedestroy($img);

    五、封装验证码类

    //验证码工具类
    
    class Captcha{
        //属性
        private $width;
        private $height;
        private $strlen;
        private $lines;     //干扰线数量
        private $stars;     //干扰点数量
        private $font;      //字体路径
    
        //构造方法:初始化属性
        public function __construct($info = array()){
            //初始化属性
            $this->width    = isset($info['width'])?$info['width']:146;
            $this->height    = isset($info['height'])?$info['height']:23;
            $this->strlen    = isset($info['strlen'])?$info['strlen']:4;
            $this->lines    = isset($info['lines'])?$info['lines']:10;
            $this->stars    = isset($info['stars'])?$info['stars']:50;
            $this->font        = isset($info['font'])?$info['font']:'fonts/AxureHandwriting-BoldItalic.otf';
        }
    
        //生成验证码图片
        public function generate(){
            //创建画布,给定背景色
            $img = imagecreatetruecolor($this->width,$this->height);
            $c_bg = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
            imagefill($img,0,0,$c_bg);
    
            //写入字符串
            $captcha = $this->getStr();
            
            //增加干扰点"*"
            for($i = 0;$i < $this->stars;$i++){
                //随机颜色
                $c_star = imagecolorallocate($img,mt_rand(100,150),mt_rand(100,150),mt_rand(100,150));
    
                //写入*号
                imagestring($img,mt_rand(1,5),mt_rand(0,$this->width),mt_rand(0,$this->height),'*',$c_star);
            }
    
            //增加干扰线
            for($i = 0;$i < $this->lines;$i++){
                //随机颜色
                $c_line = imagecolorallocate($img,mt_rand(150,200),mt_rand(150,200),mt_rand(150,200));
    
                //划线
                imageline($img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$c_line);
            }
    
            //随机颜色
            for($i = 0;$i < $this->strlen;$i++){
                $c_str = imagecolorallocate($img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100));
                imagettftext($img,mt_rand(10,20),mt_rand(-45,45),20 + $i * 30,mt_rand(14,$this->height - 6),$c_str,$this->font,$captcha[$i]);
    
            }
            
            //输出图片
            header('Content-type:image/png');
            imagepng($img);
    
            //释放资源
            imagedestroy($img);
        }
    
        //获取随机字符串
        //@return 字符串
        private function getStr(){
            //ASCII码表生成字符串
            $str = '';
    
            //循环生成
            for($i = 0;$i < $this->strlen;$i++){
                //随机选择数字,小写字母和大写字母
                switch(mt_rand(0,2)){
                    case 0: //数字
                        $str .= chr(mt_rand(49,57));
                        break;
                    case 1: //小写字母
                        $str .= chr(mt_rand(97,122));
                        break;
                    case 2: //大写字母
                        $str .= chr(mt_rand(65,90));
                        break;
                }
            }
    
            //将验证码字符串保存到session
            $_SESSION['captcha'] = $str;
    
            //返回结果
            return $str;
        }
    
        /*
         * 验证验证码
         * @param1 string $captcha,用户输入的验证码数据
         * @return boolean,成功返回true,失败返回false
         */
        public static function checkCaptcha($captcha){
            //与session中的验证码进行验证
    
            //验证码不区分大小写
            return (strtoupper($captcha) === strtoupper($_SESSION['captcha']));
        }
    
    }
  • 相关阅读:
    HDU5000 (DP + 规律)
    HDU5127 神坑题---vector 、 list 、 deque 的用法区别
    HDU5128 细心、细心、细心
    dij单源最短路纯模板
    POJ 1236 SCC+缩点
    SCC(强连通分量)
    用树状数组求数组内的逆序对数
    HDU 1811 并查集
    大数模板,只要不是手敲,非常好用
    市赛
  • 原文地址:https://www.cnblogs.com/chenjiacheng/p/6522326.html
Copyright © 2011-2022 走看看