ThinkPHP实现自动生成二维码功能

文章特色图片

一、准备工作

在ThinkPHP框架中实现二维码生成功能,通常需要使用第三方库。目前最常用的PHP二维码生成库是endroid/qr-code

1. 安装依赖

首先通过Composer安装二维码生成库:

composer require endroid/qr-code

二、基础实现

1. 创建二维码生成控制器

创建一个控制器专门处理二维码生成逻辑:

namespace app\controller;

use think\facade\App;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Label\Label;
use Endroid\QrCode\Logo\Logo;

class QrcodeController
{
    /**
     * 生成基础二维码
     * @param string $content 二维码内容
     * @param int $size 二维码尺寸
     * @return \think\Response
     */
    public function generate($content = 'https://www.example.com', $size = 300)
    {
        $qrCode = QrCode::create($content)
            ->setSize($size)
            ->setMargin(10)
            ->setForegroundColor(new Color(0, 0, 0))
            ->setBackgroundColor(new Color(255, 255, 255));
        
        $writer = new PngWriter();
        $result = $writer->write($qrCode);
        
        return response($result->getString(), 200, [
            'Content-Type' => $result->getMimeType()
        ]);
    }
}

2. 添加路由

在路由文件中添加访问规则:

use think\facade\Route;
Route::get('qrcode/generate', 'qrcode/generate');

三、高级功能实现

1. 带Logo的二维码

public function generateWithLogo($content = 'https://www.example.com', $size = 300)
{
    $qrCode = QrCode::create($content)
        ->setSize($size)
        ->setMargin(10);
    
    // 设置Logo
    $logo = Logo::create(App::getRootPath() . 'public/logo.png')
        ->setResizeToWidth(50);
    
    $writer = new PngWriter();
    $result = $writer->write($qrCode, null, $logo);
    
    return response($result->getString(), 200, [
        'Content-Type' => $result->getMimeType()
    ]);
}

2. 带文字的二维码

public function generateWithLabel($content = 'https://www.example.com', $size = 300, $labelText = '扫描二维码')
{
    $qrCode = QrCode::create($content)
        ->setSize($size)
        ->setMargin(10);
    
    // 设置标签
    $label = Label::create($labelText)
        ->setTextColor(new Color(255, 0, 0));
    
    $writer = new PngWriter();
    $result = $writer->write($qrCode, null, null, $label);
    
    return response($result->getString(), 200, [
        'Content-Type' => $result->getMimeType()
    ]);
}

3. 保存二维码到文件

public function saveToFile($content, $filename = 'qrcode.png')
{
    $qrCode = QrCode::create($content)
        ->setSize(300)
        ->setMargin(10);
    
    $writer = new PngWriter();
    $result = $writer->write($qrCode);
    
    // 保存到public目录
    $savePath = App::getRootPath() . 'public/qrcodes/' . $filename;
    $result->saveToFile($savePath);
    
    return json([
        'code' => 200,
        'message' => '二维码生成成功',
        'path' => '/qrcodes/' . $filename
    ]);
}

四、前端调用示例

在前端页面中,可以通过img标签直接调用二维码生成接口:

<img src="/qrcode/generate?content=https://www.yoursite.com&size=200" alt="二维码">

或者生成带Logo的二维码:

<img src="/qrcode/generateWithLogo?content=https://www.yoursite.com&size=200" alt="带Logo的二维码">

五、实用技巧

  1. 缓存二维码:对于频繁生成的相同内容二维码,可以考虑缓存机制

  2. 参数验证:对传入的内容和尺寸参数进行验证,防止恶意使用

  3. 权限控制:限制生成二维码的访问权限,防止滥用

  4. 自定义样式:可以自定义二维码颜色、背景等样式

六、完整示例代码

namespace app\controller;

use think\facade\App;
use think\facade\Request;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Label\Label;
use Endroid\QrCode\Logo\Logo;

class QrcodeController
{
    /**
     * 生成二维码
     * @return \think\Response
     */
    public function index()
    {
        $params = Request::get();
        $content = $params['content'] ?? 'https://www.example.com';
        $size = $params['size'] ?? 300;
        
        // 基础二维码
        $qrCode = QrCode::create($content)
            ->setSize($size)
            ->setMargin(10)
            ->setForegroundColor(new Color(0, 0, 0))
            ->setBackgroundColor(new Color(255, 255, 255));
        
        $writer = new PngWriter();
        
        // 添加Logo
        if (!empty($params['logo'])) {
            $logoPath = App::getRootPath() . 'public/' . ltrim($params['logo'], '/');
            if (file_exists($logoPath)) {
                $logo = Logo::create($logoPath)->setResizeToWidth(50);
            }
        }
        
        // 添加标签
        if (!empty($params['label'])) {
            $label = Label::create($params['label'])
                ->setTextColor(new Color(255, 0, 0));
        }
        
        $result = $writer->write($qrCode, $logo ?? null, null, $label ?? null);
        
        return response($result->getString(), 200, [
            'Content-Type' => $result->getMimeType()
        ]);
    }
}

通过以上实现,你可以在ThinkPHP项目中轻松集成二维码生成功能,满足各种业务场景需求。