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

Barcode Bundle Laravel Package

mopa-liip/barcode-bundle

MopaBarcodeBundle brings barcode generation to Symfony apps, wrapping popular barcode libraries in services and Twig helpers so you can render QR, EAN, Code39, and other formats as PNG, SVG, or HTML from templates or controllers with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate expectations: this is not a Laravel package. mopa-liip/barcode-bundle is a Symfony2 bundle from the Symfony 2.x era. It ships no ServiceProvider, no facade, no config publishing, and its public API is a Twig function (barcode(...)) wired through Symfony's DI container. composer require mopa-liip/barcode-bundle in a Laravel app will install files but do nothing; you will get a Bundle class that extends Symfony\Component\HttpKernel\Bundle\Bundle and a Twig extension referencing Symfony services that do not exist.

So "getting started" for a Laravel developer is really an extraction exercise:

  1. Read the source before installing anything. The three files that define everything are:
    • DependencyInjection/Configuration.php — the config schema (barcode types, defaults, image options).
    • DependencyInjection/MopaBarcodeExtension.php — how services are built from that config.
    • The Twig extension class in Twig/ — the actual call signature of barcode() and what options it forwards to Zend_Barcode / PHP QR Lib. This tells you the whole package is a thin config layer over two third-party renderers.
  2. Install the underlying libraries directly, not the bundle:
    composer require laminas/laminas-barcode   # modern fork of Zend_Barcode
    composer require bacon/bacon-qr-code        # better than PHP QR Lib
    
    Or, if you want the historical exact output, zendframework/zend-barcode (abandoned) and phpqrcode. Prefer the maintained forks.
  3. Wrap one renderer in a small service. This is the Laravel-native equivalent of what the bundle did:
    // app/Services/BarcodeRenderer.php
    class BarcodeRenderer
    {
        public function render(string $type, string $text, array $opts = []): string
        {
            $barcode = Barcode::factory($type, 'image', array_merge([
                'text' => $text,
                'height' => 60,
                'width'  => 0,
                'barThinWidth' => 1,
            ], $opts));
    
            ob_start();
            $barcode->draw();
            return ob_get_clean(); // raw PNG bytes
        }
    }
    
  4. First real use case: a QR/Code128 image for an invoice, ticket, or label, returned from a route and embedded in a Blade view or a PDF. That is 95% of what this bundle was ever used for.

Where to look first in your own app: a single BarcodeController@show route with a signed/validated payload, plus the service above. Do not try to port the Twig extension; port the config shape.

Implementation Patterns

Route-per-barcode (recommended)

Rather than inlining image bytes into HTML, expose one endpoint that serves barcodes by opaque reference:

Route::get('/barcodes/{token}.png', BarcodeController::class)
    ->where('token', '[A-Za-z0-9_-]+')
    ->name('barcode.show');

The token is a signed payload (URL::signedRoute) or an HMAC of the actual value, so users cannot ask your server to render arbitrary barcodes at arbitrary sizes. Inside the controller:

return response($renderer->render($type, $value, $opts), 200, [
    'Content-Type'   => 'image/png',
    'Cache-Control'  => 'public, max-age=31536000, immutable',
    'Content-Length' => strlen($png),
]);

Barcodes are deterministic: the same type + text + options always yields the same image. Long-lived immutable caching is the single biggest win over the original bundle's per-request rendering.

Blade helper mirroring the Twig function

If your views were written for Symfony, keep the call site familiar:

// app/Support/helpers.php
function barcode(string $type, string $text, array $opts = []): string
{
    $url = URL::signedRoute('barcode.show', [
        'token' => BarcodeToken::encode($type, $text, $opts),
    ]);
    return '<img src="'.$url.'" alt="barcode" />';
}

Register it in composer.json autoload.files or, better, as a Blade directive (@barcode('qrcode', $order->number)) so it is obvious it produces HTML, not a value.

Data URIs for PDFs and emails

For PDFs (dompdf, Browsershot) and mail, a URL is a liability — the renderer may not fetch it. Embed bytes directly:

$dataUri = 'data:image/png;base64,'.base64_encode($renderer->render(...));

Cache the base64 string, not the data URI, so you can reuse it in both <img> and CSS.

