最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用PHP創(chuàng)建圖像驗證碼的示例代碼

 更新時間:2026年04月01日 09:19:02   作者:我叫黑大帥  
PHP?圖像驗證碼的實現(xiàn)完全基于GD?庫,它是?PHP?官方內(nèi)置的圖像處理擴展,提供了畫布創(chuàng)建、顏色分配、文本繪制、圖形渲染、圖片輸出等全能力,下面小編就和大家詳細介紹一下具體如何實現(xiàn)的吧

PHP 圖像驗證碼的實現(xiàn)完全基于GD 庫,它是 PHP 官方內(nèi)置的圖像處理擴展,提供了畫布創(chuàng)建、顏色分配、文本繪制、圖形渲染、圖片輸出等全能力,是 PHP 圖像處理的行業(yè)標準方案。

開啟 GD 擴展

  • Windows 環(huán)境:打開php.ini,去掉extension=gd前的分號注釋,重啟 Web 服務(wù)(Apache/Nginx/PHP-FPM)
  • Linux 環(huán)境:編譯 PHP 時添加--with-gd參數(shù),或通過包管理器安裝php-gd擴展(如yum install php-gd/apt install php-gd),重啟服務(wù)生效

生成驗證碼

第一步:開啟Session與配置

<?php
// 開啟Session,用于存儲驗證碼校驗值(必須在輸出前執(zhí)行,無任何前置空格)
session_start();
// 引入驗證碼配置
$captchaConfig = [
    // 基礎(chǔ)尺寸配置
    'width'       => 150,         // 驗證碼圖片寬度
    'height'      => 50,          // 驗證碼圖片高度
    // 字符配置
    'length'      => 4,           // 驗證碼字符長度,常用4-6位
    'charset'     => '23456789ABCDEFGHJKLMNPQRSTUVWXYZ', // 字符集:去掉易混淆的0/O、1/l,提升用戶體驗
    'font_size'   => 24,          // 字體字號
    'font_file'   => './fonts/arial.ttf', // TTF字體文件路徑,必須填寫正確,否則無法繪制文字
    // 干擾項配置(平衡安全性與識別度)
    'line_num'    => 6,           // 干擾線數(shù)量
    'pixel_num'   => 100,         // 噪點數(shù)量
    // 安全配置
    'expire'      => 300,         // 驗證碼有效期,單位秒,默認5分鐘
    'session_key' => 'captcha_code', // Session存儲的key
];

第二步:創(chuàng)建畫布+分配基礎(chǔ)顏色

// 創(chuàng)建真彩色畫布
$img = imagecreatetruecolor($captchaConfig['width'], $captchaConfig['height']);
// 分配背景色:淺色系背景,提升文字辨識度(240-255區(qū)間)
$bgColor = imagecolorallocate($img, 245, 245, 245);
// 分配文字顏色:深色系,隨機生成避免固定色值被OCR識別
$textColor = imagecolorallocate($img, rand(10, 50), rand(10, 50), rand(10, 50));
// 填充畫布背景
imagefill($img, 0, 0, $bgColor);
API 函數(shù)核心作用
imagecreatetruecolor(int $width, int $height)創(chuàng)建真彩色的圖像畫布,是驗證碼的載體
imagecolorallocate(resource $image, int $red, int $green, int $blue)為畫布分配 RGB 顏色,用于背景、文字、干擾項繪制
imagefill(resource $image, int $x, int $y, int $color)為畫布填充背景色,從坐標 (x,y) 開始填充

第三步:生成隨機驗證碼字符串

$code = '';
$charsetLen = strlen($captchaConfig['charset']);
for ($i = 0; $i < $captchaConfig['length']; $i++) {
    // 從字符集中隨機取一個字符,拼接成最終驗證碼
    $code .= $captchaConfig['charset'][rand(0, $charsetLen - 1)];
}

第四步:繪制干擾元素(先畫干擾項,再畫文字,避免文字被遮擋)

