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

Flysystem Laravel Package

league/flysystem

League/Flysystem is a filesystem abstraction for PHP that provides a consistent API for local disks and cloud storage like S3. Swap adapters without changing your app, with support for reading/writing files, directories, visibility, and streams.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/flysystem
    

    For a specific adapter (e.g., AWS S3):

    composer require league/flysystem-aws-s3-v3
    
  2. Basic Usage:

    use League\Flysystem\Filesystem;
    use League\Flysystem\Adapter\Local;
    
    $adapter = new Local('/path/to/storage');
    $filesystem = new Filesystem($adapter);
    
    // Write a file
    $filesystem->write('file.txt', 'Hello, Flysystem!');
    
    // Read a file
    $contents = $filesystem->read('file.txt');
    
  3. First Use Case: Replace direct filesystem operations (e.g., file_put_contents, fopen) with Flysystem methods. For example:

    // Instead of:
    file_put_contents('/path/to/file.txt', 'content');
    
    // Use:
    $filesystem->write('file.txt', 'content');
    

Key Entry Points

  • Adapters: Define how files are stored (e.g., Local, S3, SFTP).
  • Filesystem: The main class wrapping adapters with a unified API.
  • MountManager: For managing multiple filesystems under a single interface.
  • Decorators: Extend functionality (e.g., Visibility, Cache).

Implementation Patterns

Core Workflows

  1. File Operations:

    // Write, read, delete
    $filesystem->write('file.txt', 'content');
    $content = $filesystem->read('file.txt');
    $filesystem->delete('file.txt');
    
    // Check existence
    if ($filesystem->has('file.txt')) {
        $size = $filesystem->size('file.txt');
    }
    
  2. Directory Operations:

    // Create, list, delete
    $filesystem->createDirectory('folder');
    $contents = $filesystem->listContents('folder');
    $filesystem->deleteDirectory('folder');
    
  3. Metadata and URLs:

    // Get metadata
    $metadata = $filesystem->metadata('file.txt');
    
    // Generate public URLs (if supported by adapter)
    $url = $filesystem->url('file.txt');
    
    // Temporary URLs (e.g., for S3)
    $tempUrl = $filesystem->temporaryUrl('file.txt', Carbon::now()->addHour());
    

Integration Tips

  1. Service Providers: Bind adapters and filesystems in Laravel’s AppServiceProvider:

    public function register()
    {
        $this->app->singleton('filesystem.s3', function ($app) {
            $client = new Aws\S3\S3Client([
                'version' => 'latest',
                'region'  => 'us-east-1',
                'credentials' => [
                    'key'    => env('AWS_KEY'),
                    'secret' => env('AWS_SECRET'),
                ],
            ]);
            $adapter = new AwsS3V3($client, 'bucket-name');
            return new Filesystem($adapter);
        });
    }
    
  2. MountManager for Multiple Filesystems:

    use League\Flysystem\MountManager;
    
    $mountManager = new MountManager([
        'local' => new Filesystem(new Local('/path/to/local')),
        's3'    => new Filesystem(new AwsS3V3($client, 'bucket-name')),
    ]);
    
    // Use dynamically
    $mountManager->getAdapter('s3')->write('file.txt', 'content');
    
  3. Decorators for Cross-Cutting Concerns:

    use League\Flysystem\Cached\CachedAdapter;
    
    $adapter = new Local('/path/to/storage');
    $cachedAdapter = new CachedAdapter($adapter, new FilesystemCache());
    $filesystem = new Filesystem($cachedAdapter);
    
  4. Streaming Large Files:

    // Write a stream (e.g., from a database blob or HTTP request)
    $filesystem->writeStream('large-file.zip', fopen('php://temp', 'r+', 0, 1024 * 1024));
    
    // Read a stream
    $stream = $filesystem->readStream('large-file.zip');
    

Laravel-Specific Patterns

  1. Filesystem Disks: Configure in config/filesystems.php:

    'disks' => [
        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'bucket' => 'your-bucket',
            'region' => 'us-east-1',
        ],
    ],
    

    Use via the Storage facade:

    Storage::disk('s3')->put('file.txt', 'content');
    
  2. Temporary URLs:

    $tempUrl = Storage::disk('s3')->temporaryUrl(
        'file.txt',
        now()->addMinutes(15),
        ['response-content-disposition' => 'attachment']
    );
    
  3. Symlinks:

    // Create a symlink (if adapter supports it)
    $filesystem->createSymlink('source.txt', 'link.txt');
    

Gotchas and Tips

Common Pitfalls

  1. Path Normalization:

    • Flysystem normalizes paths (e.g., converts \ to / on Windows). Ensure paths are consistent.
    • Fix: Use DIRECTORY_SEPARATOR or let Flysystem handle it:
      $filesystem->write('folder' . DIRECTORY_SEPARATOR . 'file.txt', 'content');
      
  2. Visibility Retention:

    • By default, copy() and move() may not retain visibility (e.g., public/private on S3). Configure explicitly:
      $adapter = new AwsS3V3($client, 'bucket', [
          'visibility' => 'public',
          'retain_visibility' => true,
      ]);
      
  3. Directory Listing Quirks:

    • Some adapters (e.g., S3) may return top-level directories in listings. Use listContents() carefully:
      $contents = $filesystem->listContents('folder', true); // Recursive
      
  4. Checksum Mismatches:

    • Adapters may not support all checksum algorithms. Handle exceptions:
      try {
          $checksum = $filesystem->checksum('file.txt');
      } catch (ChecksumAlgoIsNotSupported $e) {
          // Fallback to ad-hoc generation
      }
      
  5. Connection Leaks:

    • Adapters like SFTP or FTP may hold open connections. Explicitly disconnect:
      $adapter->disconnect();
      

Debugging Tips

  1. Enable Verbose Logging:

    • For adapters like SFTP, enable debug logging:
      $adapter = new SftpV3('host', 'user', 'pass', [
          'debug' => true,
      ]);
      
  2. Handle Exceptions:

    • Catch adapter-specific exceptions (e.g., ConnectionException, UnableToListContents):
      try {
          $filesystem->listContents('folder');
      } catch (UnableToListContents $e) {
          Log::error('Failed to list contents: ' . $e->getMessage());
      }
      
  3. Path Prefixing:

    • If using PathPrefixingAdapter, ensure paths are prefixed correctly:
      $adapter = new PathPrefixingAdapter(new Local('/base'), 'prefix/');
      

Extension Points

  1. Custom Adapters:

    • Extend League\Flysystem\Adapter\AbstractAdapter or use DecoratedAdapter:
      class CustomAdapter extends AbstractAdapter {
          public function write($path, $contents, Config $config) {
              // Custom logic
          }
      }
      
  2. URL Generators:

    • Implement League\Flysystem\UrlGenerator\UrlGeneratorInterface for custom URL schemes:
      class CustomUrlGenerator implements UrlGeneratorInterface {
          public function generate(string $path): string {
              return "https://custom.cdn/$path";
          }
      }
      
  3. Event Dispatching:

    • Use events (e.g., preWrite, postDelete) via decorators or middleware:
      $adapter = new EventedAdapter(new Local('/path'), new EventDispatcher());
      
  4. Async Operations:

    • For async adapters (e.g., AsyncAwsS3), handle promises:
      $adapter->writeAsync('file.txt', 'content')->then(
          function () { /* Success */ },
          function ($e) { /* Failure */ }
      );
      

Configuration Quirks

  1. AWS S3:
    • Ensure ListObjectsV2 is used (not ListObjects) for pagination:
      $adapter
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport