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

File Handling Laravel Package

czim/file-handling

Laravel package for structured file handling: store uploads, associate files with Eloquent models, manage storage locations and file variants, and simplify common file operations in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish.

 composer require czim/file-handling
 php artisan vendor:publish --provider="Czim\FileHandling\FileHandlingServiceProvider"

(If the provider tag differs in your version, php artisan vendor:publish and pick the file-handling tag interactively.) The service provider registers the storage manager and merges a config/file-handling.php file.

Where to look first. Open config/file-handling.php. The key section is strategies — named adapters (usually local, and optionally ftp/s3/custom) that map to a storage driver and a base path. Everything else in the package (creating, reading, deleting, storing uploads) resolves through these named strategies, so getting this config right is 80% of the work.

Also read the interfaces under Czim\FileHandling\Storage\Contracts (FileStorageInterface, StoredFileInterface) — that's the real API surface, and it's what you should type-hint and mock against in your own code.

First use case — read and expose a file. Resolve the storage manager, pick a strategy, and get a StoredFile value object:

use Czim\FileHandling\Storage\FileStorage;

$storage = app(FileStorage::class);
$stored  = $storage->file('uploads/avatars/42.jpg'); // strategy is 'local' by default

if ($stored->exists()) {
    $url  = $stored->url();
    $size = $stored->size();
}

The StoredFile object wraps path resolution, URL generation, MIME detection, and deletion — treat it as the primitive you hand around instead of raw paths.

Implementation Patterns

Strategy-as-tenant. Treat each strategy entry as a named bucket/dimension (e.g. public-uploads, private-documents, tmp). Pass the strategy name explicitly at call sites rather than relying on the default; it makes later relocation (local → S3) a config change with zero code churn.

$stored = $storage->strategy('private-documents')->file($path);

Persist paths, not files. Store the strategy name plus relative path on your Eloquent model (storage_disk, storage_path), not the StoredFile object. Rehydrate on read:

public function documentUrl(): ?string
{
    return $this->storage_path
        ? app(FileStorage::class)->strategy($this->storage_disk)->file($this->storage_path)->url()
        : null;
}

Wrap this in a small HasStoredFile trait so every model gets consistent accessors and a deleteFile() hook on deleting.

Upload handling. Use the uploaded-file handler for request files — it centralizes moving the temp file into a strategy and (optionally) generating derivative names:

$stored = $handler->handle($request->file('avatar'), 'public-uploads/avatars');
$model->update(['storage_path' => $stored->path()]);

Keep the handler as a constructor-injected service, not a static call, so you can swap it in tests.

Thin controller, service for orchestration. Controllers should do validation only; put store/delete/replace logic in a domain-level FileService that owns strategy names and naming conventions (hashed names, date subfolders). That's the layer that will survive a storage backend change.

Testing pattern. Because the public surface is interface-based, bind FileStorageInterface to a fake or to a local strategy pointed at a storage/framework/testing path in your test case. Assert on the returned StoredFile (path/existence) rather than filesystem details.

Gotchas and Tips

  • Docs are thin at 15 stars. The README covers the happy path; the source under src/Storage/ and src/UploadedFile/ is your real reference. Read the interfaces before writing against any concrete class — method names between strategies have historically drifted.
  • Strategy config is the trap. Base paths are usually resolved relative to Laravel's filesystem roots; a wrong path in the strategy silently writes to an unexpected directory. Dump config('file-handling') early and confirm the resolved absolute path.
  • StoredFile objects are lightweight wrappers, not handles. Calling url() or size() hits the underlying driver; don't chain them in hot loops. Cache derived values (size, mime) on your model if you display them often.
  • URL generation vs. direct access. For local, url() typically assumes a public symlink (storage:link). Private strategies should go through Storage::temporaryUrl() (or your own controller), not StoredFile::url() — otherwise you'll leak private paths.
  • Deletion is not cascaded. Deleting the model doesn't remove the file. Add the deleting hook; otherwise orphaned files accumulate and are painful to clean up later.
  • Extension points: the cleanest customization is a custom strategy implementing the storage strategy contract, or extending the uploaded-file handler to normalize filenames/extensions. Avoid editing vendor code (obvious, but tempting given sparse docs).
  • Laravel version pinning. Check composer.lock compatibility — old czim packages sometimes pin to specific Laravel/Lumen ranges. If you're on L11+, verify the installed tag actually supports it before building on it.
  • Debugging tip: log the concrete strategy class and resolved path from $storage->strategy('x') when a "file not found" is actually a misconfigured strategy — the exception message doesn't always name the strategy.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource