PHP code example of watsonhaw / think-captcha

1. Go to this page and download the library: Download watsonhaw/think-captcha library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

watsonhaw / think-captcha example snippets



namespace app\controller;

use think\captcha\CaptchaService;
use think\Request;
use think\Response;

class Captcha
{
    /**
     * 获取验证码
     * GET  /api/captcha
     *      /api/captcha/:scene   (scene 对应 config 子配置,如 login / register)
     */
    public function index(Request $request, ?string $scene = null): Response
    {
        return json([
            'code' => 1,
            'msg'  => 'success',
            'data' => CaptchaService::generate($scene),
            // data:
            //   key    : 唯一标识,提交校验时原样带回
            //   img    : data:image/png;base64,...  直接丢给 <img :src>
            //   expire : 有效秒数
        ])->header([
            'Access-Control-Allow-Origin'      => $request->header('origin', '*'),
            'Access-Control-Allow-Credentials' => 'true',
        ]);
    }

    /**
     * 校验验证码(独立接口;更多时候你会把校验直接写在 login/register 里)
     * POST /api/captcha/check
     * body: { key: "...", captcha: "a3b9" }
     */
    public function check(Request $request): Response
    {
        $ok = CaptchaService::validate(
            (string)$request->param('key'),
            (string)$request->param('captcha')
        );
        return json([
            'code' => $ok ? 1 : 0,
            'msg'  => $ok ? 'ok' : '验证码错误或已过期',
        ]);
    }

    /**
     * 刷新验证码(可选:传旧 key 立即失效)
     * GET /api/captcha/refresh?key=xxx
     */
    public function refresh(Request $request, ?string $scene = null): Response
    {
        $old = (string)$request->param('key');
        if ($old !== '') CaptchaService::remove($old);
        return json(['code' => 1, 'data' => CaptchaService::generate($scene)]);
    }
}

public function login(Request $request)
{
    $key     = (string)$request->post('key');
    $captcha = (string)$request->post('captcha');
    $account = (string)$request->post('account');
    $pass    = (string)$request->post('password');

    // ⬇ 先校验验证码
    if (!CaptchaService::validate($key, $captcha)) {
        return json(['code' => 0, 'msg' => '验证码错误或已过期']);
    }

    // 再校验账号密码...
}

use think\captcha\CaptchaService;

$data = CaptchaService::generate();            // 生成
$ok   = CaptchaService::validate($key, $code); // 校验
CaptchaService::remove($key);                  // 删除

use think\captcha\facade\Captcha;

$data = Captcha::generate('login');
$ok   = Captcha::validate($key, $code);
Captcha::remove($key);

$data = captcha_generate('register');          // 生成
$ok   = captcha_validate($key, $userInput);    // 校验
captcha_remove($key);                          // 删除


namespace app\controller;

use think\captcha\Captcha;
use think\Request;
use think\Response;

class Login
{
    // 直接输出验证码图片
    public function captcha(Captcha $captcha, ?string $config = null): Response
    {
        return $captcha->create($config);  // 返回 image/png Response
    }

    // 校验
    public function check(Captcha $captcha, Request $request): bool
    {
        return $captcha->check((string)$request->param('code'));
    }
}


return [
    // 验证码位数
    'length'      => 4,
    // 字符集合(默认已剔除 0/O/1/I 等易混淆字符)
    'codeSet'     => 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789',
    // 过期时间(秒)
    'expire'      => 180,
    // 算术验证码 (true 时 length / codeSet 忽略)
    'math'        => false,
    // 画干扰点
    'useNoise'    => true,
    // 画干扰线
    'useCurve'    => true,
    // 使用 assets/bgs/ 下的图片做背景(平铺拉伸到验证码尺寸,true 时忽略 bg 颜色)
    'useImgBg'    => false,
    // 背景色 [R, G, B](useImgBg=false 或背景图加载失败时生效)
    'bg'          => [243, 251, 254],
    // 图片尺寸(填 0 则根据 fontSize 自动计算)
    'imageH'      => 0,
    'imageW'      => 0,
    // 字号(px)
    'fontSize'    => 22,
    // 缓存键前缀(多项目共用 Redis 时改一改防冲突)
    'cachePrefix' => 'captcha_',
];

return [
    // ... 上面 12 项 ...

    // 👇 以下仅 Captcha(Session 类)支持

    'useZh'   => false,                 // 启用中文验证码(true 时用 assets/zhttfs 字体 + zhSet 字符)
    'zhSet'   => '我们的祖国...',        // 中文字符集合(useZh=true 时生效)
    'fontttf' => '',                    // 指定字体文件名(如 '3.ttf'),空 = 从 assets/ttfs 随机
    'alpha'   => 0,                     // 背景透明度:0=完全不透明,127=完全透明
    'api'     => false,                 // create() 返回类型:false=Response;true=[code, img] 数组
    'interfere' => [                    // 自定义干扰项(高级用法),值为可调用 Closure
        // 'myCustom' => fn($im, $w, $h, $fs, $c) => /* 画点线 ... */,
    ],
];

return [
    'length'   => 4,
    'expire'   => 180,
    'fontSize' => 22,

    // 登录:4 位数字 + 长过期(减少输入失败)
    'login' => [
        'length'  => 4,
        'codeSet' => '0123456789',
        'expire'  => 300,
    ],

    // 注册:6 位混合字符 + 短过期(防垃圾注册)
    'register' => [
        'length'  => 6,
        'useNoise'=> true,
        'useCurve'=> true,
        'expire'  => 60,
    ],

    // 后台:算术 + 更大字体
    'admin' => [
        'math'     => true,
        'fontSize' => 26,
    ],
];

// 原版直接出图片(不推荐前后端分离项目用,但保留了)
return captcha();            // Response: image/png binary

// 原版校验:额外传 key 即可
captcha_check($code, $key);  // $key 可省略,省略时会尝试从 request()->param('key') 取值
bash
# 运行全部测试(39 tests / 60 assertions)
composer test
vendor/bin/phpunit

# 运行单个测试文件
vendor/bin/phpunit tests/CaptchaServiceTest.php
vendor/bin/phpunit tests/CaptchaTest.php
vendor/bin/phpunit tests/HelperTest.php
vendor/bin/phpunit tests/CaptchaFacadeTest.php

# 静态分析(PHPStan level 1)
composer analyze

# 代码风格检查 + 自动修复
composer check-style
composer fix-style