// 繪制隨機干擾線
for ($i = 0; $i < $captchaConfig['line_num']; $i++) {
    // 隨機生成線條顏色(淺色系,不搶文字視覺)
    $lineColor = imagecolorallocate($img, rand(100, 200), rand(100, 200), rand(100, 200));
    // 隨機生成線條起點和終點,貫穿整個畫布
    imageline(
        $img,
        rand(0, $captchaConfig['width']),
        rand(0, $captchaConfig['height']),
        rand(0, $captchaConfig['width']),
        rand(0, $captchaConfig['height']),
        $lineColor
    );
}
// 繪制隨機噪點
for ($i = 0; $i < $captchaConfig['pixel_num']; $i++) {
    // 隨機生成噪點顏色
    $pixelColor = imagecolorallocate($img, rand(50, 150), rand(50, 150), rand(50, 150));
    // 隨機生成噪點位置
    imagesetpixel($img, rand(0, $captchaConfig['width']), rand(0, $captchaConfig['height']), $pixelColor);
}
  • imageline(resource $image, int $x1, int $y1, int $x2, int $y2, int $color) 繪制直線,多用于添加干擾線,增加機器自動識別難度
  • imagesetpixel(resource $image, int $x, int $y, int $color)繪制單個像素點,用來生成噪點干擾,強化驗證碼防破解效果

第五步:繪制驗證碼字符到畫布

// 計算單個字符的寬度,均勻分布在畫布上
$singleWidth = $captchaConfig['width'] / $captchaConfig['length'];
for ($i = 0; $i < $captchaConfig['length']; $i++) {
    // 每個字符隨機旋轉(zhuǎn)-10到10度,防止機器識別
    $angle = rand(-10, 10);
    // 計算字符的x坐標,左右留邊距,均勻分布
    $x = $singleWidth * $i + rand(5, 10);
    // 計算字符的y坐標,垂直居中(基線對齊,避免文字下沉)
    $y = $captchaConfig['height'] / 2 + $captchaConfig['font_size'] / 3;
    // 寫入單個字符到畫布
    imagettftext(
        $img,
        $captchaConfig['font_size'],
        $angle,
        $x,
        $y,
        $textColor,
        $captchaConfig['font_file'],
        $code[$i]
    );
}

imagettftext(resource $image, float $size, float $angle, int $x, int $y, int $color, string $font_file, string $text)寫入 TrueType 字體文本,是繪制驗證碼字符的核心,支持自定義字體、字號、文字旋轉(zhuǎn)角度

第六步:存儲驗證碼到Session,完成服務(wù)端持久化

// 存儲加密后的驗證碼+過期時間,生產(chǎn)環(huán)境建議加密存儲,避免Session泄露
$_SESSION[$captchaConfig['session_key']] = [
    'code' => strtolower($code), // 轉(zhuǎn)小寫,實現(xiàn)不區(qū)分大小寫校驗,提升用戶體驗
    'expire_time' => time() + $captchaConfig['expire'] // 過期時間戳
];

第七步:輸出圖片到瀏覽器

// 聲明響應(yīng)頭為PNG圖片,禁止瀏覽器緩存
header('Content-Type: image/png');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
// 輸出圖片
imagepng($img);
// 銷毀畫布資源,釋放內(nèi)存
imagedestroy($img);
  • imagepng(resource $image) 以 PNG 格式輸出圖像,可直接推送到瀏覽器,也能保存為圖片文件
  • imagedestroy(resource $image) 銷毀畫布圖像資源,釋放服務(wù)器內(nèi)存,是代碼收尾必備操作
  • header(string $header) 設(shè)置 HTTP 響應(yīng)頭,告知瀏覽器返回內(nèi)容為圖片格式,避免頁面出現(xiàn)亂碼

校驗驗證碼

<?php
// 1. 開啟Session,與生成端保持一致
session_start();
// 2. 配置項,必須與生成端保持一致
$captchaConfig = [
    'session_key' => 'captcha_code',
];
// 3. 封裝校驗函數(shù),可全局復(fù)用
function checkCaptcha(string $userInput): array
{
    global $captchaConfig;
    // 3.1 先判斷用戶是否輸入了驗證碼
    if (empty($userInput)) {
        return ['status' => false, 'msg' => '請輸入驗證碼'];
    }
    // 3.2 判斷服務(wù)端是否存在驗證碼Session
    if (!isset($_SESSION[$captchaConfig['session_key']])) {
        return ['status' => false, 'msg' => '驗證碼已過期,請刷新重試'];
    }
    // 3.3 取出Session中的驗證碼數(shù)據(jù)
    $captchaData = $_SESSION[$captchaConfig['session_key']];
    // 3.4 校驗驗證碼是否過期
    if (time() > $captchaData['expire_time']) {
        // 過期后立即銷毀,防止復(fù)用
        unset($_SESSION[$captchaConfig['session_key']]);
        return ['status' => false, 'msg' => '驗證碼已過期,請刷新重試'];
    }
    // 3.5 校驗驗證碼是否正確(統(tǒng)一轉(zhuǎn)小寫,不區(qū)分大小寫)
    if (strtolower(trim($userInput)) !== $captchaData['code']) {
        // 校驗失敗立即銷毀,防止破解
        unset($_SESSION[$captchaConfig['session_key']]);
        return ['status' => false, 'msg' => '驗證碼錯誤,請刷新重試'];
    }
    // 3.6 校驗成功,立即銷毀當(dāng)前驗證碼,防止重放攻擊(單次有效)
    unset($_SESSION[$captchaConfig['session_key']]);
    return ['status' => true, 'msg' => '驗證碼校驗通過'];
}
// 4. 調(diào)用示例(用戶POST提交表單時)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 獲取用戶輸入的驗證碼
    $userCaptcha = $_POST['captcha'] ?? '';
    // 執(zhí)行校驗
    $checkResult = checkCaptcha($userCaptcha);
    if (!$checkResult['status']) {
        // 校驗失敗,返回錯誤信息
        echo json_encode(['code' => 400, 'msg' => $checkResult['msg']]);
        exit;
    }
    // 校驗通過,執(zhí)行后續(xù)業(yè)務(wù)邏輯(登錄、注冊、發(fā)送短信等)
    echo json_encode(['code' => 200, 'msg' => '操作成功']);
    exit;
}

