Maatwebsite Excel队列导出数据到S3报PDO不可序列化错误
问题根源
你开启了ShouldQueue队列导出,且将完整的Eloquent Query Builder实例作为参数传入Export类构造方法。队列任务在分发时需要序列化整个Export对象,而Query Builder内部绑定了不可序列化的PDO数据库连接实例,因此直接抛出序列化异常。
你尝试传入toSql()结果报错的原因是:FromQuery要求query()方法返回Builder实例,你返回SQL字符串后,querySize()中调用count()自然会抛出字符串调用成员方法的错误。
解决方案
不要从控制器传入预构建的Query Builder,只传递可序列化的基础参数(过滤条件、用户信息等),在Export类内部自行构建查询逻辑,具体修改如下:
修改后控制器代码
$filters = request()->all(); // 保持你原来获取过滤参数的逻辑不变 if (request()->export_transactions){ // 仅传递可序列化的用户实例、过滤参数 (new TransactionsExport(auth('sanctum')->user(), $filters)) ->queue('transactions-exports/' . now()->format('d:m:Y') . '.csv', 's3', \Maatwebsite\Excel\Excel::CSV); return response()->json('Export started'); }
修改后Export类代码
class TransactionsExport implements FromQuery, WithMapping, WithHeadings, WithCustomQuerySize, ShouldQueue { use Exportable; private $user; private $filters; // 构造方法仅接收可序列化的基础参数 public function __construct(User $user, array $filters) { $this->user = $user; $this->filters = $filters; } /** * @return Builder */ public function query() { // 所有查询逻辑放到Export内部完成 return Transaction::query() ->with([ 'user', 'user.profile', 'senderUser', 'receiverUser', 'senderUser.roles', 'receiverUser.roles' ]) ->filterByUser() ->filter($this->filters) ->orderByDesc('created_at'); } public function querySize(): int { // 直接调用内部query方法获取构造器统计数量 return $this->query()->count(); } public function headings(): array { return [ // 保持原有表头逻辑不变 ]; } public function prepareRows($transactions): array { // 保持原有逻辑不变 } public function map($transaction): array { // 保持原有逻辑不变 } }
内容的提问来源于stack exchange,提问作者drunkOctopus
相关产品推荐
相关产品推荐

