本文提供一個可直接用於 CodeIgniter 3.x 專案的驗證碼類別,支援自訂寬高、位數、字元集、干擾線/點,並示範控制器調用、Session 儲存、前端 HTML/JS 整合與「換一張」功能。
Lib_captcha.php放置於 application/libraries/Lib_captcha.php:
<?php
class Lib_captcha {
var $width = '60';
var $num = '4';
var $height = '20';
var $name = 'randcode';
public function __construct($conf = "") {
if ($conf != "") {
foreach ($conf as $key => $value) {
$this->$key = $value;
}
}
}
function show() {
header("Content-type: image/gif");
$border = 0; // 1=顯示邊框
$how = $this->num; // 驗證碼位數
$w = $this->width;
$h = $this->height;
$fontsize = 5; // GD 內建字體 1~5
$alpha = "abcdefghijkmnopqrstuvwxyz"; // 排除 l, o 避免混淆
$number = "023456789"; // 排除 1
$randcode = "";
srand((double)microtime() * 1000000);
$im = imagecreate($w, $h);
// 背景
$bgcolor = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $bgcolor);
if ($border) {
$black = imagecolorallocate($im, 0, 0, 0);
imagerectangle($im, 0, 0, $w-1, $h-1, $black);
}
// 逐字繪製
for ($i = 0; $i < $how; $i++) {
$alpha_or_number = mt_rand(0, 1);
$str = $alpha_or_number ? $alpha : $number;
$which = mt_rand(0, strlen($str)-1);
$code = substr($str, $which, 1);
$j = !$i ? 4 : $j + 15; // 字元水平間距
$color = imagecolorallocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
imagechar($im, $fontsize, $j, 3, $code, $color);
$randcode .= $code;
}
// 干擾線
for ($i = 0; $i < 5; $i++) {
$color = imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imagearc($im, mt_rand(-5,$w), mt_rand(-5,$h), mt_rand(20,300), mt_rand(20,200), 55, 44, $color);
}
// 干擾點
for ($i = 0; $i < $how * 15; $i++) {
$color = imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imagesetpixel($im, mt_rand(0,$w), mt_rand(0,$h), $color);
}
// 存入 Session
$_SESSION[$this->name] = $randcode;
imagegif($im);
imagedestroy($im);
}
}
?>
User.php<?php
class User extends CI_Controller {
public function verify_image() {
$conf['name'] = 'verify_code'; // Session 鍵名
$this->load->library('lib_captcha', $conf);
$this->lib_captcha->show();
// 除錯用:顯示 Session 值(正式環境請移除)
// $yzm = $this->session->userdata('verify_code');
// echo $yzm;
}
}
?>
<dl>
<dt>驗證碼:</dt>
<dd>
<input type="text" name="verify_text" id="verify_text" class="yzma" value="">
<img src="/user/verify_image" alt="驗證碼" id="verify_code" class="yz_img" />
<a href="javascript:changeCode();" class="change_yz">換一張</a>
</dd>
<dd class="tips_wrong"><b>驗證碼不正確</b></dd>
<dd class="tips_correct"></dd>
</dl>
<script type="text/javascript">
function changeCode() {
// 加入隨機參數防止瀏覽器快取
document.getElementById("verify_code").src = "/user/verify_image?r=" + Math.random();
}
</script>
<?php
public function login() {
$input_code = $this->input->post('verify_text');
$sess_code = $this->session->userdata('verify_code');
if (strtolower($input_code) !== strtolower($sess_code)) {
$this->form_validation->set_message('verify_check', '驗證碼錯誤');
return false;
}
return true;
}
?>
imagechar 改為 imagettftext,載入自訂字體檔,提升辨識難度。$this->name = 'captcha_' . $form_id。| 現象 | 可能原因 | 解決 |
|---|---|---|
| 圖片顯示破圖/無輸出 | GD 未安裝、輸出前有空白/BOM、header 已送出 | 檢查 phpinfo() gd 支援、確保類別檔無結尾 ?>、ob_start() |
| Session 讀不到值 | session 未啟動、名稱不符、Cookie domain 設定錯誤 | config.php 設定 sess_driver、sess_cookie_name、確認 domain |
| 換一張無反應 | JS 錯誤、圖片快取、路徑錯誤 | 檢查 Console、確認隨機參數生效、網路面板看請求 |