php
57 lines · 9 steps
Rendering invoice PDFs in a Laravel queue job
A queued job that loads an invoice, renders it to PDF, stores the file, and notifies the customer — with retries and failure handling.
Explained by
highlit
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Invoice;
6use App\Notifications\InvoiceGenerated;
7use Barryvdh\DomPDF\Facade\Pdf;
8use Illuminate\Bus\Queueable;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Bus\Dispatchable;
11use Illuminate\Queue\InteractsWithQueue;
12use Illuminate\Queue\SerializesModels;
13use Illuminate\Support\Facades\Storage;
14
15class GenerateInvoicePdf implements ShouldQueue
16{
17 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
18
19 public int $tries = 3;
20 public int $backoff = 30;
21
22 public function __construct(public Invoice $invoice)
23 {
24 }
25
26 public function handle(): void
27 {
28 $this->invoice->loadMissing(['customer', 'lineItems']);
29
30 $pdf = Pdf::loadView('invoices.pdf', [
31 'invoice' => $this->invoice,
32 'customer' => $this->invoice->customer,
33 'lineItems' => $this->invoice->lineItems,
34 ])->setPaper('a4');
35
36 $path = sprintf('invoices/%s/%s.pdf', $this->invoice->customer_id, $this->invoice->number);
37
38 Storage::disk('invoices')->put($path, $pdf->output(), 'private');
39
40 $this->invoice->update([
41 'pdf_path' => $path,
42 'generated_at' => now(),
43 ]);
44
45 $this->invoice->customer->notify(new InvoiceGenerated($this->invoice));
46 }
47
48 public function uniqueId(): string
49 {
50 return (string) $this->invoice->id;
51 }
52
53 public function failed(\Throwable $e): void
54 {
55 $this->invoice->update(['generation_failed_at' => now()]);
56 }
57}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Implementing ShouldQueue lets heavy work like PDF rendering run in the background instead of blocking the request.
- 2Setting $tries and $backoff plus a failed() hook makes a job resilient to transient errors and observable when it gives up.
- 3Persisting the file path and a timestamp on the model keeps a durable record of what the job produced.
Related explainers
php
<?php class NameParser {
Parsing a full name into components in PHP
string-parsing
arrays
normalization
Intermediate
8 steps
php
<?php namespace App\Services\Checkout;
Validating coupons with Laravel's Pipeline
pipeline
chain of responsibility
transactions
Intermediate
7 steps
php
<?php namespace App\Services;
How a password strength validator works in PHP
validation
regular-expressions
data-driven
Intermediate
8 steps
php
<?php namespace App\Services;
Building a cached daily leaderboard in Laravel
caching
aggregation
eager-loading
Intermediate
9 steps
php
<?php final class RotatingFileLogger {
How a rotating file logger works in PHP
logging
file-rotation
io
Intermediate
9 steps
php
class TwoFactorController extends Controller { public function show(Request $request): View|RedirectResponse {
Two-factor auth challenge flow in Laravel
authentication
two-factor
middleware
Intermediate
10 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/rendering-invoice-pdfs-in-a-laravel-queue-job-explained-php-5b11/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.