Laravel队列中wkhtmltopdf缓存配置引发的任务冲突问题
问题
在Laravel应用中使用wkhtmltopdf生成PDF,依赖barryvdh/laravel-snappy包,预算打印和账单打印功能以队列任务运行。预算打印设置了0边距、横向等配置,账单打印采用纵向等不同配置,但预算的配置会残留影响账单生成,重启队列可临时解决问题。已尝试独立初始化WKPDF但无效,现寻求无需重启队列即可隔离各任务wkhtmltopdf配置的方法。
预算打印代码:
$pdf = WKPDF::loadHtml($pdf_html); $pdf->setPaper('a4'); $pdf->setOption('disable-smart-shrinking', true); $pdf->setOption('margin-top', 0); $pdf->setOption('margin-right', 0); $pdf->setOption('margin-bottom', 0); $pdf->setOption('margin-left', 0); $pdf->setOption('encoding', "UTF-8"); $pdf->setOption('orientation', 'landscape'); $pdf->setOption('load-error-handling', "ignore"); $pdf->setOption('enable-local-file-access', true); $pdf->save(($upload_path) . '/' . $file_name);
账单打印代码:
$pdf = WKPDF::setOptions(['dpi' => 100, 'enable-local-file-access' => true, 'load-error-handling' => "ignore", 'encoding' => "UTF-8",]) ->setPaper('a4', 'portrait') ->loadHTML($pdf_html) ->save($file_upload_path . '/' . $pdf_file_name);
解决方案
问题核心是队列进程为长生命周期,barryvdh/laravel-snappy的WKPDF门面默认用单例模式,前序任务的配置会被后续任务继承。以下三种方法可彻底隔离配置:
1. 直接实例化底层类(推荐)
放弃WKPDF门面,手动创建Barryvdh\Snappy\Pdf独立实例,每个任务都生成全新对象:
预算打印改造代码
use Barryvdh\Snappy\Pdf; $pdf = new Pdf( config('snappy.pdf.binary'), config('snappy.pdf.options') ); $pdf->loadHtml($pdf_html); $pdf->setPaper('a4'); $pdf->setOption('disable-smart-shrinking', true); $pdf->setOption('margin-top', 0); $pdf->setOption('margin-right', 0); $pdf->setOption('margin-bottom', 0); $pdf->setOption('margin-left', 0); $pdf->setOption('encoding', "UTF-8"); $pdf->setOption('orientation', 'landscape'); $pdf->setOption('load-error-handling', "ignore"); $pdf->setOption('enable-local-file-access', true); $pdf->save($upload_path . '/' . $file_name);
账单打印改造代码
use Barryvdh\Snappy\Pdf; $pdf = new Pdf( config('snappy.pdf.binary'), config('snappy.pdf.options') ); $pdf->setOptions([ 'dpi' => 100, 'enable-local-file-access' => true, 'load-error-handling' => "ignore", 'encoding' => "UTF-8", ])->setPaper('a4', 'portrait') ->loadHTML($pdf_html) ->save($file_upload_path . '/' . $pdf_file_name);
2. 重置门面实例
若坚持使用门面,在每个任务的handle方法开头添加重置逻辑,清空之前的实例缓存:
// 清除已缓存的单例实例 app()->forgetInstance('snappy.pdf'); // 重新获取的实例为全新状态 $pdf = WKPDF::loadHtml($pdf_html);
3. 通过容器创建临时实例
利用Laravel容器的makeWith方法,每次生成独立实例:
$pdf = app()->makeWith(Barryvdh\Snappy\Pdf::class, [ 'binary' => config('snappy.pdf.binary'), 'options' => config('snappy.pdf.options'), ]);
验证方式
修改后模拟队列连续执行预算、账单打印任务,检查生成的PDF是否符合各自配置(预算为横向0边距、账单为纵向正常配置),无需重启队列即可验证效果。
内容的提问来源于stack exchange,提问作者Mehran
相关产品推荐
相关产品推荐

