Uppy与CodeIgniter Events集成:PHP事件系统

Uppy与CodeIgniter Events集成:PHP事件系统

【免费下载链接】uppy The next open source file uploader for web browsers :dog: 【免费下载链接】uppy 项目地址: https://gitcode.com/gh_mirrors/up/uppy

引言:解决文件上传的事件驱动痛点

在Web开发中,文件上传是一个常见但复杂的功能。传统的上传处理方式往往将验证、存储和后续操作耦合在一起,导致代码难以维护和扩展。Uppy作为现代化的文件上传前端库,提供了强大的上传体验,而CodeIgniter的事件系统则为后端处理提供了灵活的钩子机制。本文将展示如何将两者结合,构建一个松耦合、可扩展的文件上传处理流程。

读完本文后,你将能够:

  • 理解Uppy与CodeIgniter事件系统集成的优势
  • 掌握在CodeIgniter中配置和使用事件的方法
  • 实现文件上传过程中的事件触发与处理
  • 构建可扩展的文件上传处理流程

Uppy前端配置

首先,我们需要配置Uppy前端,使其能够与CodeIgniter后端进行通信。以下是一个基本的Uppy配置示例:

import Uppy from '@uppy/core'
import Dashboard from '@uppy/dashboard'
import Webcam from '@uppy/webcam'
import XHRUpload from '@uppy/xhr-upload'

import '@uppy/core/dist/style.css'
import '@uppy/dashboard/dist/style.css'
import '@uppy/webcam/dist/style.css'

const uppy = new Uppy({
  debug: true,
  autoProceed: false,
})

uppy.use(Webcam)
uppy.use(Dashboard, {
  inline: true,
  target: 'body',
  plugins: ['Webcam'],
})
uppy.use(XHRUpload, {
  endpoint: '/upload',
  headers: {
    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
  }
})

// 监听上传成功事件
uppy.on('upload-success', (file, response) => {
  console.log('Upload successful:', file, response)
  // 可以在这里触发前端后续操作
})

这段代码配置了一个包含仪表盘和 webcam 功能的 Uppy 实例,并使用 XHRUpload 插件将文件上传到 CodeIgniter 后端的 /upload 端点。我们还添加了 CSRF 令牌,以确保与 CodeIgniter 的安全通信。

CodeIgniter 后端设置

1. 创建上传控制器

首先,我们需要创建一个处理上传请求的控制器。在 CodeIgniter 中,创建一个 UploadController.php 文件:

<?php
namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\Events\Events;

class UploadController extends Controller
{
    public function index()
    {
        // 检查请求方法
        if ($this->request->getMethod() !== 'post') {
            return $this->response->setStatusCode(405)->setJSON(['error' => 'Method Not Allowed']);
        }
        
        // 获取上传的文件
        $file = $this->request->getFile('file');
        
        // 触发文件上传开始事件
        Events::trigger('upload_start', $file);
        
        // 验证文件
        if (!$file->isValid()) {
            // 触发上传验证失败事件
            Events::trigger('upload_validation_failed', $file, $file->getErrorString());
            return $this->response->setStatusCode(400)->setJSON([
                'error' => $file->getErrorString()
            ]);
        }
        
        // 触发文件验证成功事件
        Events::trigger('upload_validated', $file);
        
        // 移动文件到上传目录
        $newName = $file->getRandomName();
        $file->move(WRITEPATH . 'uploads', $newName);
        
        // 准备文件信息数组
        $fileInfo = [
            'name' => $file->getClientName(),
            'new_name' => $newName,
            'type' => $file->getClientMimeType(),
            'size' => $file->getSize(),
            'path' => WRITEPATH . 'uploads/' . $newName
        ];
        
        // 触发文件上传成功事件
        Events::trigger('upload_success', $fileInfo);
        
        return $this->response->setStatusCode(201)->setJSON([
            'message' => 'File uploaded successfully',
            'file' => $fileInfo
        ]);
    }
}

2. 配置路由

app/Config/Routes.php 中添加一个路由,将上传请求映射到我们刚刚创建的控制器:

$routes->post('upload', 'UploadController::index');

3. 配置事件处理

现在,我们需要配置 CodeIgniter 的事件系统来处理我们触发的事件。在 app/Config/Events.php 文件中注册事件处理器:

<?php

namespace Config;

use CodeIgniter\Events\Events;

Events::on('upload_start', function ($file) {
    log_message('info', 'File upload started: ' . $file->getClientName());
    // 可以在这里执行上传开始前的准备工作
});

Events::on('upload_validation_failed', function ($file, $error) {
    log_message('error', 'File validation failed for ' . $file->getClientName() . ': ' . $error);
    // 可以在这里添加错误处理逻辑,如发送通知等
});

Events::on('upload_validated', function ($file) {
    log_message('info', 'File validated successfully: ' . $file->getClientName());
    // 可以在这里执行文件验证后的操作,如病毒扫描等
});

Events::on('upload_success', function ($fileInfo) {
    log_message('info', 'File uploaded successfully: ' . $fileInfo['name']);
    // 可以在这里执行文件上传后的操作,如生成缩略图、添加到数据库等
    
    // 例如,我们可以在这里触发另一个事件来处理文件处理
    Events::trigger('process_uploaded_file', $fileInfo);
});

// 处理已上传文件的事件
Events::on('process_uploaded_file', function ($fileInfo) {
    log_message('info', 'Processing uploaded file: ' . $fileInfo['name']);
    
    // 示例:如果是图片文件,生成缩略图
    if (strpos($fileInfo['type'], 'image/') === 0) {
        // 这里添加生成缩略图的逻辑
        log_message('info', 'Generating thumbnail for image: ' . $fileInfo['name']);
    }
    
    // 示例:将文件信息保存到数据库
    $model = new \App\Models\FileModel();
    $model->save([
        'name' => $fileInfo['name'],
        'new_name' => $fileInfo['new_name'],
        'type' => $fileInfo['type'],
        'size' => $fileInfo['size'],
        'path' => $fileInfo['path'],
        'uploaded_at' => date('Y-m-d H:i:s')
    ]);
});

4. 创建文件模型

为了演示如何将文件信息保存到数据库,我们创建一个简单的 FileModel.php

<?php
namespace App\Models;

use CodeIgniter\Model;

class FileModel extends Model
{
    protected $table = 'files';
    protected $primaryKey = 'id';
    protected $allowedFields = ['name', 'new_name', 'type', 'size', 'path', 'uploaded_at'];
}

完整的上传流程

下图展示了Uppy与CodeIgniter事件系统集成的完整上传流程:

mermaid

高级应用:自定义事件和监听器

对于更复杂的应用,我们可以创建自定义事件类和监听器,使代码更加结构化。

创建自定义事件类

<?php
namespace App\Events;

class FileUploadEvent
{
    public $fileInfo;
    
    public function __construct(array $fileInfo)
    {
        $this->fileInfo = $fileInfo;
    }
}

创建监听器类

<?php
namespace App\Listeners;

use App\Events\FileUploadEvent;

class ProcessImageListener
{
    public function handle(FileUploadEvent $event)
    {
        $fileInfo = $event->fileInfo;
        
        // 仅处理图片文件
        if (strpos($fileInfo['type'], 'image/') === 0) {
            // 图片处理逻辑
            log_message('info', 'Processing image: ' . $fileInfo['name']);
            // 例如:生成缩略图、裁剪图片等
        }
    }
}

注册自定义事件和监听器

app/Config/Events.php 中:

Events::on('upload_success', function ($fileInfo) {
    $event = new \App\Events\FileUploadEvent($fileInfo);
    Services::events()->trigger($event);
});

Services::events()->on('App\Events\FileUploadEvent', 'App\Listeners\ProcessImageListener::handle');

总结与扩展

通过将Uppy与CodeIgniter的事件系统集成,我们构建了一个松耦合、可扩展的文件上传处理流程。这种方式的主要优势包括:

  1. 关注点分离:将上传处理的不同阶段分离为独立的事件处理函数
  2. 可扩展性:可以轻松添加新的事件处理逻辑,而无需修改核心上传代码
  3. 可维护性:每个事件处理器负责单一职责,使代码更易于理解和维护

未来,你可以进一步扩展这个系统:

  • 添加更多事件,如上传进度事件、文件删除事件等
  • 实现更复杂的文件处理逻辑,如视频转码、文档转换等
  • 集成第三方服务,如云存储、CDN等
  • 添加文件权限控制和用户配额管理

通过这种事件驱动的架构,你的文件上传系统将能够适应不断变化的需求,同时保持代码的清晰和可维护性。

参考资料

【免费下载链接】uppy The next open source file uploader for web browsers :dog: 【免费下载链接】uppy 项目地址: https://gitcode.com/gh_mirrors/up/uppy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值