使用 PHP GD 擴展動態生成圖形驗證碼是經典的防機器人機制。本文提供一個功能完整、可直接落地的實作,支援純數字、純字母、英數混合三種模式,並可調整干擾點、干擾線密度與 TrueType 字體渲染。
<?php
require_once 'string.func.php'; // 假設存放輔助函數
/**
* 產生隨機字串
* @param int $type 1=數字 2=字母 3=英數混合
* @param int $length 字串長度
*/
function buildRandomString($type = 1, $length = 4) {
$pool = '';
if ($type === 1) {
$pool = implode('', range(0, 9));
} elseif ($type === 2) {
$pool = implode('', array_merge(range('a', 'z'), range('A', 'Z')));
} elseif ($type === 3) {
$pool = implode('', array_merge(range('a', 'z'), range('A', 'Z'), range(0, 9)));
}
return substr(str_shuffle($pool), 0, $length);
}
/**
* 生成驗證碼圖片並輸出 GIF
* @param int $type 字元類型 (1/2/3)
* @param int $length 字元數
* @param int $pixel 干擾點密度 (0 關閉)
* @param int $line 干擾線條數 (0 關閉)
* @param string $sess_name Session 變數名
*/
function verifyImage($type = 1, $length = 4, $pixel = 0, $line = 0, $sess_name = 'verify') {
// session_start(); // 若未在入口啟動,請取消註解
// 畫布設定
$width = 100;
$height = 40;
$image = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0, 0, 0);
imagefilledrectangle($image, 1, 1, $width - 2, $height - 2, $white);
// 產生驗證碼並存入 Session
$chars = buildRandomString($type, $length);
$_SESSION[$sess_name] = $chars;
// 字體檔案路徑 (需自行備妥 TTF 檔)
$fontfiles = ['SIMKAI.TTF']; // 可擴充多字體隨機切換
// 逐字繪製:隨機大小、角度、顏色、位置
for ($i = 0; $i < $length; $i++) {
$size = mt_rand(14, 18);
$angle = mt_rand(-15, 15);
$x = 5 + $i * $size;
$y = mt_rand(20, 26);
$fontfile = '../fonts/' . $fontfiles[mt_rand(0, count($fontfiles) - 1)];
$color = imagecolorallocate($image, mt_rand(50, 90), mt_rand(80, 200), mt_rand(90, 180));
$text = $chars[$i];
imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text);
}
// 干擾點
if ($pixel) {
for ($i = 0; $i < 50; $i++) {
imagesetpixel($image, mt_rand(0, $width - 1), mt_rand(0, $height - 1), $black);
}
}
// 干擾線
if ($line) {
for ($i = 1; $i < $line; $i++) {
$color = imagecolorallocate($image, mt_rand(50, 90), mt_rand(80, 200), mt_rand(90, 180));
imageline($image, mt_rand(0, $width - 1), mt_rand(0, $height - 1), mt_rand(0, $width - 1), mt_rand(0, $height - 1), $color);
}
}
// 輸出並銷毀
header('Content-Type: image/gif');
imagegif($image);
imagedestroy($image);
}
?>
verifyImage() 前已 session_start(),否則驗證碼無法寫入 $_SESSION。../fonts/ 目錄;Windows 系統字體通常在 C:\Windows\Fonts,Linux 可用 yum install fontconfig 後以 fc-list 查找。strtoupper($_POST['captcha']) === strtoupper($_SESSION['verify']) 比對 (不分大小寫) 或嚴格比對。imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR) 模糊、或使用更複雜的背景圖片、扭曲變形,提高機器識別難度。<?php // captcha.php - 獨立驗證碼端點 session_start(); require_once 'verify.func.php'; // 上述函數檔 verifyImage(3, 4, 1, 2); // 英數混合 4 碼 + 干擾點 + 2 條干擾線 ?>
前端 <img src="captcha.php" id="captcha">,點擊圖片重載 src += '?' + Date.now() 即可切換。