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

Filesystem Laravel Package

fidry/filesystem

A tiny wrapper around Symfony Filesystem offering a FileSystem interface and utilities for path escaping, real and normalized paths, and temporary files and directories, including support for custom stream wrappers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require fidry/filesystem
    

    If your application uses Symfony 8 components, require fidry/filesystem 2.0.1 or later, which adds Symfony 8 support:

    composer require fidry/filesystem:^2.0.1
    

    Register the package in config/app.php under providers:

    Fidry\FileSystem\FileSystemServiceProvider::class,
    
  2. Basic Usage: Bind the FileSystem interface in your service container:

    $this->app->bind(FileSystem::class, NativeFileSystem::class);
    

    Or use the static FS helper for quick operations:

    use Fidry\FileSystem\FS;
    
    FS::touch('test.txt'); // Creates a file
    
  3. First Use Case: Replace Laravel’s native filesystem operations (e.g., Storage::put()) with this package for cross-platform path handling:

    $path = FS::escapePath('C:/path/to/file'); // Converts to `C:\path\to\file` on Windows
    FS::dumpFile($path, 'Hello, World!'); // Writes content
    

Implementation Patterns

Dependency Injection

  • Bind the Interface: Prefer dependency injection for testability:
    $this->app->bind(FileSystem::class, function () {
        return new NativeFileSystem();
    });
    
  • Read-Only Mode: Use ReadOnlyFileSystem in tests or read-heavy environments:
    $readOnlyFS = new ReadOnlyFileSystem(failOnWrite: true);
    

Path Handling

  • Cross-Platform Paths: Normalize paths for consistency:
    $normalized = FS::normalizedRealPath('C:\Users\Name\file.txt'); // Returns `C:/Users/Name/file.txt`
    
  • Temporary Files/Directories: Generate safe temp files/dirs:
    $tempFile = FS::tmpFile('upload', '.tmp'); // e.g., `/tmp/upload1234.tmp`
    $tempDir = FS::tmpDir('cache'); // e.g., `/tmp/cache5678`
    

Testing

  • TestCase Integration: Extend FileSystemTestCase for isolated tests:
    class MyTest extends FileSystemTestCase {
        public function test_file_operations() {
            FS::dumpFile('test.txt', 'content');
            $this->assertFileExists('test.txt');
        }
    }
    
  • Mocking SplFileInfo: Use SplFileInfoBuilder to avoid verbose mocks:
    $fakeFile = SplFileInfoBuilder::withTestData()
        ->withFile('test.txt')
        ->withContents('mocked')
        ->build();
    

Finder Integration

  • Custom Finder: Create a Finder instance with the package:
    $finder = FS::createFinder()
        ->files()
        ->in(storage_path('app'));
    
  • Symfony 8 Compatibility: With fidry/filesystem 2.0.1+, Finder integration is compatible with Symfony 8. If you upgrade Symfony components in a Laravel app, verify the package version resolves correctly:
    composer why symfony/finder
    composer update fidry/filesystem --with-dependencies
    

Gotchas and Tips

Pitfalls

  1. Path Normalization:

    • realPath() vs. normalizedRealPath(): The former preserves OS-specific separators (e.g., \ on Windows), while the latter forces /.
    • Fix: Use normalizedRealPath() for consistent paths in logs/URLs.
  2. Temporary Files:

    • tmpFile()/tmpDir() may fail if the target directory lacks write permissions.
    • Fix: Specify a custom directory:
      FS::tmpFile('data', '.tmp', storage_path('framework/cache'));
      
  3. Read-Only Mode:

    • ReadOnlyFileSystem silently ignores writes when failOnWrite: false. Enable failOnWrite: true to catch accidental writes in tests.
  4. Symfony 8 Upgrade Conflicts:

    • Release 2.0.1 adds Symfony 8 support. If your app upgrades to Symfony 8 components, older versions of fidry/filesystem may conflict with symfony/finder or related dependencies.
    • Fix: Require fidry/filesystem:^2.0.1 and update dependencies together.
  5. Symfony Finder SplFileInfo:

    • The getContents() method is deprecated in Symfony 7.1+. With Symfony 8 support in 2.0.1, prefer FS::readFile() instead:
      $content = FS::readFile($filePath);
      

Debugging Tips

  • Path Issues: Use FS::escapePath() to debug cross-platform path inconsistencies.
  • Permission Errors: Check isReadable() before operations:
    if (!FS::isReadable($file)) {
        throw new \RuntimeException("File not readable: {$file}");
    }
    
  • Symfony 8 Compatibility: If Composer resolves an older package version, check the installed version and constraints:
    composer show fidry/filesystem
    composer why symfony/finder
    

Extension Points

  1. Custom Stream Wrappers:

    • Override NativeFileSystem to support custom streams (e.g., S3, SFTP):
      class CustomFileSystem extends NativeFileSystem {
          protected function getStreamWrapper(): string {
              return 's3://';
          }
      }
      
  2. Test Isolation:

    • Override getTmpDirPrefix() in FileSystemTestCase to avoid conflicts:
      protected function getTmpDirPrefix(): string {
          return 'myapp_';
      }
      
  3. Legacy Code:

    • Replace deprecated SplFileInfo::getContents() with FS::readFile() in tests:
      $content = FS::readFile($filePath); // Modern alternative
      

Performance

  • Batch Operations: Use Finder for bulk file operations (e.g., renaming, deleting):
    FS::createFinder()
        ->files()
        ->in($directory)
        ->each(function (SplFileInfo $file) {
            FS::rename($file->getPathname(), $file->getPathname() . '.bak');
        });
    

Laravel-Specific

  • Storage Integration:
    • Replace Laravel’s Storage::disk() calls for filesystem operations:
      $filesystem = app(FileSystem::class);
      $filesystem->put('file.txt', 'content'); // Uses Laravel’s filesystem adapter
      
  • Artisan Commands:
    • Use FS for CLI scripts to avoid DI overhead:
      use Fidry\FileSystem\FS;
      
      FS::mkdir(storage_path('logs/backup'));
      
  • Symfony 8 Upgrades:
    • Laravel apps often inherit Symfony component versions through the framework. Before upgrading Symfony components, ensure fidry/filesystem is at least 2.0.1 to avoid dependency resolution issues with Symfony 8.
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.
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen