必须用队列实现后台执行耗时操作;需PHP≥8.2,安装yiisoft/queue,配置DbQueue并确保db名称正确,建表后定义任务类。

要在 Yii3.0 中实现邮件发送、报表生成、文件转码等耗时操作不阻塞用户请求,必须用队列把任务推到后台执行——这一步不是可选项,而是 PHP 8.2+ 环境下保障响应速度的硬性路径。
安装队列扩展并确认环境兼容性
运行 composer require yiisoft/queue 安装核心队列包。注意:该命令仅在 PHP ≥ 8.2 的环境中成功执行,低于此版本会直接报错退出,【不会降级兼容,也不会提示警告】。
若项目已启用 PSR-11 容器(即 config/common.php 中存在 ContainerInterface::class => ... 配置),则跳过容器注册;否则需在 config/common.php 中手动注入:QueueInterface::class => ['class' => SyncQueue::class] 作为开发阶段兜底方案。
配置数据库驱动队列组件
执行迁移命令创建队列表:php yii migrate --migrationPath=vendor/yiisoft/queue/src/Migrations。该命令将生成 queue 表,字段含 id、job、status、created_at 等,不可手动删减或修改结构。
在 config/common.php 中添加队列服务定义:
'queue' => [ 'class' => \Yiisoft\Queue\Db\Queue::class, 'db' => 'db', 'tableName' => '{{%queue}}', 'channel' => 'default', 'retryLimit' => 3],
其中 'db' 必须与你已注册的数据库连接名称完全一致,【若填错为 'database' 或 'primary',启动 worker 时会抛出 ConnectionNotFoundException】。
创建可执行的异步任务类
方法一:基础任务类(无依赖)
新建 src/Jobs/SendEmailJob.php,内容如下:
<?php namespace App\Jobs;use Yiisoft\Queue\JobInterface;final class SendEmailJob implements JobInterface{ public function __construct(public string $to, public string $subject, public string $body) {} public function execute(): void { // 实际调用 MailerInterface::send() 或其他发送逻辑 echo "Sending email to {$this->to}\n"; }}
方法二:带依赖注入的任务类(推荐生产使用)
在构造函数中声明所需接口,如 private MailerInterface $mailer,Yii3 容器会在执行时自动解析并注入实例。无需手动 new 或 get(),也无需在 execute() 内部再调用容器。
推送任务到队列并启动工作进程
第一步:在控制器或服务中获取队列实例
$queue = $container->get(QueueInterface::class);
第二步:构造任务并推送
$queue->push(new SendEmailJob('user@example.com', '欢迎注册', '感谢您加入我们'));
第三步:启动监听进程
执行 php yii queue/listen --verbose 启动单次监听;若需长期运行,请配合 systemd 或 supervisor 管理进程生命周期。该命令默认只消费 default 通道任务,如需指定通道,加参数 --channel=report。
第四步:验证任务是否入表
检查数据库 queue 表中是否有新记录,status 字段初始值为 waiting,worker 进程拉取后会更新为 reserved,执行完成变为 done 或 failed。


















