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

ozznest/barcode-bundle

A Laravel/PHP barcode bundle for generating and rendering common barcode formats through a simple API, making it easy to add scannable codes to invoices, labels, product catalogs, tickets, and other application workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the reality check. ozznest/barcode-bundle is a Symfony bundle (not a Laravel package), it has zero stars/dependents, and it wraps zendframework/zend-barcode, which was abandoned when Zend Framework became Laminas in 2019. There is no Laravel service provider, no config/barcode.php, and no facade. Treat it as a thin convenience wrapper around Zend\Barcode — you are really evaluating Zend/Laminas Barcode, and in a Laravel app you will almost certainly skip the bundle and use the renderer classes directly.

Minimal steps

  1. Install and see what resolves:

    composer require ozznest/barcode-bundle
    

    If it fails on PHP 8.1+, add a Composer alias so the abandoned package maps to the maintained fork:

    "replace": { "zendframework/zend-barcode": "laminas/laminas-barcode:^2.0" }
    

    and composer require laminas/laminas-barcode.

  2. Verify the renderer works from php artisan tinker:

    $bc = \Laminas\Barcode\Barcode::factory('code128', 'image', ['text' => 'INV-1001']);
    ob_start(); $bc->draw(); $png = ob_get_clean();
    file_put_contents('/tmp/test.png', $png);
    

    Open it. If it renders, the rest is plumbing.

  3. Where to look first in the repo: DependencyInjection/ and Resources/config/services.* — that's the only real logic. Everything else is Zend Barcode. The service id and constructor arguments there are the entire "API surface" you'd be re-implementing.

  4. First use case: an order/invoice barcode endpoint. Wrap the renderer in a small service and a controller:

    // app/Services/BarcodeService.php
    namespace App\Services;
    
    use Laminas\Barcode\Barcode;
    
    class BarcodeService
    {
        public function png(string $text, string $type = 'code128', array $opts = []): string
        {
            $barcode = Barcode::factory($type, 'image', array_merge([
                'text'            => $text,
                'drawText'        => true,
                'factor'          => 2,
                'barHeight'       => 60,
                'withQuietZone'   => true,
            ], $opts));
    
            ob_start();
            $barcode->draw();
            return (string) ob_get_clean();
        }
    }
    
    // routes/web.php
    Route::get('/barcode/{text}', [BarcodeController::class, 'show'])
        ->where('text', '[A-Za-z0-9\-]+');
    
    // controller
    public function show(string $text, BarcodeService $bc)
    {
        return response($bc->png($text), 200, [
            'Content-Type'  => 'image/png',
            'Cache-Control' => 'public, max-age=31536000, immutable',
        ]);
    }
    

    That's the entire "package." Roughly 30 lines, which tells you a lot about its value.

Implementation Patterns

Cache at the edge, not in PHP. Barcode output is deterministic for a given (type, text, options) tuple. Hash the inputs into the URL or an ETag, store the PNG once (S3/local disk), and serve it statically. Rendering is GD work plus an ob_start() round-trip — you don't want it on a hot path.

public function url(string $text): string
{
    $key = 'barcodes/' . md5($text . '|code128') . '.png';
    if (! Storage::exists($key)) {
        Storage::put($key, $this->png($text));
    }
    return Storage::url($key);
}

Blade usage. Either a helper or a route-based <img> — the latter is better because it's cacheable by the browser:

<img src="{{ route('barcode.show', $order->number) }}" alt="Barcode {{ $order->number }}">

Avoid a Blade directive that calls the service inline; you lose HTTP caching and you'll render on every page load.

PDFs / dompdf. dompdf can't execute PHP mid-render, so embed a data URI:

$src = 'data:image/png;base64,' . base64_encode($bc->png($order->number));
// <img src="{{ $src }}">

Watch the PDF memory ceiling — base64 PNGs of large barcodes inflate fast.

Label / bulk printing. Push rendering into a queued job that produces a ZIP or a merged PDF (FPDI or spatie/laravel-pdf), rather than rendering N barcodes in a web request.

QR codes use the same path with Barcode::factory('qr', 'image', ...), but prefer simplesoftwareio/simple-qrcode for QR specifically — Zend's QR renderer predates the modern spec and chokes on UTF-8 (see Gotchas).

Testing. Don't snapshot bytes. Assert the invariants:

$png = app(BarcodeService::class)->png('INV-1001');
$this->assertStringStartsWith("\x89PNG", $png);
$this->assertSame('image/png', (new \finfo(FILEINFO_MIME_TYPE))->buffer($png));
[$w, $h] = getimagesizefromstring($png);
$this->assertGreaterThan(200, $w);

Gotchas and Tips

The bundle will not auto-register in Laravel. Ozznest\BarcodeBundle\OzznestBarcodeBundle is a Symfony\Component\HttpKernel\Bundle\Bundle. Nothing in Laravel reads Resources/config/services.yml. You are re-implementing its DI wiring by hand — which is why the "use Laminas directly" path above is the honest recommendation.

Zend is dead; Laminas is alive. zendframework/zend-barcode has been abandoned since 2019 and is not PHP 8.1+ clean without the replace alias. If you must keep the namespace, use composer replace; if you're doing this fresh, just require laminas/laminas-barcode and never touch the bundle.

draw() echoes. It does not return a string. Forgetting ob_start() dumps raw PNG bytes into an HTML response, which looks like a corrupted page and is genuinely confusing to debug. Always buffer, and use ob_get_clean() without exceptions in between.

GD with FreeType is required for text. drawText => true silently fails (or throws) if GD lacks FreeType. Check extension_loaded('gd') and gd_info()['FreeType Support']. ImageMagick can be used as the renderer backend but is far slower and needs its own setup.

Scanners are unforgiving. A Code128 rendered with default options often looks fine on screen but fails at the till: bars too thin, quiet zone too small, or drawText clipping the digits. Tune factor (bar width multiplier, 2–3 is safe) and barHeight (≥ 50px), and test on a physical scanner or a real scanning app — never by eye.

QR + UTF-8. Zend/Laminas QR encodes as ISO-8859-1. Passing accented characters, emoji, or CJK yields a barcode that scans to mojibake. Either transliterate your input or switch libraries for QR.

No config/barcode.php exists. The Symfony-side configuration lives in the DI extension's Configuration.php and is limited to service definitions — not runtime options. Design your own config file for defaults (type, factor, barHeight, disk) and pass per-call overrides.

Extension points are thin. In Symfony you'd override the service definition. In Laravel, define an interface (BarcodeGenerator) and bind your implementation — that's the seam that lets you swap to picqer/php-barcode-generator or milon/barcode later without touching callers. Given the maintenance status of this package, having that seam is the single most valuable design decision here.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle