Weave Code
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

Php Weasyprint Laravel Package

pontedilana/php-weasyprint

PHP 8.3+ wrapper around WeasyPrint (v60+) to generate PDFs from URLs or HTML. Snappy-inspired, drop-in style API with strict typing. Set the weasyprint binary, pass CLI options, stream to browser or write files.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Install the package**:
   ```bash
   composer require pontedilana/php-weasyprint
  1. Install WeasyPrint (version 60+):

    • Linux (Debian/Ubuntu):
      sudo apt-get install weasyprint
      
    • macOS (via Homebrew):
      brew install weasyprint
      
    • Windows: Use Chocolatey or download from WeasyPrint releases.
  2. Verify binary path (e.g., /usr/local/bin/weasyprint or C:\Program Files\WeasyPrint\weasyprint.exe).

First Use Case: Generate PDF from HTML

use Pontedilana\PhpWeasyPrint\Pdf;

$pdf = new Pdf('/usr/local/bin/weasyprint');
header('Content-Type: application/pdf');
echo $pdf->getOutput('<h1>Hello, PDF!</h1>');

First Use Case: Generate PDF from URL

$pdf = new Pdf('/usr/local/bin/weasyprint');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="report.pdf"');
echo $pdf->getOutput('https://example.com');

Where to Look First

  • README.md: For installation, basic usage, and security notes.
  • Enum/ directory: For predefined options (e.g., MediaType, PdfVersion).
  • Pdf class: Core functionality (methods like getOutput(), generateFromHtml()).
  • Changelog: For breaking changes and new features.

Implementation Patterns

Common Workflows

1. Dynamic PDF Generation in Controllers

use Pontedilana\PhpWeasyPrint\Pdf;

public function generateInvoice(Request $request)
{
    $html = view('invoices.pdf', ['invoice' => $request->invoice])->render();
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    $pdf->setOption('media-type', 'print');
    $pdf->setOption('stylesheet', [public_path('css/invoice.css')]);

    return response($pdf->getOutput($html))
        ->header('Content-Type', 'application/pdf');
}

2. Queue-Based PDF Generation

use Pontedilana\PhpWeasyPrint\Pdf;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class GeneratePdfJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        $pdf = new Pdf('/usr/local/bin/weasyprint');
        $pdf->disableTimeout(); // Let Laravel Queue handle timeouts
        $pdf->generateFromHtml('<h1>Queued PDF</h1>', storage_path('app/invoice.pdf'));
    }
}

3. Reusable PDF Service

namespace App\Services;

use Pontedilana\PhpWeasyPrint\Pdf;

class PdfService
{
    protected Pdf $pdf;

    public function __construct()
    {
        $this->pdf = new Pdf(config('weasyprint.binary'));
    }

    public function generateFromView(string $view, array $data, string $filename)
    {
        $html = view($view, $data)->render();
        $this->pdf->generateFromHtml($html, $filename);
    }

    public function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            $this->pdf->setOption($key, $value);
        }
    }
}

4. Customizing WeasyPrint Options

$pdf = new Pdf('/usr/local/bin/weasyprint');
$pdf->setOption('media-type', \Pontedilana\PhpWeasyPrint\Enum\MediaType::Print);
$pdf->setOption('pdf-version', \Pontedilana\PhpWeasyPrint\Enum\PdfVersion::Pdf17);
$pdf->setOption('timeout', 60); // Override default 10s timeout
$pdf->setOption('attachment', [
    'https://example.com/logo.png',
    storage_path('app/assets/header.jpg')
]);

5. Handling Errors Gracefully

try {
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    $output = $pdf->getOutput('https://example.com');
} catch (\Pontedilana\PhpWeasyPrint\Exception\RuntimeException $e) {
    Log::error('PDF generation failed: ' . $e->getMessage());
    return response()->view('errors.pdf_failed');
}

Integration Tips

Laravel-Specific Integrations

  1. Service Provider Binding:

    // config/app.php
    'providers' => [
        // ...
        App\Providers\PdfServiceProvider::class,
    ];
    
    // app/Providers/PdfServiceProvider.php
    public function register()
    {
        $this->app->singleton(PdfService::class, function ($app) {
            return new PdfService(new Pdf(config('weasyprint.binary')));
        });
    }
    
  2. Config File:

    // config/weasyprint.php
    return [
        'binary' => env('WEASYPRINT_BINARY', '/usr/local/bin/weasyprint'),
        'timeout' => env('WEASYPRINT_TIMEOUT', 10),
        'allowed_schemes' => ['http', 'https'],
    ];
    
  3. Middleware for PDF Generation:

    public function handle(Request $request, Closure $next)
    {
        if ($request->is('pdf/*')) {
            $pdf = new Pdf(config('weasyprint.binary'));
            $html = $next($request)->getContent();
            return response($pdf->getOutput($html))
                ->header('Content-Type', 'application/pdf');
        }
        return $next($request);
    }
    

Testing

use Pontedilana\PhpWeasyPrint\Pdf;
use Illuminate\Support\Facades\Storage;

public function testPdfGeneration()
{
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    $html = '<h1>Test PDF</h1>';
    $filename = 'test.pdf';

    // Generate PDF
    $pdf->generateFromHtml($html, storage_path("app/{$filename}"));

    // Assert file exists and is a valid PDF
    $this->assertTrue(Storage::exists("app/{$filename}"));
    $this->assertTrue(file_exists(storage_path("app/{$filename}")));
}

Performance Optimization

  1. Disable Timeout in Queues:
    $pdf->disableTimeout(); // Let Laravel Queue handle timeouts
    
  2. Cache HTML Templates:
    $cachedHtml = Cache::remember('invoice_html', 3600, function () {
        return view('invoices.pdf', ['data' => $data])->render();
    });
    $pdf->getOutput($cachedHtml);
    
  3. Use generateFromHtml for Local Files:
    $pdf->generateFromHtml($html, 'path/to/output.pdf');
    // Faster than streaming output for large PDFs
    

Gotchas and Tips

Pitfalls

  1. Binary Path Issues:

    • Gotcha: Hardcoding /usr/local/bin/weasyprint may fail on Windows or CI environments.
    • Fix: Use config('weasyprint.binary') or env('WEASYPRINT_BINARY').
    • Debug: Call checkBinary() to validate the path:
      $pdf = new Pdf('/path/to/weasyprint');
      if (!$pdf->checkBinary()) {
          throw new \RuntimeException('WeasyPrint binary not found or not executable.');
      }
      
  2. Timeout Conflicts:

    • Gotcha: Default 10s timeout may kill long-running processes (e.g., complex reports).
    • Fix: Disable timeout in queues or increase it:
      $pdf->setTimeout(30); // 30 seconds
      // OR
      $pdf->disableTimeout(); // For queue workers
      
  3. SSRF Risks:

    • Gotcha: URLs in options (e.g., attachment, stylesheet) are fetched by default only for http/https.
    • Fix: Explicitly allow schemes if needed:
      $pdf = new Pdf('/usr/local/bin/weasyprint', [], null, ['http', 'https', 'ftp']);
      
    • Security: Avoid passing user-controlled URLs directly to setOption().
  4. Memory Limits:

    • Gotcha: Large HTML/CSS may exceed PHP’s memory_limit.
    • Fix: Increase memory limit or optimize HTML:
      ini_set('memory_limit', '512M');
      
    • Tip: Use generateFromHtml() for local
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi