zoukankan      html  css  js  c++  java
  • PHP 验证码:扭曲+粘连+变形

    一,绪论

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

      基于PHP CodeIgniter 框架,代码放置在下面的路径下。 

    /application/libraries

    二,主要代码

    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>

     五,生成的验证码效果图

  • 相关阅读:
    测试用例编写思路
    pipenv和virtualenv
    HTTP协议
    性能测试实践
    性能测试
    JS创建类和对象
    servlet的转发与重定向
    早晚得看算法
    安卓开始啦
    写于大三下开学前(即将休学)
  • 原文地址:https://www.cnblogs.com/fengyubo/p/4932276.html
Copyright © 2011-2022 走看看