在 Web 開發中,驗證碼是防止機器人惡意提交表單的基本防線。雖然現代框架多內建驗證碼元件,但了解如何從零打造客製化驗證碼,不僅能因應特殊需求,更能深入掌握 GD 圖形處理的核心邏輯。本文將完整解析一個支援自訂字元數、字體大小、圖片寬高的驗證碼產生函式,並逐行剖析關鍵技術細節。
<?php
function vCode($num = 4, $size = 20, $width = 0, $height = 0) {
// 1. 動態計算畫布尺寸
!$width && $width = $num * $size * 4 / 5 + 5;
!$height && $height = $size + 10;
// 2. 定義字元池(排除易混淆字元)
$str = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVW";
$code = '';
for ($i = 0; $i < $num; $i++) {
$code .= $str[mt_rand(0, strlen($str) - 1)];
}
// 3. 建立真彩色畫布
$im = imagecreatetruecolor($width, $height);
// 4. 分配顏色
$back_color = imagecolorallocate($im, 235, 236, 237); // 淺灰背景
$border_color = imagecolorallocate($im, 118, 151, 199); // 藍色邊框
$text_color = imagecolorallocate($im, mt_rand(0,200), mt_rand(0,120), mt_rand(0,120)); // 隨機文字色
// 5. 繪製基礎圖層
imagefilledrectangle($im, 0, 0, $width, $height, $back_color); // 填滿背景
imagerectangle($im, 0, 0, $width-1, $height-1, $border_color); // 繪製邊框
// 6. 干擾線(5 條隨機弧線)
for ($i = 0; $i < 5; $i++) {
$font_color = imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imagearc($im,
mt_rand(-$width, $width),
mt_rand(-$height, $height),
mt_rand(30, $width*2),
mt_rand(20, $height*2),
mt_rand(0,360), mt_rand(0,360),
$font_color
);
}
// 7. 干擾點(50 個隨機像素)
for ($i = 0; $i < 50; $i++) {
$font_color = imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imagesetpixel($im, mt_rand(0,$width), mt_rand(0,$height), $font_color);
}
// 8. 繪製驗證碼文字(使用 TrueType 字體)
@imagefttext($im, $size, 0, 5, $size+3, $text_color, 'c://WINDOWS//Fonts//simsun.ttc', $code);
// 9. 輸出圖片並釋放資源
header("Cache-Control: max-age=1, s-maxage=1, no-cache, must-revalidate");
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
}
?>
函式預設參數 $width=0, $height=0,若呼叫端未指定,會依據字元數 $num 與字體大小 $size 自動推算:
$num * $size * 4/5 + 5 —— 考量字元間距與左右留白$size + 10 —— 確保文字上下有足夠間距這樣設計讓函式既能「開箱即用」,又支援進階客製化。
$str 故意移除 0, 1, O, l, I 等易混淆字元,大幅降低使用者辨識錯誤率,這是生產環境的必備細節。
imagearc() 繪製隨機位置、大小、角度的弧線,比直線更難被 OCR 識別範例使用 Windows 路徑 c://WINDOWS//Fonts//simsun.ttc。實際部署至 Linux 伺服器時,需修改為系統實際字體路徑(如 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf),或將字體檔案隨專案佈建,以相對路徑載入,確保跨環境相容。
<?php
// 基本用法:4 字元、20px 字體
vCode(4, 20);
// 進階用法:6 字元、24px、寬 200px、高 50px
vCode(6, 24, 200, 50);
?>
$code 存入 $_SESSION['captcha'],驗證時比對並銷毀imagefttext() 的第 3 參數imagecreatefromjpeg() 載入紋理背景替代純色imagegif() 或啟用 OPcache 緩存編譯後的腳本這個 vCode() 函式雖精簡,卻涵蓋了驗證碼生成的完整流程:畫布建立、色彩管理、幾何繪圖、文字渲染、HTTP 標頭控制、資源釋放。掌握這些 GD 库核心函式,就能根據業務需求打造出安全性與使用體驗並重的專屬驗證碼系統。