Weave Code
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

symfony/filesystem

Symfony Filesystem component offers convenient, robust filesystem utilities for PHP: create, copy, move, remove, chmod, and mirror files/directories, with error handling and cross-platform support. Ideal for safe file operations in Symfony and beyond.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps
1. **Installation**:
   ```bash
   composer require symfony/filesystem:^8.1

No configuration is required—use the Symfony\Component\Filesystem\Filesystem class directly.

  1. First Use Case: Replace native PHP filesystem operations (e.g., mkdir, copy, unlink) with the Filesystem class for cross-platform reliability and mode preservation (new in v8.1.0-BETA2).

    use Symfony\Component\Filesystem\Filesystem;
    
    $fs = new Filesystem();
    $fs->mkdir('path/to/directory'); // Cross-platform path handling
    $fs->copy('source.txt', 'destination.txt', true); // `true` preserves file mode (NEW in v8.1.0-BETA2)
    
  2. Where to Look First:

    • Official Documentation (API reference, examples).
    • Symfony\Component\Filesystem\Filesystem class methods (e.g., dumpFile, exists, remove, mirror).
    • Laravel integration: Use app('filesystem') if wrapping in a Laravel service provider.

Implementation Patterns

Core Workflows

  1. Path Normalization: Use Path helper for cross-platform path manipulation (e.g., joining, normalizing).

    use Symfony\Component\Filesystem\Path;
    
    $path = Path::makeAbsolute('relative/path', '/base/dir'); // Resolves to `/base/dir/relative/path`
    $normalized = Path::normalize('/dir//with/../duplicates'); // `/dir`
    
  2. Directory Operations:

    • Recursively create directories with permissions:
      $fs->mkdir(['dir1/dir2', 'dir3'], 0775); // Sets permissions
      
    • Mirror directories (preserves structure):
      $fs->mirror('source', 'destination'); // Copies recursively
      
  3. File Operations:

    • Atomic writes with mode preservation (NEW in v8.1.0-BETA2):
      $fs->dumpFile('file.txt', 'content'); // Writes atomically
      $fs->copy('source.txt', 'dest.txt', true); // `true` preserves file mode (NEW)
      
    • Temporary files with cleanup:
      $tempFile = $fs->tempnam(sys_get_temp_dir(), 'prefix_');
      $fs->remove($tempFile); // Cleanup
      
  4. File Mode Handling (NEW in v8.1.0-BETA2): Explicitly preserve file permissions during copy/move operations:

    $fs->copy('source.txt', 'dest.txt', true); // Preserves mode
    $fs->move('source.txt', 'dest.txt', true); // Preserves mode (NEW in v8.1.0-BETA2)
    

Laravel Integration Tips

  1. Service Provider Binding: Bind the Filesystem class for dependency injection:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(Filesystem::class, function () {
            return new Filesystem();
        });
    }
    
  2. Artisan Commands: Use in commands for CLI operations (e.g., backups, deployments) with mode preservation:

    use Symfony\Component\Filesystem\Filesystem;
    
    class BackupCommand extends Command
    {
        protected $fs;
    
        public function __construct(Filesystem $fs)
        {
            parent::__construct();
            $this->fs = $fs;
        }
    
        protected function handle()
        {
            $this->fs->mirror(storage_path('app'), backup_path('app'));
            $this->fs->chmod(backup_path('app'), 0755); // Ensure backup dir has correct permissions
        }
    }
    
  3. Event Listeners: Handle filesystem events with mode-aware operations:

    use Symfony\Component\Filesystem\Filesystem;
    
    class HandleUpload
    {
        public function __construct(private Filesystem $fs) {}
    
        public function handle($event)
        {
            $this->fs->copy($event->source, $event->destination, true); // Preserve mode
        }
    }
    
  4. Testing: Use Filesystem in tests to mock filesystem operations, including mode checks:

    public function testFileCopyPreservesMode()
    {
        $fs = $this->createMock(Filesystem::class);
        $fs->expects($this->once())->method('copy')->with('source.txt', 'dest.txt', true);
        // ...
    }
    

Gotchas and Tips

Pitfalls

  1. Windows/Linux Path Quirks:

    • Backslashes on UNIX: Methods like Path::makeAbsolute may incorrectly replace backslashes on UNIX systems (fixed in v8.0.9). Always use forward slashes or DIRECTORY_SEPARATOR.
    • Trailing Slashes: makePathRelative may remove trailing slashes for existing files (fixed in v8.0.6). Use Path::canonicalize for consistency.
  2. Permission Issues:

    • Filesystem::remove() may fail on Windows due to locked files (fixed in v7.1.2). Use try-catch blocks:
      try {
          $fs->remove($file);
      } catch (\RuntimeException $e) {
          // Handle locked files
      }
      
  3. Atomic Writes:

    • dumpFile uses atomic writes, but large files may still cause partial writes on slow storage. For critical data, implement checksum verification.
  4. Temporary Files:

    • Temp files may not clean up on Windows (fixed in v7.1.5). Use tempnam with explicit cleanup or try-finally blocks.
  5. Recursive Operations:

    • mirror and remove can be slow for large directories. Use limitDepth for performance:
      $fs->mirror('source', 'dest', ['limitDepth' => 2]);
      
  6. Mode Preservation Edge Cases (NEW in v8.1.0-BETA2):

    • Symbolic Links: Mode preservation may not work for symlinks. Use lchmod if needed:
      if (is_link('symlink.txt')) {
          lchmod('symlink.txt', 0777);
      } else {
          $fs->copy('source.txt', 'dest.txt', true);
      }
      
    • Sticky Bits: Custom permissions (e.g., setgid) may not be preserved. Use chmod post-copy if required.

Debugging Tips

  1. Path Normalization: Use Path::canonicalize to debug path issues:

    $path = Path::canonicalize('/dir/../relative/path');
    // Outputs: `/relative/path` (absolute)
    
  2. File Existence: Check existence before operations to avoid errors:

    if ($fs->exists('file.txt')) {
        $fs->remove('file.txt');
    }
    
  3. Permissions: Use chmod to debug permission issues or verify mode preservation:

    $fs->chmod('file.txt', 0644); // Set expected mode
    $actualMode = fileperms('file.txt'); // Verify
    
  4. Logging: Enable Symfony’s debug mode to log filesystem operations:

    $fs = new Filesystem();
    $fs->setDebug(true); // Logs operations to stderr
    
  5. Mode Verification (NEW in v8.1.0-BETA2): Verify mode preservation after copy/move:

    $fs->copy('source.txt', 'dest.txt', true);
    $sourceMode = fileperms('source.txt');
    $destMode = fileperms('dest.txt');
    $this->assertEquals($sourceMode, $destMode);
    

Extension Points

  1. Custom Filesystem Adapter: Extend Filesystem for custom storage backends (e.g., S3) with mode handling:

    class CustomFilesystem extends Filesystem
    {
        public function customCopy($source, $dest, $preserveMode = true) {
            if ($preserveMode) {
                $mode = fileperms($source);
                parent::copy($source, $dest, true);
                chmod($dest, $mode);
            } else {
                parent::copy($source, $dest);
            }
        }
    }
    
  2. Event Dispatching: Dispatch events for critical operations (e.g., file creation with mode):

    $fs->copy('source.txt', 'dest.txt', true);
    event(new FileCopied('dest.txt', fileperms('dest.txt')));
    
  3. Path Manipulation: Override Path for project-specific rules or mode-aware paths

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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui