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

PHP 圖形驗證碼完整實作:GD 庫生成、Session 驗證與前端整合

     編輯:PHP 綜合知識

前言

圖形驗證碼(CAPTCHA)是防止機器人惡意提交的經典方案。本文基於 PHP GD 庫,完整示範驗證碼圖片生成(干擾點、干擾線、隨機字元)、Session 儲存驗證碼、前端表單整合與「換一張」無刷新重載功能,程式碼可直接用於專案。

一、驗證碼圖片生成 captcha.php

<?php
session_start();

// 1. 建立 100x30 真彩色畫布
$image = imagecreatetruecolor(100, 30);

// 2. 白色背景
$bgcolor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $bgcolor);

// 3. 產生 4 位隨機字元
$captcha_code = "";
$charset = "abcdefghijkmnpqrstuvwxy3456789"; // 排除易混淆字元 o,0,1,l,i,2
for ($i = 0; $i < 4; $i++) {
    $fontsize = 6; // 內建字體 1-5,6 為較大
    $fontcolor = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120)); // 深色系
    $char = $charset[rand(0, strlen($charset) - 1)];
    $captcha_code .= $char;
    
    // 隨機位置
    $x = ($i * 100 / 4) + rand(5, 10);
    $y = rand(5, 10);
    imagestring($image, $fontsize, $x, $y, $char, $fontcolor);
}

// 4. 儲存至 Session(轉小寫比對不區分大小寫)
$_SESSION["authcode"] = strtolower($captcha_code);

// 5. 干擾點(100 個)
for ($i = 0; $i < 100; $i++) {
    $pointcolor = imagecolorallocate($image, rand(50, 200), rand(50, 200), rand(50, 200));
    imagesetpixel($image, rand(1, 99), rand(1, 29), $pointcolor);
}

// 6. 干擾線(2 條)
for ($i = 0; $i < 2; $i++) {
    $linecolor = imagecolorallocate($image, rand(80, 220), rand(80, 220), rand(80, 220));
    imageline($image, rand(1, 99), rand(1, 29), rand(1, 99), rand(1, 29), $linecolor);
}

// 7. 輸出 PNG
header("Content-Type: image/png");
imagepng($image);
imagedestroy($image);
?>

關鍵技術點

  • 字元集優化:移除 o,0,1,l,i,2 等易混淆字元
  • 色彩分層:背景白、字元深色、干擾中間色,保證可讀性
  • Session 儲存:驗證碼存入 $_SESSION['authcode'],驗證時比對
  • 資源釋放:imagedestroy() 防止記憶體洩漏

二、前端表單與驗證 form.php

<?php
session_start();

if (isset($_POST["authcode"])) {
    $input = strtolower(trim($_POST["authcode"]));
    $stored = $_SESSION["authcode"] ?? '';
    
    if ($input === $stored) {
        echo "OK - 驗證通過";
        // 清除驗證碼防重放
        unset($_SESSION["authcode"]);
    } else {
        echo "NO - 驗證碼錯誤";
    }
    exit;
}
?>
<!doctype html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <title>驗證碼測試</title>
    <style>
        .captcha-img { border: 1px solid #ccc; vertical-align: middle; cursor: pointer; }
        .refresh-link { margin-left: 10px; vertical-align: middle; }
    </style>
</head>
<body>
    <form action="form.php" method="post">
        <p>
            驗證碼圖片: 
            <img id="captchaImg" class="captcha-img" src="captcha.php?r=<?php echo rand(); ?>" alt="驗證碼">
            <a href="javascript:void(0)" class="refresh-link" id="refreshCaptcha">換一張</a>
        </p>
        <p><input type="text" name="authcode" placeholder="請輸入驗證碼" autocomplete="off"></p>
        <p><input type="submit" value="提交"></p>
    </form>

    <script>
        document.getElementById('refreshCaptcha').onclick = function() {
            document.getElementById('captchaImg').src = 'captcha.php?r=' + Math.random();
        };
        // 點擊圖片也可重載
        document.getElementById('captchaImg').onclick = function() {
            this.src = 'captcha.php?r=' + Math.random();
        };
    </script>
</body>
</html>

前端優化細節

  • 隨機參數:?r=... 破除瀏覽器快取,確保每次請求新圖片
  • 雙重觸發:點擊「換一張」連結或點擊圖片本身均可重載
  • autocomplete="off":防止瀏覽器自動填入舊驗證碼
  • 大小寫不敏感:前後端統一 strtolower() 比對,提升用戶體驗

三、進階增強方向

  1. TTF 字體:使用 imagettftext() + 自訂字體檔,字體更豐富、更難被 OCR 識別
  2. 幾何扭曲:imageaffine() 仿射變換,增加機器識別難度
  3. 中文驗證碼:字元集改為常用漢字,配合 TTF 字體
  4. 點選/滑塊驗證:前端 Canvas 實作,體驗更佳,安全性更高
  5. 第三方服務:Google reCAPTCHA v3、Geetest 等無感驗證

四、常見問題排查

現象原因解決
圖片顯示破圖GD 未安裝/啟用php -m | grep gd,安裝 php-gd
Session 失效session_start() 位置錯誤確保輸出前調用,無 BOM、無空白輸出
驗證總是失敗大小寫/空白差異雙方統一 strtolower(trim())
中文亂碼字體不支援中文使用支援中文的 TTF 字體

五、結語

PHP GD 庫提供了完整的圖形繪製能力,結合 Session 機制即可實作基礎驗證碼。本文範例涵蓋生成、驗證、前端整合全流程,並提供進階優化方向。實務中建議根據業務風險等級選擇:低風險用簡單 GD 驗證碼,中高風險接入成熟第三方服務,兼顧安全與用戶體驗。

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