knplabs/knp-gaufrette-bundle
KnpGaufretteBundle integrates Gaufrette’s filesystem abstraction into Symfony, letting you configure adapters and filesystems as services. It supports local, in-memory, cloud, and custom adapters for storage-agnostic file handling.
A storage-portability decision, not a feature decision. This bundle is the Symfony integration layer for Gaufrette, a filesystem abstraction library. The product question it answers is: "Can we change where customer files live without changing application code?" That is a de-risking lever for roadmap planning, not a user-facing capability.
Concretely, it supports:
Storage facade with first-party S3 support. So the decision this package actually supports is narrower — "should our Symfony services use Gaufrette while our Laravel services use Flysystem?" Running two abstractions is a real cognitive and maintenance tax. Only adopt if Symfony services genuinely need adapters Flysystem doesn't cover well, or if a shared Gaufrette-based library already exists in the estate.Diligence flags a PM should register before treating this as a foundation:
Adopt when all of the following hold:
filesystem_map — rather than constructed ad hoc in application code. This is the bundle's real differentiator over using Gaufrette directly.Look elsewhere when any of these are true:
Storage/Flysystem. Introducing Gaufrette here is duplicated abstraction for no gain, and it will confuse new hires.Filesystem component or native PHP is sufficient; the abstraction is pure overhead.Suggested adoption gate (a PM-sized checklist): confirm Symfony version support in CI for the next two framework majors; identify who owns upgrades internally; verify whether the adapters you need are actively maintained upstream (Gaufrette + gaufrette/* packages); confirm the license chain (MIT bundle, but check each adapter metapackage's transitive dependencies); and decide explicitly whether "swap storage providers" is a scenario you actually need, or a hypothetical you're paying for.
For executives — the one-liner: "This gives our Symfony applications a single, configurable way to store files — local servers, S3, Azure, SFTP — so we can change storage providers without rewriting application code. The value is optionality and lower switching costs, not new features. It's MIT-licensed and cheap to try, but it's a small, pre-1.0 open-source component from a vendor that is currently looking for maintainers, so we should pilot it on one service rather than standardize across the portfolio. Recommended decision: approve a scoped pilot with a named internal owner for upgrades; revisit standardization after that service has survived one Symfony major upgrade."
Framing the business case in three points:
For engineering — the summary:
"knplabs/knp-gaufrette-bundle is the Symfony integration for Gaufrette, a filesystem abstraction layer. It gives us adapters declared as config and filesystems exposed as injectable services (gaufrette.<name>_filesystem, plus a filesystem_map), so application code depends on Gaufrette's Filesystem interface rather than an SDK. Adapter coverage is the selling point: AsyncAws S3, AWS S3, Google Cloud, Azure, FTP/SFTP/phpseclib, Dropbox, GridFS, Doctrine DBAL, cache, stream wrapper, plus a service adapter for anything custom. Three caveats to design around: (1) it is 0.x, with a real BC break at 0.8.0 — pin versions and read changelogs on every bump; (2) each adapter is a separate metapackage that drags in its vendor SDK, so our dependency and upgrade surface grows with every backend we enable — enable only what we ship; (3) Symfony major support is coupled to this package's release cadence (Symfony 4 dropped, Symfony 7 added in 0.9.0), so it belongs on the same tracking board as framework upgrades. Not applicable to our Laravel services — those should stay on Flysystem behind Storage. If we adopt, adopt it for the Symfony surface only, and don't build shared file-handling code across both."
The honest recommendation to record: treat this as a solved-problem dependency for Symfony workloads with genuine multi-backend needs, evaluated on a single service with a pinned version and a named owner. Do not standardize on it portfolio-wide, and do not adopt it at all if the estate is Laravel-first — in that case the correct answer is Flysystem, and this package's main contribution to the discussion is confirming that Flysystem is the right default.
How can I help you explore Laravel packages today?