Config-driven type registry

The bundle's real value was centralizing per-type defaults. Reproduce that in config/barcodes.php:

return [
    'qrcode'  => ['renderer' => 'qr',   'options' => ['height' => 200, 'margin' => 1]],
    'code128' => ['renderer' => 'zend', 'options' => ['height' => 60, 'barThinWidth' => 1]],
    'ean13'   => ['renderer' => 'zend', 'options' => ['height' => 60, 'drawText' => true]],
];

Then validate the incoming $type against array_keys(config('barcodes')) — never pass user input to the barcode factory.

Pre-generation for high volume

If a barcode appears on every row of a listing page, do not render N images per request. Generate on write (job or observer), store PNG/SVG in storage/app/barcodes/{hash}.png, and serve via Storage::response() or a CDN. The key is a hash of type|text|normalized-options, which also gives you free deduplication.

Testing

Assert on the container format, not pixels:

$this->assertStringStartsWith("\x89PNG\r\n\x1a\n", $png);
$this->assertSame([200, 60], array_slice(getimagesizefromstring($png), 0, 2));

And add one test that a valid EAN-13 checksum passes and an invalid one throws — that is where barcode libraries silently misbehave.

Gotchas and Tips

The package itself will not run on modern PHP. Zend_Barcode (underscore class names = Zend Framework 1) relies on PHP 5 semantics. It breaks on PHP 7.2+ in places and firmly on PHP 8 (dynamic properties, removed functions). The Symfony DI extension also targets Symfony\Component\DependencyInjection 2.x APIs. Treat this repo as documentation of an approach, not as installable code.

License is NOASSERTION — treat as unresolved. The repo declares no clear license, and the underlying dependencies are a mix (Zend Framework is BSD-3-Clause; PHP QR Lib is LGPL-3.0). LGPL in a bundled vendor directory raises distribution questions for a commercial Laravel app. Get this reviewed before shipping, or pick a permissively licensed alternative (picqer/php-barcode-generator, bacon/bacon-qr-code, endroid/qr-code, all MIT).

One star and zero dependents means no community, no patches, no Stack Overflow answers. Anything you adopt from here you own forever. Budget accordingly.

Output buffering is mandatory. Zend_Barcode::draw() writes to stdout, not a return value. Every call must be wrapped in ob_start() / ob_get_clean(), and any stray output (BOM in a PHP file, a var_dump left behind, Laravel's debug output) will corrupt the PNG. If images intermittently fail to scan, check for a leading newline before debugging the barcode library.

Send headers explicitly and stop. Return a Response with the PNG bytes and Content-Type: image/png. Do not return a view, do not let middleware append a charset, and do not enable output compression on that route — gzip on an already-compressed PNG is wasted CPU.

Validate barcode payloads, not just types. EAN-13/UPC-A require exactly 12/11 digits (+ checksum), Code 128 has per-symbol rules for non-ASCII, QR has capacity limits at a given EC level. Malformed input either throws deep inside the renderer or — worse — renders a barcode that scans to the wrong value. Validate at the boundary and surface a 422.

Cap dimensions and count. Width/height come from user-controlled options in a naive port; a request for a 20000×20000 PNG is a trivial memory-exhaustion vector (GD allocates the full bitmap). Clamp to sane maxima and rate-limit the endpoint.

Scannability is about module count, not pixel size. Resizing a generated PNG by a non-integer factor blurs module edges and breaks scanners. Generate at the final size, or use SVG output for anything that will be scaled. QR codes need a quiet zone — keep margin >= 1 module, ideally 4 for print.

Never emit raw SVG from user input. If you add an SVG renderer, sanitize or serve it with Content-Disposition: attachment; inline SVG is an XSS vector.

Font/path issues inside vendor. Zend_Barcode's text-drawing renderers locate bundled fonts relative to the library path. Once you relocate or wrap anything, drawText => true may silently render blank. Test text rendering after every dependency bump.

Extension points, if you are porting: the bundle's seams were (a) the barcode type → renderer mapping, (b) per-type option merging, and (c) the Twig function as a thin presentation layer. Rebuild exactly those three as a config array, a factory, and a Blade directive — nothing else in the bundle is load-bearing.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle