PHP 验证码 浅析

作者: 尽情的嘲笑我吧 | 来源:发表于2017-10-07 08:23 被阅读0次

    拓展

    我们需要开启gd拓展,可以使用下面的代码来查看是否开启gd拓展。

    <?php
    
    echo "Hello World!!!!";
    
    echo phpinfo();
    ?>
    

    然后在浏览器上Ctrl+F查找gd选项即可验证自己有没有装这个拓展,如果没有的话,还需要自己全装一下这个拓展。

    背景图

    imagecreatetruecolor

    默认生成黑色背景

    <?php
    // 使用gd的imagecreatetruecolor();创建一张背景图
    $image = imagecreatetruecolor(100,30);
    // 在显示这张图片的时候一定要先声明头信息
    header('content-type:image/png');
    
    imagepng($image);
    
    // 释放资源,销毁执行对象
    imagedestroy($image);
    

    imagecolorallocate

    创建一个填充色,并用imagefill(image,x,y,color)方法来附着。

    <?php
    // 使用gd的imagecreatetruecolor();创建一张背景图
    $image = imagecreatetruecolor(100,30);
    
    // 生成填充色
    $bgcolor = imagecolorallocate($image,255,255,255);
    // 将填充色填充到背景图上
    imagefill($image,0,0,$bgcolor);
    // 在显示这张图片的时候一定要先声明头信息
    header('content-type:image/png');
    
    imagepng($image);
    
    // 释放资源,销毁执行对象
    imagedestroy($image);
    

    imagepng

    在使用这个方法之前,一定要先设置头信息,否则不会正常的显示图片

    imagedestory(image)

    适时的释放资源会减轻对服务器请求的压力。

    简易数字验证码

    imagecolorallocate

    生成颜色信息,方便待会的赋予处理。

    $fontcolor=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
    

    imagestring

    把内容信息写到图片的相应位置上。

    imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
    

    增加识别干扰

    增加点

    // 生成一些干扰的点,这里是200个
    for($i=0;$i<200;$i++){
        $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
    }
    
    

    增加线

    // 生成一些干扰线 这里是5个
    for($i=0;$i<5;$i++){
        // 设置为浅色的线,防止喧宾夺主
        $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
        
    }
    
    

    数字字母混合验证码

    <?php
    // 使用gd的imagecreatetruecolor();创建一张背景图
    $image = imagecreatetruecolor(100,40);
    
    // 生成填充色
    $bgcolor = imagecolorallocate($image,255,255,255);
    // 将填充色填充到背景图上
    imagefill($image,0,0,$bgcolor);
    
    //////// 生成随机4位字母以及数字混合的验证码
    for($i=0;$i<4;$i++){
        $fontsize = rand(6,8);
        $fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
        // 为了避免用户难于辨认,去掉了某些有歧义的字母和数字
        $rawstr = 'abcdefghjkmnopqrstuvwxyz23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
        $fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
        // 避免生成的图片重叠
        $x += 20;
        $y = rand(10,20);
        imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);    
    }
    
    // 生成一些干扰的点,这里是200个
    for($i=0;$i<200;$i++){
        $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
    }
    // 生成一些干扰线 这里是4个
    for($i=0;$i<4;$i++){
        // 设置为浅色的线,防止喧宾夺主
        $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
        
    }
    
    
    header('content-type:image/png');
    
    imagepng($image);
    
    // 释放资源,销毁执行对象
    imagedestroy($image);
    

    使用验证码

    开启session的时机

    注意: 开启session一定要在开始的地方

    验证的原理

    验证的过程就是客户端输入的验证码和存在于session域中的验证码进行对比。即:

    if(isset($_REQUEST['checkcode'])){
            session_start();
            if($_REQUEST['checkcode']==$_SESSION['checkcode']){
                echo "<font color='green'>Success!</font>"; 
            }else{
                echo "<font color='red'>Failed!</font>";    
            }
            exit();
        }
    

    优化验证

    但是简单的这样验证有一点不好的地方,那就是字母的大小写容易出错。所以我们要做一下转换,将用户输入的数值全部变成小写的。

    if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){···}
    

    小案例

    生成验证码

    <?php
    session_start();// 必须在php的最开始部分声明,来开启session
    
    
    // 使用gd的imagecreatetruecolor();创建一张背景图
    $image = imagecreatetruecolor(100,40);
    
    // 生成填充色
    $bgcolor = imagecolorallocate($image,255,255,255);
    // 将填充色填充到背景图上
    imagefill($image,0,0,$bgcolor);
    
    //////// 生成随机4位字母以及数字混合的验证码
    $checkcode='';
    for($i=0;$i<4;$i++){
        $fontsize = rand(6,8);
        $fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
        // 为了避免用户难于辨认,去掉了某些有歧义的字母和数字
        $rawstr = 'abcdefghjkmnopqrstuvwxyz23456789';
        $fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
        // 拼接即将诞生的验证码
        $checkcode.=$fontcontent;
        // 避免生成的图片重叠
        $x += 20;
        $y = rand(10,20);
        imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);    
    }
    // 保存到session变量中
    $_SESSION['checkcode']=$checkcode;
    
    // 生成一些干扰的点,这里是200个
    for($i=0;$i<200;$i++){
        $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
    }
    // 生成一些干扰线 这里是4个
    for($i=0;$i<4;$i++){
        // 设置为浅色的线,防止喧宾夺主
        $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
        imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
        
    }
    
    
    header('content-type:image/png');
    
    imagepng($image);
    
    // 释放资源,销毁执行对象
    imagedestroy($image);
    

    表单验证

    <?php
    header("Content-Type:text/html;charset=utf8");
            if(isset($_REQUEST['checkcode'])){
                session_start();
                if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){
                    echo "<font color='green'>Success!</font>"; 
                }else{
                    echo "<font color='red'>Failed!</font>";    
                }
                exit();
            }
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>验证验证码信息</title>
        <script>
            function change(){
                document.getElementById("image_checkcode").src='./store.php?r='+Math.random();  
            }
        </script>
    </head>
    <body>
    <form action="./form.php" method="post">
    <p>验证码图片:</p><img id="image_checkcode" src="./store.php?r=<?php echo rand();?>"   /><a href="javascript:void(0)" onclick="change()">看不清楚</a><br/>
    请输入验证码<input type="text" name="checkcode" /><br />
    <p><input type="submit" value="提交" /></p>
    
    
    </form>
    
    </body>
    </html>
    

    总结

    最后,来个总结吧。

    • 使用php制作验证码需要gd拓展的支持。
    • 使用imagecreatetruecolor方法生成背景色,并用imagefill填充一个由imagecolorallocate产生的颜色。
    • 使用imagestring来实现验证码和背景图的结合
    • 使用imagesetpixel来添加干扰点
    • 使用imageline来添加干扰线
    • 使用session之前要在开头开启session_start()方法
    • 使用JavaScript来动态的修改验证码的src,来满足用户“换一张”的需求。

    相关文章

      网友评论

        本文标题:PHP 验证码 浅析

        本文链接:https://www.haomeiwen.com/subject/rdidyxtx.html