endroid/qr-code
Generate QR codes quickly in PHP. Built on BaconQrCode with optional validation, and multiple writers for PNG, WebP, SVG, EPS, or binary output. Includes a fluent Builder plus extras like Twig extensions, routes, factories, and a Symfony bundle.
composer require endroid/qr-codephp -m | grep gd)—required for PngWriter, WebPWriter, SvgWriterBuilder:
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Writer\PngWriter;
$qr = (new Builder())
->writer(new PngWriter())
->data('https://your-app.com/ticket/123')
->size(200)
->build();
$qr->saveToFile(storage_path('app/qrcodes/ticket-123.png'));
Builder with named config groups: In Laravel, define reusable configurations via a custom service or facade:
// app/Services/QrCodeService.php
public function forOrder(Order $order): QrCodeResult
{
return (new Builder())
->writer(new PngWriter())
->data(route('orders.show', $order))
->size(300)
->margin(10)
->logoPath(public_path('img/logo-sm.png'))
->logoResizeToWidth(40)
->build();
}
$result = $builder->build();
return response($result->getString())
->header('Content-Type', $result->getMimeType())
->header('Content-Disposition', 'inline; filename="ticket-'.$order->id.'.png"');
$writer = $request->wantsJson()
? new SvgWriter()
: new PngWriter();
dispatch(new GenerateShippingLabels($orders->each(fn($o) => $qrService->forOrder($o)->saveToFile($path))));
validateResult(true) triggers a decoder pass—only enable in development or for critical payloads (e.g., payment URLs). Disable in production by default.public_path()), and logos are 24-bit PNG with transparency—JPEG logos require manual conversion or will fail silently.width/height attributes are missing—use WRITER_OPTION_EXCLUDE_WIDTH_AND_HEIGHT => false or add CSS max-width: 100%.new Color(hexdec(substr($hex, 1, 2)), hexdec(substr($hex, 3, 2)), hexdec(substr($hex, 5, 2))).ErrorCorrectionLevel::High increases size by ~30% but improves scan reliability on logos/partial occlusion—ideal for product packaging.$qrCode->getRoundBlockSize()—non-integer values indicate block rounding; set roundBlockSizeMode(RoundBlockSizeMode::Margin) for sharper output.UTF-8 with ECI headers—switch to Encoding::ISO_8859_1 if targeting legacy scanners and ASCII-only content.Writer and assert $result->getString() length > 0 (QR codes have predictable minimal structure size).How can I help you explore Laravel packages today?