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

Knp Gaufrette Bundle Laravel Package

short-edition/knp-gaufrette-bundle

Symfony bundle integrating Gaufrette, the PHP filesystem abstraction library. Configure local and remote filesystem adapters as services, inject them into your app, and use Gaufrette's stream wrapper for uniform file access across storage backends.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is not a Laravel package. This is a Symfony Bundle. There is no service provider, no facade, no config/gaufrette.php, no KnpGaufretteBundle::class => ['all' => true] equivalent in bootstrap/app.php. It depends on Symfony's kernel, DI container, and YAML compiler passes. If the target is Laravel, stop reading the "how to use" parts and treat the decision as "use league/flysystem via Laravel's built-in Storage facade instead." Laravel already ships Flysystem; adding a Symfony bundle to that mix is not a migration path, it's a dead end.

If the target is a Symfony app (the only context where any of the rest applies):

  • Install and register. composer require short-edition/knp-gaufrette-bundle, then register the bundle in config/bundles.php alongside the other Symfony bundles. Verify composer.json PHP and Symfony constraints against your composer.json before committing — this fork is old enough that a lockfile mismatch is common.
  • First config block. Create config/packages/knp_gaufrette.yaml with a filesystems: map. Give each fs a name, an adapter, and optional wrappers.
    knp_gaufrette:
        adapters:
            uploads_local: { local: { directory: '%kernel.project_dir%/var/uploads' } }
            media_s3:      { aws_s3: { service_id: 'app.s3_client', bucket: '%env(S3_BUCKET)%' } }
        filesystems:
            uploads: { adapter: uploads_local, stream_wrapper: true }
            media:   { adapter: media_s3,    stream_wrapper: false }
    
  • Where to look first. The fork's README/CHANGELOG, then a diff against upstream knplabs/KnpGaufretteBundle. The whole reason this fork exists should be visible in Filesystem\DependencyInjection\ and the commit log. Do that diff before writing a line of application code.
  • First use case. Inject Gaufrette\Filesystem for one named fs and write a file. Day-to-day operations are write(), read(), has(), delete(), rename(), keys(), mimeType() — same API regardless of backend. If you can write a file to uploads in dev and to media in staging without changing application code, the abstraction is working. If not, the problem is config, not your code.

Implementation Patterns

  • Named filesystem injection. The bundle registers each configured filesystem as gaufrette.<name> and also exposes a FilesystemMap. In a Symfony service, prefer arguments: ['@gaufrette.uploads'] with a Filesystem type-hint. Where there is exactly one fs, alias the type globally so services inject by type. Never call the container directly from a controller.
  • Environment parity is the whole pitch. Define the same named filesystem in dev, test, and prod YAML blocks and let the adapter differ. Dev → local, test → in-memory or a temp dir, prod → S3/GCS. This is the pattern that removes "works locally, fails in CI" defects from file handling, and it is the day-to-day reason to use the bundle at all.
  • One filesystem per domain, not per bucket. uploads, exports, backups, media should be distinct named filesystems even if two share an S3 bucket. That lets you swap an adapter for one domain without touching the others, and it lets the ops team rotate credentials per adapter.
  • Stream wrapper per filesystem, deliberately. Enable stream_wrapper: true only where PHP-native functions will be used (e.g. getimagesize('gaufrette://media/thumb.jpg')). Leave it off for filesystems that will only ever be touched through the Filesystem object — fewer moving parts, fewer boot-time registration surprises.
  • Cache wrapper for read-heavy adapters. Wrap an S3 adapter in a Cache (APCu or Redis) when the same files are stat'd or listed repeatedly (gallery listings, template thumbnails). Do not wrap adapters that receive writes from outside the app — the cache goes stale immediately.
  • Checksum wrapper only where it matters. Enable Checksum on archives and backup filesystems where you need hash verification, and disable it elsewhere — it costs an extra read per file.
  • Exploit lazy-loaded adapters. The bundle defers adapter construction, so declaring an S3 filesystem in config does not hit S3 at boot. This means you can safely configure a filesystem that is only used on one code path without paying a connection cost on every request.
  • Testing. In config/packages/test/knp_gaufrette.yaml, point every filesystem at local (or in-memory) inside var/cache/test/. Never test against S3 in CI. If a test needs an fs that doesn't exist in test config, add it rather than mocking the Filesystem — mocking a filesystem abstraction is almost always the wrong tool.

Gotchas and Tips

  • Ecosystem mismatch is the headline risk. This is Symfony-only, and it's a zero-star fork of knplabs/KnpGaufretteBundle. For a Laravel roadmap the equivalent is Flysystem; for a greenfield Symfony roadmap the equivalent is league/flysystem-bundle. Adopt this bundle only when an existing Symfony codebase is already on Gaufrette.
  • Provenance must be verified before pinning. Zero stars and zero dependents means you are the only audience. Diff against upstream, identify the fork's patch, and pin to a commit SHA rather than a tag. If the diff is trivial, use upstream directly. If the diff is non-trivial, vendor the fork under your own org and assign an owner.
  • Upstream has effectively ceded to Flysystem. Budget for this being your code. Every Symfony major is a potential break site because the bundle ships DI service definitions and compiler passes, which are the most version-sensitive surfaces in Symfony.
  • Silent adapter misconfiguration. Lazy loading means an S3 endpoint or credential error surfaces on first use mid-request, not at boot. In dev, add a one-line health check (e.g. $fs->has('.health')) behind a console command so misconfiguration fails loudly and early.
  • Stream wrapper registration order. gaufrette:// wrappers are registered during kernel boot, and CLI vs FPM can behave differently if the bundle boots differently in each. If file_exists('gaufrette://media/x') silently returns false, run php -r 'print_r(stream_get_wrappers());' and confirm gaufrette is registered before debugging your code.
  • Metadata cache staleness is the classic production bug. Another service uploads a file, the app still lists the old directory. Namespace the cache per environment, set a short TTL for write-heavy filesystems, and document that external writes invalidate nothing. This is the #1 "works until it doesn't" failure mode with the cache wrapper enabled.
  • gaufrette.<name> IDs are derived from YAML keys. Rename a filesystem in config and every hardcoded @gaufrette.<name> reference in services silently breaks at runtime rather than at compile time. Keep the name in one constant or a thin domain wrapper service if the name appears anywhere outside the YAML.
  • The Filesystem interface is lowest-common-denominator. Presigned URLs, multipart upload tuning, S3 lifecycle rules, object lock, GCS IAM — none of them are exposed. When you need them you will reach through the adapter to the native client and bypass the abstraction, which is the worst of both worlds. Decide up front which operations stay on the abstraction and which legitimately use the SDK directly, and document that split.
  • Local adapter user/UMASK mismatch. A filesystem writable by the PHP-FPM user is often not writable by the CLI user running bin/console. When "it works in web but not in commands" shows up, check posix_getpwuid(posix_geteuid()) in both contexts and align directory ownership.
  • Fork divergence risk is ongoing, not a one-time check. If the fork carries a patch, put it in an ADR, rebase quarterly against upstream, and define the exit trigger ("drop the fork when upstream merges X"). Without that, the patch quietly rots and the security review window closes.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin