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

Php File Interface Laravel Package

php-extended/php-file-interface

php-extended/php-file-interface provides PHP contracts for file and directory abstractions, covering paths, metadata, content access, and filesystem operations. It enables consistent, implementation-agnostic file handling across compatible php-extended packages.

View on GitHub
Deep Wiki
Context7

Getting Started

php-extended/php-file-interface is an interfaces-only package. composer require php-extended/php-file-interface installs a set of PHP contracts (namespace PhpExtended\File\) that model files, directories, paths and file systems — there is no working filesystem code in the box. The first thing to internalise is that this is a ports library: it exists so your application code can stop depending on fopen, SplFileObject, Illuminate\Filesystem\Filesystem or Flysystem directly.

Minimal steps:

composer require php-extended/php-file-interface

Then look at the interface sources in vendor/php-extended/php-file-interface/src/ before writing anything. Start with, in this order:

  1. FileInterface — the single-file contract (contents, name, extension, size, timestamps, copy/move/delete).
  2. DirectoryInterface — listing and creating entries.
  3. FilesystemInterface / FileSystemInterface — the entry point that resolves a path string into a FileInterface or DirectoryInterface.
  4. PathInterface — normalisation, parents, segments, extensions.

Before coding against them, decide which implementation you will bind — either the sibling concrete package from the same vendor (php-extended/php-file), or a thin adapter you write over Laravel's filesystem/Flysystem. Without one, every type-hint resolves to nothing at runtime.

First use case — inject the filesystem, don't construct it:

use PhpExtended\File\FilesystemInterface;
use PhpExtended\File\FileInterface;

final class InvoiceArchiver
{
    public function __construct(private FilesystemInterface $filesystem) {}

    public function store(string $path, string $contents): FileInterface
    {
        $file = $this->filesystem->getFile($path);
        $file->write($contents);   // verify exact method name in the interface source

        return $file;
    }
}

Bind the interface once in a service provider, and from that point the rest of the application never touches a raw path.

Implementation Patterns

Ports and adapters, bound in the container. The canonical Laravel wiring is a single binding in AppServiceProvider:

$this->app->singleton(
    \PhpExtended\File\FilesystemInterface::class,
    fn () => new NativeFilesystemAdapter(base_path())   // your implementation
);

Everything downstream — controllers, jobs, console commands — type-hints the interface. Swapping local disk for an in-memory or test implementation becomes a one-line change.

Adapter over what you already have. Because the package ships no behaviour, the highest-value pattern is a small adapter class per interface, delegating to Illuminate\Filesystem\Filesystem or a Flysystem FilesystemOperator. Keep the adapter dumb: translate method calls, translate exceptions, nothing else.

Decorators instead of configuration. Interfaces are the natural seam for cross-cutting file concerns, and this is where the package earns its keep day-to-day:

  • ReadOnlyFile implements FileInterface — delegates reads, throws on writes.
  • SandboxedFilesystem implements FilesystemInterface — rejects paths escaping a configured root (a path-jail), which is the single most useful decorator for anything touching user-supplied filenames.
  • LoggingFilesystem / CachingFilesystem — record every mutation, or memoise metadata lookups during a long import.

All of these compose without touching your domain code.

Iteration and bulk operations. Use DirectoryInterface plus the iterator/visitor/filter interfaces (where present in the package) for scans, cleanups and imports rather than glob()/scandir(). A job that walks a directory tree through the interfaces can be tested against a fake in-memory tree with three or four files instead of fixture directories on disk.

Path handling through PathInterface. Resolve, normalise and inspect paths via the interface rather than str_replace('//', '/') and explode('/'). It keeps Windows separators, trailing slashes and .. segments in one place instead of scattered across the codebase.

Testing. This is the strongest day-to-day argument for the package. Unit tests implement the interface inline (or with an anonymous class) to simulate a missing file, a permission error or a full disk — cases that are painful to reproduce against a real filesystem. Feature tests can bind an in-memory implementation and assert on recorded writes.

Gotchas and Tips

  • It is interfaces only — nothing runs. The most common first-hour mistake is requiring this package and expecting to read a file. Plan for the implementation dependency up front; if you don't want the vendor's concrete package, budget a day for adapters.
  • Zero dependents means zero community validation. There is no Stack Overflow corpus, no third-party tutorials, and no guarantee that the interface set matches your mental model. Read the source; treat the interfaces as the spec and your adapters as the code you own.
  • Fat interfaces mean boilerplate. Some contracts bundle a lot of members. A full Flysystem adapter may need thirty stub methods you never call. Either implement only the narrow interfaces you actually use, or put the stubs in a trait/abstract base so the noise lives in one file.
  • Name collisions are real. PhpExtended\File\FilesystemInterface vs Illuminate\Contracts\Filesystem\Filesystem vs Symfony's Finder will bite you in any file that touches both. Alias on import (use PhpExtended\File\FilesystemInterface as FsPort;) and keep adapters in their own namespace so collisions never reach domain code.
  • Don't let vendor exceptions leak. Check which exception types the contracts declare and what your adapter can throw. Wrap implementation-specific exceptions (Flysystem's UnableToWriteFile, PHP warnings) at the adapter boundary, otherwise swapping the implementation breaks catch blocks everywhere.
  • Path semantics live in the implementation, not the interface. Absolute vs relative, symlink following, trailing-slash tolerance and case sensitivity are unspecified behaviour. Write a small conformance test suite once and run it against every implementation and decorator you build — it will save you when you switch backends.
  • Remote storage is not modelled. S3-style concerns (streaming, visibility, presigned URLs, eventual consistency) don't map cleanly onto a local-filesystem-shaped interface. If remote disks are in scope, keep Flysystem underneath and expose only the subset of operations your domain genuinely needs.
  • Debugging is shallow by design. Stack traces terminate in your adapter, since interfaces contain no logic. BindingResolutionException on an interface type-hint almost always means the service provider binding is missing or misspelled — check ::class constants rather than string class names.
  • Pin versions. A small, low-traffic package can change signatures between minor releases without a loud deprecation cycle. Use exact or tilde constraints and run static analysis (PHPStan/Psalm) at a decent level — the interfaces are your only compile-time guarantee, so let the analyser enforce them.
  • Prefer extension over forking. New behaviour belongs in a decorator that implements the interface. Forking the contract package fragments your types and makes every adapter incompatible with the ecosystem.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager