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>

 

 五,生成的验证码效果图

posted @ 2015-11-03 10:27  健康平安快乐  阅读(1811)  评论(0编辑  收藏  举报