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

PHP 驗證碼類:自定 Session 路徑、干擾線/框、支援 JPEG/PNG 輸出

     編輯:PHP 相關知識

生產級驗證碼類別特色

  • 自定 Session 儲存路徑:避開預設 /tmp,適合共享主機或叢集環境。
  • 智慧重用:5 秒內重複請求回傳同一張圖,減少運算。
  • 豐富干擾:橫線、斜線、邊框、雜訊像素。
  • 雙格式輸出:優先 JPEG,不支援則 fallback PNG。

完整類別代碼

<?php
// 1. 設定 Session 儲存路徑(需可讀寫)
$sessPath = dirname(__FILE__) . '/../data/sessions/';
if (is_writable($sessPath) && is_readable($sessPath)) {
    session_save_path($sessPath);
}
session_start();

class Captcha {
    private $im;
    public function generate() {
        // 5 秒內不重新生成
        $now = time();
        if (empty($_SESSION['verifycode']) || empty($_SESSION['verifycode_last']) ||
            $now - $_SESSION['verifycode_last'] > 5) {
            $code = '';
            for ($i=0;$i<4;$i++) $code .= chr(mt_rand(65,90)); // A-Z
            $_SESSION['verifycode'] = strtolower($code);
            $_SESSION['verifycode_last'] = $now;
        }
        $code = $_SESSION['verifycode'];
        $len = strlen($code);

        // 建立畫布
        $this->im = imagecreate(50, 20);
        imagecolorallocate($this->im, 255,255,255); // 白底(第一個顏色為背景)
        $line1 = imagecolorallocate($this->im, 240,220,180);
        $line2 = imagecolorallocate($this->im, 250,250,170);

        // 橫向干擾線
        for ($y=3;$y<=16;$y+=3) imageline($this->im, 2,$y, 48,$y, $line1);
        // 斜向干擾線
        for ($x=2;$x<52;$x+=mt_rand(3,6)) imageline($this->im, $x,2, $x-6,18, $line2);

        // 邊框
        $border = imagecolorallocate($this->im, 0x99,0x99,0x99);
        imagerectangle($this->im, 0,0, 49,19, $border);

        // 文字
        $fontColor = imagecolorallocate($this->im, 48,61,50);
        for ($i=0;$i<$len;$i++) {
            $ch = strtoupper($code[$i]);
            imagestring($this->im, 5, $i*10+6, mt_rand(2,4), $ch, $fontColor);
        }

        // 輸出
        header("Pragma: no-cache");
        header("Cache-Control: no-cache");
        header("Expires: 0");
        if (function_exists('imagejpeg')) {
            header("Content-Type: image/jpeg");
            imagejpeg($this->im);
        } else {
            header("Content-Type: image/png");
            imagepng($this->im);
        }
        imagedestroy($this->im);
        exit;
    }
}

// 直接輸出
(new Captcha())->generate();
?>

前端整合

<img src="captcha.php" id="captcha" onclick="this.src='captcha.php?'+Date.now()" style="cursor:pointer">
<input name="captcha" maxlength="4" placeholder="輸入字母">

後端驗證

<?php
session_start();
if (strtolower($_POST['captcha']) === ($_SESSION['verifycode'] ?? '')) {
    echo "通過";
    unset($_SESSION['verifycode'], $_SESSION['verifycode_last']);
} else {
    echo "錯誤";
}
?>

遷移至真彩色 + TTF 版本(建議)

<?php
// 替換 imagecreate → imagecreatetruecolor
// 替換 imagestring → imagettftext
$im = imagecreatetruecolor(100, 35);
$font = __DIR__.'/fonts/arial.ttf';
for ($i=0;$i<4;$i++) {
    $color = imagecolorallocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
    imagettftext($im, 20, mt_rand(-15,15), $i*22+10, 25, $color, $font, $code[$i]);
}
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved