check() 驗證方法。<?php
class Captcha {
private $sname;
public function __construct($sname = '') {
$this->sname = $sname ?: 'm_captcha';
}
public function create($length = 4, array $param = []) {
header('Content-Type: image/png');
$code = $this->random($length);
$this->captcha_session($this->sname, $code);
$w = $param['width'] ?? 13;
$h = $param['height'] ?? 18;
$pnum = $param['pnum'] ?? 100;
$lnum = $param['lnum'] ?? 2;
$imgW = $w * $length + 10;
$imgH = $h + 6;
$im = imagecreate($imgW, $imgH);
$bg = imagecolorallocate($im, 238, 238, 238);
// 隨機多邊形背景
$pts = [];
for ($i=0;$i<12;$i++) $pts[] = mt_rand(0, $imgW);
imagefilledpolygon($im, $pts, 6, imagecolorallocate($im, mt_rand(170,255), mt_rand(200,255), mt_rand(210,255)));
// 繪製字元
for ($i=0;$i<$length;$i++) {
$color = imagecolorallocate($im, mt_rand(0,50), mt_rand(0,150), mt_rand(0,200));
$x = $i/$length * $imgW + rand(1,6);
$y = rand(1, $imgH/3);
imagestring($im, mt_rand(4,6), $x, $y, $code[$i], $color);
}
// 干擾像素
for ($i=0;$i<$pnum;$i++) {
imagesetpixel($im, mt_rand(0,$imgW), mt_rand(0,$imgH), imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255)));
}
// 干擾線
for ($i=0;$i<$lnum;$i++) {
imageline($im, mt_rand(0,$imgW), mt_rand(0,$imgH), mt_rand(0,$imgW), mt_rand(0,$imgH), imagecolorallocate($im, mt_rand(50,255), mt_rand(150,255), mt_rand(200,255)));
}
imagepng($im);
imagedestroy($im);
}
public function check($input, $sname = '') {
$sname = $sname ?: $this->sname;
session_start();
$stored = $_SESSION[$sname] ?? '';
unset($_SESSION[$sname]); // 一次性驗證碼
return strtoupper($input) === strtoupper($stored);
}
private function random($len) {
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // 排除易混淆字元
$str = '';
for ($i=0;$i<$len;$i++) $str .= $chars[mt_rand(0, strlen($chars)-1)];
return $str;
}
private function captcha_session($name, $value) {
session_start();
$_SESSION[$name] = $value;
}
}
<?php
require 'Captcha.class.php';
$captcha = new Captcha();
$captcha->create(4, ['width'=>15, 'height'=>22, 'pnum'=>80, 'lnum'=>3]);
<form method="post">
<img src="captcha.php" onclick="this.src='captcha.php?'+Math.random()" />
<input name="captcha" required />
<button type="submit">送出</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$captcha = new Captcha();
if ($captcha->check($_POST['captcha'])) {
echo "驗證通過";
} else {
echo "驗證碼錯誤";
}
}
unset,防止重放攻擊。imagettftext + TTF 字體或第三方服務。Captcha 類別以原生 GD 實現經典驗證碼功能,代碼精簡易懂,適合教學與低風險表單保護。生產環境面對自動化攻擊建議接入成熟驗證碼服務,兼顧安全性與用戶體驗。