生產(chǎn)環(huán)境注意事項與安全規(guī)范

必須使用 HTTPS 傳輸:驗證碼接口和表單提交接口必須通過 HTTPS 傳輸,防止中間人竊取驗證碼圖片和提交內(nèi)容,規(guī)避重放攻擊。

驗證碼存儲安全

  • 生產(chǎn)環(huán)境嚴禁將驗證碼原始字符串返回給前端,必須僅存儲在服務(wù)端 Session/Redis 中;
  • 高并發(fā)場景建議使用 Redis 存儲驗證碼,替代原生 Session,提升性能和分布式系統(tǒng)兼容性;
  • 建議對存儲的驗證碼進行不可逆加密,避免 Session/Redis 泄露導(dǎo)致驗證碼被破解。

用戶體驗與安全平衡

  • 字符集必須剔除易混淆的0和O1和l、2和Z等字符,減少用戶輸入錯誤;
  • 干擾線和噪點數(shù)量需合理,避免過度干擾導(dǎo)致用戶無法識別;
  • 必須實現(xiàn)不區(qū)分大小寫校驗,降低用戶輸入門檻。

防破解規(guī)范

  • 驗證碼必須單次有效,無論校驗成功或失敗,立即銷毀,禁止重復(fù)使用;
  • 同一 IP 短時間內(nèi)多次獲取驗證碼,需進行頻率限制,防止驗證碼被批量抓取;
  • 校驗失敗 3 次以上,必須強制刷新驗證碼,避免暴力枚舉。

字體與資源規(guī)范

  • 必須使用開源免費字體,避免商用字體導(dǎo)致的版權(quán)風(fēng)險;
  • 建議使用多種字體隨機切換,每個字符使用不同字體,大幅提升 OCR 識別難度;
  • 字體文件路徑建議使用絕對路徑,避免相對路徑導(dǎo)致的繪制失敗。

輸出規(guī)范

  • 必須設(shè)置禁止緩存的響應(yīng)頭,防止瀏覽器、CDN 緩存驗證碼圖片,導(dǎo)致校驗失敗;
  • 輸出圖片前必須清空輸出緩沖區(qū),避免框架輸出的多余內(nèi)容導(dǎo)致圖片亂碼;
  • 圖片輸出后必須執(zhí)行imagedestroy()銷毀畫布資源,避免服務(wù)器內(nèi)存泄漏。

嚴禁存儲敏感信息:驗證碼僅用于人機校驗,禁止在其中嵌入用戶 ID、密碼等敏感信息。

到此這篇關(guān)于使用PHP創(chuàng)建圖像驗證碼的示例代碼的文章就介紹到這了,更多相關(guān)PHP圖像驗證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

古蔺县| 承德市| 五华县| 泸西县| 礼泉县| 乌鲁木齐县| 隆德县| 焉耆| 定结县| 仲巴县| 潼南县| 信阳市| 上饶县| 冀州市| 六盘水市| 怀集县| 浦城县| 神池县| 开江县| 大洼县| 兴业县| 读书| 许昌县| 万全县| 鄂州市| 奈曼旗| 安丘市| 托克逊县| 随州市| 绥德县| 南阳市| 长寿区| 安国市| 太康县| 洱源县| 常熟市| 武城县| 康乐县| 兴化市| 当涂县| 威信县|