首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 圖形驗證碼製作入門(上):隨機碼生成與 GD 庫基礎

     編輯:PHP 相關知識

前言

驗證碼是 Web 表單防機器人提交的基礎防線。本系列教學從零開始,帶你理解隨機碼生成策略、GD 圖形庫核心函數,並一步步實作完整的圖形驗證碼系統。本篇(上)聚焦隨機碼生成與 GD 基礎。

一、隨機驗證碼字串生成策略

核心函數:rand(int $min, int $max) 或 mt_rand()(更快、隨機性更好)。

策略 1:字元池 + 索引隨機

$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= $chars[mt_rand(0, strlen($chars) - 1)];
}
// 結果:如 "A7K2"

策略 2:ASCII 碼區間隨機(數字/大寫/小寫混合)

$code = '';
for ($i = 0; $i < 4; $i++) {
    $type = mt_rand(0, 2);
    switch ($type) {
        case 0: $ascii = mt_rand(48, 57);  break; // 0-9
        case 1: $ascii = mt_rand(65, 90);  break; // A-Z
        case 2: $ascii = mt_rand(97, 122); break; // a-z
    }
    $code .= chr($ascii);
}

策略 3:十六進位隨機(顏色值常用)

$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= dechex(mt_rand(0, 15)); // 0-9, a-f
}

策略 4:中文驗證碼(字元陣列隨機)

$chinese = ['我', '愛', '中', '國', '程', '式', '開', '發'];
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= $chinese[mt_rand(0, count($chinese) - 1)];
}
// 需配合 iconv 轉 UTF-8 給 imagettftext 使用
$code = iconv('GB2312', 'UTF-8', $code); // 若原檔為 GB2312

生成器封裝建議

class CaptchaGenerator {
    public static function generate($length = 4, $type = 'alphanum') {
        $pools = [
            'num'      => '0123456789',
            'alpha'    => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'alphanum' => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'mixed'    => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
            'hex'      => '0123456789abcdef',
        ];
        $pool = $pools[$type] ?? $pools['alphanum'];
        $code = '';
        $max = strlen($pool) - 1;
        for ($i = 0; $i < $length; $i++) {
            $code .= $pool[mt_rand(0, $max)];
        }
        return $code;
    }
}

// 使用
$code = CaptchaGenerator::generate(4, 'alphanum');

二、GD 庫啟用與核心函數

啟用 GD 擴展

; php.ini
extension=gd2          ; PHP 7.2+ 內建 GD,無需 dll
; extension=php_gd2.dll ; PHP 5.x Windows

驗證:php -m | grep gd 或 phpinfo() 查看 GD 區塊。

核心函數速查表

函數用途關鍵參數
imagecreatetruecolor()建立真彩色畫布寬、高(像素)
imagecolorallocate()分配顏色(回傳顏色標識)畫布資源、R、G、B (0-255)
imagefill()填充背景畫布、起始座標、顏色
imagestring()繪製內建字體字串畫布、字體(1-5)、x、y、字串、顏色
imagettftext()繪製 TrueType 字體字串畫布、大小、角度、x、y、顏色、字體檔、字串
imageline()繪製直線畫布、x1、y1、x2、y2、顏色
imagesetpixel()繪製單一像素點畫布、x、y、顏色
imagejpeg/png/gif()輸出圖片到瀏覽器/檔案畫布、[檔案路徑]、[品質]
imagedestroy()釋放畫布記憶體畫布資源

HTTP Header 設定(關鍵)

// 輸出 JPEG
header('Content-Type: image/jpeg');
imagejpeg($im);

// 輸出 PNG(支援透明)
header('Content-Type: image/png');
imagepng($im);

// 輸出 GIF
header('Content-Type: image/gif');
imagegif($im);

三、最簡驗證碼實作(數字版)

<?php
session_start();

// 1. 生成 4 位隨機碼
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= mt_rand(0, 9);
}
$_SESSION['captcha'] = $code; // 存入 Session 驗證用

// 2. 建立畫布 80x30
$im = imagecreatetruecolor(80, 30);

// 3. 分配顏色
$bg  = imagecolorallocate($im, 240, 240, 240); // 淺灰背景
$fg  = imagecolorallocate($im, 50, 50, 50);    // 深灰文字
$noise = imagecolorallocate($im, 180, 180, 180); // 干擾色

// 4. 填充背景
imagefill($im, 0, 0, $bg);

// 5. 繪製干擾點
for ($i = 0; $i < 50; $i++) {
    imagesetpixel($im, mt_rand(0, 79), mt_rand(0, 29), $noise);
}

// 6. 繪製干擾線
for ($i = 0; $i < 3; $i++) {
    imageline($im, 
        mt_rand(0, 79), mt_rand(0, 29),
        mt_rand(0, 79), mt_rand(0, 29),
        $noise
    );
}

// 7. 繪製驗證碼文字(內建字體,大小 5)
imagestring($im, 5, 15, 5, $code, $fg);

// 8. 輸出
header('Content-Type: image/jpeg');
imagejpeg($im);
imagedestroy($im);

四、前端整合範例

<form action="login.php" method="post">
  <img src="captcha.php" id="captchaImg" alt="驗證碼" style="vertical-align:middle; cursor:pointer" 
       onclick="this.src='captcha.php?'+Math.random()" title="點擊更換">
  <input type="text" name="captcha" maxlength="4" required>
  <button type="submit">登入</button>
</form>

五、常見問題與優化方向

問題原因解決/優化
圖片顯示「無法顯示」/ 破圖腳本有輸出(空白、BOM、錯誤訊息)ob_clean()、檔案無 BOM、錯誤導向日誌
字體顯示方塊/亂碼imagettftext 字體路徑錯誤/編碼不符絕對路徑、iconv 轉 UTF-8、字體檔存在
驗證碼太易被識別干擾不足、字體固定、無扭曲增加干擾線/點、使用 TTF 字體、隨機旋轉/縮放
Session 驗證失效Session 未啟動/域名不匹配/過期session_start() 最前、檢查 cookie 域、延長 gc_maxlifetime

下篇預告

下一篇將深入 **TTF 字體繪製、文字扭曲變形、進階干擾模式、Session 驗證邏輯封裝**,並封裝成可複用的 Captcha 類,敬請期待!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved