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

Laravel Php Pdf Laravel Package

dskripchenko/laravel-php-pdf

Laravel integration for the PHP-PDF library, making it easy to generate and work with PDF documents inside your Laravel applications. Provides a familiar service-provider setup and a clean, framework-friendly API for creating PDFs.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. composer require dskripchenko/laravel-pdf (pulls dskripchenko/php-pdf — v1.5.0 requires ^1.18), then php artisan vendor:publish --tag=pdf-config and, if you bundle fonts, --tag=pdf-fonts.
  2. Start in the package config (config/pdf.php): three sections matter day-to-day — fonts.families (registered TTF faces), fonts.provider (new in 1.5.0), and signing (certificate, key, and now signer).
  3. First use case — render a document and sign it in one chain:
use Dskripchenko\LaravelPdf\Facades\Pdf;

Pdf::loadView('invoices.show', ['invoice' => $invoice])
    ->format('A4')
    ->save(storage_path("invoices/{$invoice->id}.pdf"));

Pdf::loadView('invoices.show', ['invoice' => $invoice])->sign();
  1. For anything beyond a local .p12, skip the certificate/key config entirely and bind a signer (see below). Set PDF_SIGNER=App\Pdf\CryptoProSigner::class in .env and you're done — the package resolves it once and uses it for sign(), signed(), signatureConfig() and signDetached().

Implementation Patterns

Signer binding (the headline feature of 1.5.0). signing.signer accepts a container binding string or a class name. Bind an interface you control so tests and tenants can swap implementations without touching config:

// AppServiceProvider::register()
$this->app->singleton(SignerContract::class, fn () => new CryptoProSigner(
    container: config('services.cryptopro.container'),
    pin: config('services.cryptopro.pin'),
));
// config/pdf.php
'signing' => [
    'signer' => App\Pdf\SignerContract::class, // or env('PHP_PDF_SIGNER')
],

Because the signer replaces the configured certificate and key, delete the certificate/key entries once signer is set — leaving both in place invites confusion about which one produced a given signature. This is also the sanctioned place for HSM/PKCS#11/KMS credentials: keep secrets in env or a vault read by the signer class, never in the config array.

Test doubles. Bind a deterministic Signer in TestCase::setUp() (or a Signer::fake()-style stub) so signing tests don't need a token plugged in. Snapshot the signature dictionary (/ByteRange, /SubFilter) rather than the raw bytes.

Font provider for portability. fonts.provider receives every family not listed in fonts.families, which makes it the right hook for aliasing Liberation fonts to the Arial / Times New Roman / Courier New names your Blade views already reference:

final class LiberationFontProvider implements FontProvider
{
    public function getFont(string $family): ?Font
    {
        return match (strtolower($family)) {
            'arial'            => Font::fromFiles(resource_path('fonts/LiberationSans-Regular.ttf'), /* … */),
            'times new roman'  => Font::fromFiles(resource_path('fonts/LiberationSerif-Regular.ttf'), /* … */),
            default            => null,
        };
    }
}

This keeps views written on macOS/Windows rendering consistently inside a slim Linux container.

Detached signatures for archival flows. Pdf::signDetached() produces the CMS blob separately from the document — the right shape when a document lives in object storage and the signature in a database column, or when multiple parties countersign sequentially.

Queue long-running work. HSM round-trips and large documents belong in a job. Bind the signer as a singleton so a single token session is reused across documents in the worker rather than re-authenticating per PDF.

Gotchas and Tips

  • The signer is resolved once. Don't expect config mutation or Pdf::signatureConfig() calls mid-request to swap backends — bind per-tenant signers as scoped bindings or a resolver that reads the current tenant, not by editing config at runtime.
  • Upgrade re-baselines your PDFs. The bold/italic/bold_italic fix means text in configured families that previously fell back to the regular face now genuinely renders bold. Any pixel/page-count snapshot tests, fixed-width table layouts, or measured column widths will shift. Regenerate fixtures and eyeball one invoice per template before shipping.
  • A missing face still falls back silently. Only regular is presumably mandatory; if you configure bold but forget bold_italic, italic bold text quietly renders in the regular face. Register all four faces per family and assert it in a test (Pdf::font() metadata checks beat visual diffs).
  • signDetached() + CmsSigner needs php-pdf 1.20+. The TypeError is fixed, but only on that version; on 1.18/1.19 you get an explicit error rather than corrupt output. composer show dskripchenko/php-pdf before you blame your signer.
  • Config caching bites closures. signer and provider must be class strings or container keys — closures in config/pdf.php vanish under php artisan config:cache. Class strings also mean the class must be autoloadable from the config-cache context.
  • Wrong signer type fails late. A binding that returns something that isn't a Signer/CmsSigner blows up on the first sign(), not at boot. Add one smoke test that resolves config('pdf.signing.signer') and asserts the interface.
  • Debug signatures outside PHP. pdfsig document.pdf for embedded signatures, and openssl cms -verify -in sig.p7s -content doc.pdf -inform DER -noverify for detached blobs. Verify the chain separately with -CAfile; -noverify only tells you the CMS parses.
  • Aliasing is metric compatibility, not licensing. Liberation fonts match Arial/Times/Courier advances so layouts hold, but glyphs differ — and aliasing doesn't grant you rights to embed the real Microsoft fonts. Keep the licensed TTFs out of the repo.
  • Extension points to know: custom Signer/CmsSigner implementations, a custom FontProvider, and the raw fonts.families map. Those three cover nearly every "my environment differs" situation without forking the package.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log