在用PHP写自己的博客时,当做到登录这块时,需要使用一个图片验证码,在网上搜了一大圈,都没找到一个满意的结果,最终参照网友的代码,自己做了一些更改,并抽取成一个通用的函数。
首先是生成一张字符窜图片:
<?php
/**
* 将字符窜生成图片(包含随机线条等混淆信息)
* @access public
* @param string $_str 字符窜
* @param int $_width 图片宽度
* @param int $_height 图片高度
* @param bool $_flag 图片是否需要边框
*/
function create_str_image($_str, $_width, $_height, $_flag = true) {
if (!is_int($_width) || $_width <= 0 || !is_int($_height)
|| $_height <= 0) {
return null;
}
$_str_len = strlen($_str);
if ($_str_len <= 0) {
return null;
}
// 创建一张图像
$_img = imagecreatetruecolor($_width, $_height);
// 白色
$_white = imagecolorallocate($_img, 255, 255, 255);
// 填充
imagefill($_img, 0, 0, $_white);
// 边框
if ((bool)$_flag) {
$_rnd_color = imagecolorallocate($_img, mt_rand(0, 255),
mt_rand(0, 255), mt_rand(0, 255));
imagerectangle($_img, 0, 0, $_width-1, $_height-1, $_rnd_color);
}
$_rnd_count = $_width > $_height ? $_width - $_height : $_height - $_width;
// 随机画线
for ($i = 0; $i < $_rnd_count; $i++) {
$_rnd_color = imagecolorallocate($_img, mt_rand(0, 255),
mt_rand(0, 255), mt_rand(0, 255));
imageline($_img, mt_rand(0, $_width), mt_rand(0, $_height),
mt_rand(0, $_width), mt_rand(0, $_height), $_rnd_color);
}
// 随机雪花
for ($i = 0; $i < $_rnd_count; $i++) {
$_rnd_color = imagecolorallocate($_img, mt_rand(200, 255),
mt_rand(200, 255), mt_rand(200, 255));
imagestring($_img, 1, mt_rand(1, $_width), mt_rand(1, $_height),
'*', $_rnd_color);
}
// 输出验证码
$_str_width = 0.9 * $_width / $_str_len;
$_str_height = 0.9 * $_height;
$_str_pos = 0.1 * $_width;
// 使用时需要修改一下字体路径
// 默认情况下,生成的图片字体很小,所以才选择使用了别的字体
$_font = $_SERVER["DOCUMENT_ROOT"] . "/fonts/FreeMonoOblique.ttf";
for ($i = 0; $i < $_str_len; $i++) {
$_rnd_color = imagecolorallocate($_img, mt_rand(0, 100),
mt_rand(0, 150), mt_rand(0, 200));
imagettftext($_img, $_str_height, mt_rand(0, 45), $_str_pos,
$_str_height, $_rnd_color, $_font, $_str[$i]);
$_str_pos += $_str_width;
}
return $_img;
}
?>
默认情况下是不支持图片生成的,还需要安装php5-gd,并将/etc/php5/apache2/php.ini文件中的gd.jpeg_ignore_warning = 0注释取消。
现在图片是生成出来了,但是要显示到页面,还得有如下代码:
<?php
/**
* @param int $len 随机字符窜长度,默认值:4
* @param int $width 图片宽度,默认值:140
* @param int $height 图片高度,默认值:40
* @param bool $flag 是否需要边框,默认值:true
* @param string $type 图片类型,默认值:image/png
* @param string $key SESSION存放键,默认值:random_validation_code
*/
include_once(__DIR__ . "/include/array.php");
include_once(__DIR__ . "/include/random.php");
include_once(__DIR__ . "/include/images.php");
$len = array_get_int($_REQUEST, "len", 4);
$width = array_get_int($_REQUEST, "width", 140);
$height = array_get_int($_REQUEST, "height", 37);
$flag = array_get_bool($_REQUEST, "flag", true);
$type = array_get_string($_REQUEST, "type", "png");
$key = array_get_string($_REQUEST, "key", "vcode");
$str = random_str($len);
$img= create_str_image($str, $width, $height, $flag);
if ($img != null) {
session_start();
//输出图像
switch(strtolower($type)) {
case "jpeg":
header("Content-Type: image/jpeg");
imagejpeg($img);
break;
case "gif":
header("Content-Type: image/gif");
imagegif($img);
break;
default:
header("Content-Type: image/png");
imagepng($img);
break;
}
// 销毁
imagedestroy($img);
// 保存在session
$_SESSION[$key] = $str;
} else {
header("Content-Type: text/plain");
echo "fail to create image";
}
// print_r(array($len, $width, $height, $flag, $type, $key));
?>
为了更通用一些,所以所有参数都可以通过Request Param加入。