以下是一個更完善的驗證碼類:
/**
* 驗證碼生成工具類
*/
class Captcha
{
protected $length = 4; // 驗證碼長度
protected $fonts = ['arial.ttf']; // 驗證碼字體
protected $width = 100; // 驗證碼寬度
protected $height = 40; // 驗證碼高度
protected $bg_color = [255, 255, 255]; // 背景顏色
protected $text_color = [0, 0, 0]; // 驗證碼字體顏色
protected $pixel_noise = 0; // 像素噪點密度
protected $line_noise = 0; // 直線噪點密度
public function __construct($options = [])
{
foreach ($options as $key => $value) {
$this->$key = $value;
}
}
public function generate()
{
// 創建畫布
$image = imagecreatetruecolor($this->width, $this->height);
// 設定背景色
$bg_color = imagecolorallocate($image, ...$this->bg_color);
imagefill($image, 0, 0, $bg_color);
// 生成驗證碼字符串
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$str = '';
for ($i = 0; $i < $this->length; $i++) {
$str .= $chars[mt_rand(0, strlen($chars) - 1)];
}
// 繪製驗證碼字符串
$text_color = imagecolorallocate($image, ...$this->text_color);
$char_width = $this->width / $this->length;
$char_height = $this->height - 8;
$font_size = $char_height * 0.75;
foreach (str_split($str) as $i => $char) {
$font_file = __DIR__ . '/fonts/' . $this->fonts[mt_rand(0, count($this->fonts) - 1)];
$angle = mt_rand(-10, 10);
$x = $char_width * $i + ($char_width - $font_size) / 2;
$y = $char_height + $font_size / 2 - 4;
imagettftext($image, $font_size, $angle, $x, $y, $text_color, $font_file, $char);
}
// 添加像素噪點
if ($this->pixel_noise > 0) {
for ($i = 0; $i < $this->pixel_noise; $i++) {
$x = mt_rand(0, $this->width);
$y = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagesetpixel($image, $x, $y, $color);
}
}
// 添加直線噪點
if ($this->line_noise > 0) {
for ($i = 0; $i < $this->line_noise; $i++) {
$x1 = mt_rand(0, $this->width);
$y1 = mt_rand(0, $this->height);
$x2 = mt_rand(0, $this->width);
$y2 = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imageline($image, $x1, $y1, $x2, $y2, $color);
}
}
// 輸出圖像
header('Content-type: image/png');
imagepng($image);
// 釋放資源
imagedestroy($image);
// 把驗證碼字符串存儲到會話中
session_start();
$_SESSION['captcha'] = strtolower($str);
}
public function validate($input)
{
session_start();
$captcha = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : '';
unset($_SESSION['captcha']);
return strtolower($input) === strtolower($captcha);
}
}示例使用方法:
// 實例化驗證碼生成器
$captcha = new Captcha([
'length' => 4, // 驗證碼長度
'width' => 120, // 驗證碼寬度
'height' => 32, // 驗證碼高度
'bg_color' => [240, 240, 240], // 背景顏色
'text_color' => [20, 20, 20], // 字體顏色
'pixel_noise' => 50, // 像素噪點密度
'line_noise' => 5, // 直線噪點密度
]);
// 生成驗證碼
$captcha->generate();
// 驗證驗證碼
if ($captcha->validate($_POST['captcha'])) {
echo '驗證通過';
} else {
echo '驗證失敗';
}此驗證碼類有以下改進:
- 可以通過構造函數傳遞參數,而不需要通過類屬性手動配置;
- 可以配置多個字體文件,每次繪製驗證碼時隨機選擇一個字體;
- 可以配置像素噪點和直線噪點密度。