Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Helpers Bundle Laravel Package

m-adamski/symfony-helpers-bundle

A small Symfony bundle that collects handy helper utilities for everyday development. It aims to reduce boilerplate in Symfony projects, though it is a minor, low-activity package with limited adoption and documentation, so evaluate its fit before relying on it.

View on GitHub
Deep Wiki
Context7

Getting Started

This release is a small additive change to barryvdh/laravel-dompdf: PDF::output() now returns the rendered PDF as a raw string instead of only exposing download() / stream() / save(). Nothing breaks; existing code keeps working.

First steps for a project that doesn't have it yet:

composer require barryvdh/laravel-dompdf
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

That publishes config/dompdf.php (options passed straight to the underlying Dompdf\Options) and puts the dompdf disk in config/filesystems.php.

The first use case is almost always "render a Blade view to a PDF and return it from a controller":

use Barryvdh\DomPDF\Facade\Pdf;

public function invoice(Invoice $invoice)
{
    $pdf = Pdf::loadView('pdf.invoice', compact('invoice'));

    return $pdf->download("invoice-{$invoice->id}.pdf");
}

With 2.0.3, the same object also gives you the bytes:

$bytes = Pdf::loadView('pdf.invoice', compact('invoice'))->output();

Where to look first: config/dompdf.php (paper size, orientation, DPI, font dir, enable_remote, chroot), then the Barryvdh\DomPDF\PDF class itself — it's a thin wrapper around the Dompdf instance and exposes setPaper(), setOption(), setWarnings(), loadView(), loadHTML(), loadFile(), plus the four output methods.

Implementation Patterns

Controller-level generation. Load a Blade view, pass it through setPaper(), return a response. Keep the view free of JS/layout dependencies — dompdf renders a single pass of HTML/CSS.

$pdf = Pdf::loadView('pdf.report', $data)
    ->setPaper('a4', 'landscape')
    ->setOption(['isRemoteEnabled' => true]);

return $pdf->stream('report.pdf'); // inline in browser

Store on a disk, then serve separately. Useful when the PDF is expensive and generated by a queued job:

Pdf::loadView('pdf.statement', $data)->save(storage_path("app/pdf/{$user->id}.pdf"));

Use output() for things that aren't HTTP responses. This is the whole point of 2.0.3. Before it you had to call save() to a temp path, file_get_contents() it, and clean up — or dig into the underlying getDomPDF()->output(). Now:

// Attach to mail without touching the filesystem
Mail::to($user)->send(new StatementMail($user, Pdf::loadView('pdf.statement', $data)->output()));

// Hand to a storage SDK / HTTP client that wants raw bytes
Storage::disk('s3')->put("statements/{$id}.pdf", $pdf->output());

// Assert on output in a feature test
$this->assertStringStartsWith('%PDF-', Pdf::loadView('pdf.blank')->output());

The string is the complete binary PDF — treat it as application/pdf bytes, don't echo it into a view.

Centralise rendering. A small service or action class (GenerateInvoicePdf) that owns the view name and paper settings stops setPaper() arguments drifting between controllers, mailables, and jobs. Inject it where needed and keep the Pdf facade out of your domain code.

Mail attachments. The package ships Barryvdh\DomPDF\PDF with an OutputInterface-ish shape, but the simplest and most explicit path is ->output() into Attachment::fromData(fn () => $bytes, 'statement.pdf')->withMime('application/pdf'). Using fromData with a closure keeps the PDF out of memory until send time.

Queues. PDF generation is CPU- and memory-hungry; move anything bigger than a couple of pages into a job. Render in the job, store to disk, email a link. Don't pass the Pdf object across the queue boundary — regenerate it.

Testing. Pdf::loadHTML('<p>hi</p>')->output() works fine in tests and is cheap enough for a smoke test on the layout. Assert on %PDF- prefix and, if you care, on page count via getDomPDF()->getCanvas()->get_page_count().

Gotchas and Tips

output() returns bytes, not a path. Easy to misread the name and then Storage::put($path, $pdf->output()) — that's correct — but ->output($path) will silently ignore the argument (PHP doesn't complain about extra args on userland methods... it does throw now, so expect no error but check your call). The signature is output(): string.

Don't return $pdf->output() from a controller. Laravel will send the raw bytes without a Content-Type, and the browser will render it as text/mojibake. Use response($pdf->output())->header('Content-Type', 'application/pdf') or, better, just use ->download() / ->stream().

Memory. Dompdf loads the whole document into memory, including embedded images. A 200-row table of logos will blow past PHP's default memory_limit. Raise it per-request (ini_set('memory_limit', '512M')) or, preferably, resize images before embedding. Generated-at-request PDFs are the number one cause of 500s in production on this package.

Remote assets are off by default. isRemoteEnabled is false; <img src="https://..."> fails silently-ish (a warning in $pdf->getWarnings()). Turning it on is also an SSRF surface if any user-controlled URL reaches the view. Prefer local paths under chroot.

Fonts and CSS. No flexbox, no grid, limited float handling. Use tables or simple block layout. Custom fonts must exist in storage/fonts (dompdf's font cache), and the first render is slow while it builds *.ufm files — that's a known cold-start cost, not a bug. Ensure storage/fonts is writable and warm the cache during deploy.

Warnings are silently swallowed. $pdf->getWarnings() returns dompdf's complaints (missing images, unsupported CSS). Log them in non-production; they're the fastest way to explain "why is half the page blank".

setPaper() must precede rendering. Call it after loadView() but before any output/save/stream; the paper size is baked in at render time.

Config caching. config/dompdf.php is read at container resolution. After editing it, run php artisan config:clear — otherwise your new font dir or paper default appears to do nothing.

Extension points. Override the dompdf.wrapper binding to return your own PDF subclass (add company letterhead defaults, custom setPaper presets). setOption() per instance is fine for one-offs; anything global belongs in the config file. If you need raw dompdf behaviour, $pdf->getDomPDF() is the escape hatch.

output() for large documents. Passing megabytes of binary between PHP processes (queues, HTTP clients) is fine, but base64-encoding it for JSON APIs inflates by ~33% — stream the download endpoint instead.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums