继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

PHP 动态生成图形验证码

woider
关注TA
已关注
手记 23
粉丝 209
获赞 1963

验证码是一种区分用户的全自动程序,它可以有效防止黑客对于特定程序的暴力破解。
最常用的CAPTCHA测试是图形验证码,程序将随机生成一串文字或数字,再将其进行扭曲变形或进行干扰处理(避免被光学字符识别程序破解),最后将输入文字和标准文字进行比较,从而确定用户身份。

借助于一个名为GD(Graphics Draw)的图形库,PHP脚本可以采用图片格式动态生成图像。


生成验证码文本序列

首先要确定文本序列长度,可以使用一个常量表示口令长度,通常6-8个字符就足够了,这样既可以阻止机器人,同时也不会惹恼人类。

 define("CAPTCHA_NUMCHARS", 6);  

接下来需要随机生成每一个字符,rand() 函数在其参数指定范围内返回一个随机数,chr() 将一个数字ASCII字符码转换为一个真正的字符。

chr(rand(97, 122));     //将随机生成字母a-z

图形函数可视化显示图像

首先需要在内存中创建一个空图像,准备由其他GD函数在它之上进行绘制。

$image = imagecreatetruecolor(width:int,height:int);

分配主题颜色,第一个参数是图像资源标识,后面三个参数表示RGB数值分量。

imagecolorallocate(image:resource,red:int,green:int,blue:int);

在图像中一个指定的坐标上绘制一个像素,最后一个参数传入颜色资源标识。

imagesetpixel(image:resource,x:int,y:int,color:int);

在两个坐标之间绘制一条直线,坐标是相对于图像左上角指定的,最后一个参数控制绘制的颜色。

imageline(image:resource,x1:int,y1:int,x2:int,y2:int,color:int);

用某种指定的颜色填充一个矩形,矩形大小由 (x1,y1) 与 (x2,y2) 决定。

imagefilledrectangle(image:resource,x1:int,y1:int,x2:int,y2:int,color:int);

绘制圆和椭圆,以一个中心点和一个宽度和高度作为参数,椭圆的颜色作为最后一个参数传入。

imagefilledellipse(image:resource,cx:int,cy:int,width:int,height:int,color:int);

完成图像绘制,调用 imagepng() 函数将图像输出。如果选择直接在内存中生成一个PNG图像,那么还必须调用 header() 函数通过一个首部把它传送到浏览器。

header("Content-type: image/png");
imagepng(image:resource);

一旦输出了图像,一定要用 imagedestroy() 释放内存中的图像。


利用图形函数绘制文本

imagestring() 函数很容易用来绘制文本,不过对于文本的外观控制很有限。要得到某种特定的外观,需要使用特殊字体,对于通行短语图像来说,字体外观必须独特,而且最好采用一种粗字体来绘制。
字体文件位于 C:\Windows\Fonts 文件夹下,当然你也可以拷贝一份在你的Web服务器上。
通过 imagettftext() 函数,你不仅可以使用你所选择的任何字体,而且可以控制字体的大小,甚至设置绘制文本的角度。

imagettftext( ) 函数参数:

  1. 第一个参数是图像资源标识,
  2. 第二个参数是字体的大小,
  3. 第三个参数是字体的角度,
  4. 第四个参数是文本左下角的X坐标,
  5. 第五个参数是文本左下角的Y坐标,
  6. 第六个参数是字体颜色,
  7. 第七个参数是字体文件位置,
  8. 第八个参数是要绘制的具体文本

生成一个随机的验证码
/* 生成验证码序列 */
define("CAPTCHA_NUMCHARS", 6);  //验证码长度
$pass_phrase = "";              //验证码内容
for ($i = 0; $i < CAPTCHA_NUMCHARS; $i++) {
    //随机生成字母添加至验证码
    $pass_phrase .= chr(rand(97, 122));
}

/* 生成验证码图像 */
define("CAPTCHA_WIDTH", 300);    //验证码宽度
define("CAPTCHA_HEIGHT", 100);    //验证码高度
//创建空白画布
$img = imagecreatetruecolor(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
//设置主题颜色
$bg_color = imagecolorallocate($img, 225, 225, 225);       //白色背景
$text_color = imagecolorallocate($img, 0, 0, 0);           //黑色字体
$graphic_color = imagecolorallocate($img, 64, 64, 64);     //灰色图像
//填充背景
imagefilledrectangle($img, 0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, $bg_color);
//绘制随机直线
for ($i = 0; $i < 10; $i++) {
    imageline($img, 0, rand() % CAPTCHA_HEIGHT, CAPTCHA_WIDTH, rand() % CAPTCHA_HEIGHT, $graphic_color);
}
//绘制随机点
for ($i = 0; $i < 20; $i++) {
    imagefilledellipse($img, rand() % CAPTCHA_WIDTH, rand() % CAPTCHA_HEIGHT, 10, 10, $graphic_color);
}
//绘制验证码
imagettftext($img, 60, 0, 20, CAPTCHA_HEIGHT - 20, $text_color, "C:/Windows/Fonts/SketchFlow Print.ttf", $pass_phrase);
//作为PNG图像输出
header("Content-type: image/png");
imagepng($img);
//从内存从撤销图像
imagedestroy($img);

验证码图像

问:可以使用GD函数创建PNG以外其他格式的图像吗?
答:可以,使用 imagegif( ) 和 imagejpeg( ) 函数可以分别创建 GIF 和 JPEG 图像。
问:使用 imagepng( ) 直接向浏览器输出一个PNG图像时,图像文件存储在哪里?
答:图像并不存储在任何文件中。实际上,imagepng( ) 函数会在服务器的内存中生成一个二进制PNG图像,然后把它直接通过一个首部传送到浏览器。
问:生成图形的PHP脚本能否直接放在<img>标签的src属性中?
答:在<img>标签的src属性中引用一个PHP脚本时,会由脚本直接传送图像。脚本会通过一个首部将图像直接传送到浏览器,而浏览器会把来自首部的图像连接到<img>标记。

打开App,阅读手记
6人推荐
发表评论
随时随地看视频慕课网APP