驗證碼生成是 PHP 基礎功能,不同專案需求不同。本文提供三個版本函數:簡易版(最少代碼)、Session 版(標準流程)、功能全版(參數化、雪花干擾、邊框、可配置長寬字元數),並對比優缺點供選型參考。
function code() {
$im = imagecreatetruecolor(100, 40);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $white);
$strarr = array_merge(range(0,9), range('a','z'), range('A','Z'));
shuffle($strarr);
$str = join(array_slice($strarr, 0, 4));
$color = imagecolorallocate($im, rand(0,40), rand(0,255), rand(0,255));
imagestring($im, 5, rand(0,40), 10, $str, $color);
// 700 雜訊點 + 3 條干擾線
for ($i=0; $i<700; $i++) {
$c = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($im, rand(0,100), rand(0,40), $c);
}
for ($t=0; $t<3; $t++) {
$c = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
imageline($im, rand(0,100), rand(0,40), rand(0,100), rand(0,40), $c);
}
header("Content-Type: image/png");
imagepng($im);
}
code();
優點:單一函數、無依賴、直接輸出。
缺點:無 Session 綁定、字元固定 4 位、無法複用參數。
function _code($len = 4, $width = 75, $height = 25) {
$code = '';
for ($i=0; $i<$len; $i++) $code .= dechex(mt_rand(0,15)); // 16 進位字元
$_SESSION["code"] = $code;
$img = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($img, 250, 250, 250);
imagefill($img, 0, 0, $white);
$gray = imagecolorallocate($img, 196, 196, 196);
imagerectangle($img, 0, 0, $width-1, $height-1, $gray);
// 6 條淡色干擾線
for ($i=0; $i<6; $i++) {
$c = imagecolorallocate($img, mt_rand(200,255), mt_rand(200,255), mt_rand(200,255));
imageline($img, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $c);
}
// 50 個星號干擾
for ($i=0; $i<50; $i++) {
$c = imagecolorallocate($img, mt_rand(200,255), mt_rand(200,255), mt_rand(200,255));
imagestring($img, 1, mt_rand(1,$width-5), mt_rand(1,$height-5), "*", $c);
}
// 繪製驗證碼字元
for ($i=0; $i<$len; $i++) {
$c = imagecolorallocate($img, mt_rand(0,102), mt_rand(0,102), mt_rand(0,102));
imagestring($img, 5, $i * $width/$len + mt_rand(1,10), mt_rand(1,$height/2), $code[$i], $c);
}
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
}
優點:參數化長寬長度、Session 自動綁定、邊框美觀。
缺點:字元集僅 0-9a-f、干擾模式固定。
/**
* @param int $width 畫布寬度,預設 80
* @param int $height 畫布高度,預設 25
* @param int $num 驗證碼字元數,預設 4
* @param int $line_num 干擾線條數,預設 10
* @param int $snow_num 雪花干擾數,預設 50
*/
function captcha($width = 80, $height = 25, $num = 4, $line_num = 10, $snow_num = 50) {
header('Content-Type: image/png');
session_start();
// 產生驗證碼(16 進位)
$code = '';
for ($a = 0; $a < $num; $a++) $code .= dechex(mt_rand(0, 15));
$_SESSION['captcha'] = $code;
$img = imagecreatetruecolor($width, $height);
$bg = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $bg);
// 黑色邊框
$border = imagecolorallocate($img, 0, 0, 0);
imagerectangle($img, 0, 0, $width-1, $height-1, $border);
// 隨機干擾線(淡色系)
for ($i=0; $i<$line_num; $i++) {
imageline($img,
mt_rand(0, $width*0.1), mt_rand(0, $height),
mt_rand($width*0.9, $width), mt_rand(0, $height),
imagecolorallocate($img, mt_rand(150,255), mt_rand(150,255), mt_rand(150,255))
);
}
// 隨機雪花(極淡色星號)
for ($i=0; $i<$snow_num; $i++) {
imagechar($img, 1,
mt_rand(0, $width), mt_rand(0, $height), '*',
imagecolorallocate($img, mt_rand(200,255), mt_rand(200,255), mt_rand(200,255))
);
}
// 繪製驗證碼字元(深色系,位置微隨機)
for ($b = 0; $b < strlen($_SESSION['captcha']); $b++) {
imagechar($img, 5,
$b * $width/$num + mt_rand(5,10), mt_rand(2, $height/2),
$_SESSION['captcha'][$b],
imagecolorallocate($img, mt_rand(10,150), mt_rand(10,150), mt_rand(0,100))
);
}
ob_clean(); // 清除可能的輸出緩衝
imagepng($img);
imagedestroy($img);
}
優點:五大參數全配置、雪花+干擾線雙重干擾、邊框、ob_clean 防輸出汙染、Session 鍵名固定 captcha。
適用場景:需根據頁面佈局調整尺寸、安全性要求較高的專案。
| 維度 | 簡易版 | Session 版 | 功能全版 |
|---|---|---|---|
| 代碼行數 | ~30 | ~45 | ~65 |
| 參數化 | 無 | 長寬長度 | 五大參數 |
| Session 綁定 | 無 | 自動 | 自動 (captcha) |
| 字元集 | 0-9a-zA-Z | 0-9a-f | 0-9a-f |
| 干擾模式 | 點+線 | 線+星號 | 線+雪花+邊框 |
| 推薦場景 | 原型/教學 | 標準專案 | 生產/高安全 |
<img src="captcha.php" id="captcha" onclick="this.src='captcha.php?v='+Date.now()" /> <input name="verify" placeholder="驗證碼" />
// 驗證邏輯
session_start();
if (strtolower($_POST['verify']) !== strtolower($_SESSION['captcha'])) {
exit('驗證碼錯誤');
}
三個版本由簡到繁,展示了驗證碼生成的核心要素:隨機字元、Session 綁定、畫布繪製、干擾干擾、輸出格式。理解原理後,建議生產環境直接引入成熟 Composer 套件,專注業務邏輯而非重複造輪子。