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

Flysystem Backblaze Laravel Package

mhetreramesh/flysystem-backblaze

A Flysystem adapter for Backblaze B2 cloud storage that lets PHP and Laravel applications upload, download, list, and delete files through a familiar filesystem API. Configure B2 buckets and use Flysystem streams, metadata, and file operations in your app.

Deep Wiki
Context7

Getting Started

  1. Check the constraints before anything else. This package hasn't been touched since 2016, so its composer.json almost certainly pins league/flysystem to ^1.0 and depends on an old Backblaze B2 SDK (Guzzle 5/6 era). Run composer show mhetreramesh/flysystem-backblaze and inspect vendor/mhetreramesh/flysystem-backblaze/composer.json before installing. If you're on Laravel 9+, stop here — Laravel ships Flysystem 3 and this adapter's AdapterInterface no longer exists.

  2. Install only in a compatible project (Laravel ≤8 / Flysystem 1):

    composer require mhetreramesh/flysystem-backblaze
    
  3. Collect credentials from the Backblaze B2 console: accountId, applicationKey, and the bucket ID (not the bucket name — they're different values and easy to swap). Create a key scoped to the bucket with listFiles, readFiles, writeFiles, deleteFiles capabilities.

  4. First use case: point a Laravel disk at it and store user uploads or nightly database dumps. Register a custom driver in a service provider (see next section), then:

    Storage::disk('b2')->put('backups/'.now()->format('Y-m-d').'.sql.gz', $gz);
    
  5. Look first at src/ in the vendor directory for the exact adapter class name and constructor signature — the README is the only documentation you'll get, and it may not match the code.

Implementation Patterns

Custom Laravel disk via Storage::extend. This is the day-to-day integration. In config/filesystems.php:

'b2' => [
    'driver'     => 'backblaze',
    'accountId'  => env('B2_ACCOUNT_ID'),
    'appKey'     => env('B2_APPLICATION_KEY'),
    'bucketId'   => env('B2_BUCKET_ID'),
],

Then in AppServiceProvider::boot():

Storage::extend('backblaze', function ($app, $config) {
    $client  = new \BackblazeB2\Client($config['accountId'], $config['appKey']);
    $adapter = new \Mhetreramesh\Flysystem\BackblazeAdapter($client, $config['bucketId']);

    return new \League\Flysystem\Filesystem($adapter);
});

Confirm the class names in vendor/ — the constructor may want a bucket name rather than an ID.

Everyday operations go through the normal Storage API once the disk is registered: put, putFile, putFileAs, get, exists, delete, files, allFiles. Streams work if the adapter implements writeStream/readStream; verify with a 50 MB file early, not in production.

Path conventions. B2 is flat object storage with /-delimited keys. Prefix everything by environment and type (prod/uploads/…, staging/…) so a single bucket can serve multiple apps and a mis-scoped delete can't nuke everything. Use date-sharded paths for backups so listContents stays cheap.

Backup command pattern. A scheduled artisan command that dumps MySQL, gzips it, and pushes to B2 is the sweet spot for this package. It's a small file count, sequential writes, and no URL/visibility requirements — all the adapter's weak spots are avoided.

Read-through caching. Wrap the adapter in League\Flysystem\Cached\CachedAdapter with an in-memory or Laravel cache store for metadata-heavy flows (listContents on large prefixes is slow over the B2 API).

Testing. Don't hit B2 in unit tests. Keep a local disk for feature tests, and put adapter behaviour behind a thin repository/service class you can fake. Reserve real-bucket tests for a single integration test run manually.

Gotchas and Tips

  • Laravel 9+ is a hard no. Flysystem 3 replaced AdapterInterface with FilesystemAdapter and split packages. There's no drop-in fix; the realistic migration is the next bullet.
  • Strongly prefer the S3-compatible path for new work. Backblaze B2 exposes an S3 API. Use league/flysystem-aws-s3-v3 with endpoint => https://s3.<region>.backblazeb2.com, use_path_style_endpoint => true, region = your bucket's region, and you get a maintained adapter with multipart uploads, presigned URLs, and full Laravel support. For a greenfield project this package is not worth the risk.
  • Memory blowups on large files. Mid-2010s B2 adapters often read the whole file to compute the required SHA1 and upload in one request. A 2 GB upload can OOM. Test with a file larger than memory_limit / 2.
  • PHP 8 and Guzzle conflicts. The bundled B2 SDK may use removed PHP functions or pin Guzzle 6, clashing with Laravel's Guzzle 7. composer why-not is your friend; there is often no clean resolution.
  • Visibility is bucket-level, not object-level. B2 has no per-file ACL. put($path, $contents, ['visibility' => 'public']) is silently ignored. Public URLs only work if the bucket itself is public; otherwise Storage::url() will be wrong or return false, and you need a download authorization token instead.
  • listContents pagination. B2 returns at most 1000 entries per list call. Old adapters frequently forget to loop, so allFiles() silently truncates. If file counts matter, page manually or verify the adapter handles nextFileName.
  • Exceptions aren't Flysystem exceptions. Network/API failures may bubble up as raw SDK exceptions or generic \Exception, so Storage::exists() can throw instead of returning false. Wrap read paths in try/catch and log the underlying B2 error body.
  • Bucket ID vs bucket name is the single most common setup failure; a "bucket not found" 400 usually means you pasted the wrong one.
  • Debugging: write a 10-line standalone script that constructs the client and lists the bucket before debugging inside Laravel. Enable Guzzle request logging to see the actual HTTP status and B2 error code.
  • Test the delete path carefully. B2 requires both file name and file ID for deletes; if the adapter's has()/delete() round trip is broken, you get orphaned objects you'll pay to store forever.
  • Extension point: if you must stay on Flysystem 1 but need reliability, write a ~200-line wrapper adapter around the B2 SDK yourself — it's a small surface area (write, read, delete, listContents, getMetadata) and you control the error mapping and multipart handling.
  • Fork it. Given 63 stars and no release since 2016, assume no upstream fixes. Vendor the code or fork it under your org so a composer update can't yank it out from under you.
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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
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