工作生活

用 PHP 生成驗證碼的辦法及範例

2019-06-29  本文已影响0人  麥丹慈

辦法

若不考慮援用第三方拓展,則參見圖像生成與處理的說明以選取適當的函式庫來完成即可。其中以借用 Graphics Draw 的實現爲經典,但使用時仍需注意 PHP、GD 及相關組件的版次。

在 Windows 上要使用 GD 庫,須依次序載入以下三個以動態鏈接庫形態存在的擴展:

另外 php.ini 中亦需注意 memory_limit 設定是否恰當。

範例

需求

利用 GD 生成隨機驗證碼:建立一尺寸爲 120 * 25 px^2 的畫布並在其上散佈 50 個綠色的隨機干擾畫素點,且驗證碼有且僅有 5 個字符,字符僅能由大寫英文字母同阿拉伯數字組成,且各字符之色彩可不同。

分析

每次生成驗證碼都要完成的確定的步驟:

  1. 建立指定尺寸的畫布;
  2. 散佈干擾畫素;
    每次生成都要完成但可配置的步驟:指定具體生成的驗證碼,可考慮作爲參數傳入。

範例原始碼

<?php
const
X = 0,
Y = 1,
WIDTH = 0,
HEIGHT = 1;

function random_colour_val()
{
    return mt_rand(0, 127);
}

/**
 * Generate verification code image.
 * @param $code array Verification code
 */
function img_code_verif_gen($code = 0, $charCount = 5)
{
    // Code process
    if (is_string($code)) {
        if (mb_strlen($code) != $charCount) {
            throw new Exception('Code string length is not equal to character count ' . $charCount);
        }
    } elseif (is_numeric($code)) {
        $code = str_pad($code, $charCount, '0', STR_PAD_LEFT);
    }

    // Initialize the image handle
    $imgSize = [
        WIDTH => 120,
        HEIGHT => 25,
    ];
    $img = imagecreate($imgSize[WIDTH], $imgSize[HEIGHT]);

    imagecolorallocate($img, 255, 255, 255); // The first colour in the image is as backound colour. White.
    $colourDot = imagecolorallocate($img, 63, 255, 63); // Green

    // 散佈干擾畫素,或會重複
    for ($i = 0; $i < 50; $i++) {
        imagesetpixel($img, mt_rand(0, $imgSize[WIDTH] - 1), mt_rand(0, $imgSize[HEIGHT] - 1), $colourDot);
    }

    // Set characters
    for ($i = 0; $i < $charCount; $i++) {
        // Using random location
        $location = [
            X => mt_rand(0, 8) + ($imgSize[WIDTH] / $charCount) * $i,
            Y => mt_rand(0, $imgSize[HEIGHT] / 3),
        ];

        $colourChar = imagecolorallocate($img, random_colour_val(), random_colour_val(), random_colour_val()); // Set random colour within dark colour set

        imagestring($img, 4, $location[X], $location[Y], $code[$i], $colourChar); // Insert characters
    }

    // Output directly
    header('content-type: image/png');
    imagepng($img);
    imagedestroy($img);
}

function main()
{
    $charCount = 5;
    $charSet = array_merge(range(0, 9), range('A', 'Z'));
    $charOffsetMax = count($charSet) - 1;

    $code = [];
    for ($i = 0; $i < $charCount; $i++) {
        $code[$i] = $charSet[mt_rand(0, $charOffsetMax)];
    }

    img_code_verif_gen($code, $charCount); // Build the code
}

main();

執行

利用 PHP 內建之 web 伺服器 php -S 即可體驗。

上一篇 下一篇

猜你喜欢

热点阅读