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 Sftp Laravel Package

league/flysystem-sftp

Deprecated since Flysystem 3.0; use flysystem-sftp-v3 instead. Provides an SFTP adapter for Flysystem using phpseclib2. This is a sub-split—issues and PRs belong in the main Flysystem repo. Install via composer require league/flysystem-sftp.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require league/flysystem-sftp
    

    Ensure league/flysystem is also installed (dependency).

  2. Basic Usage

    use League\Flysystem\Filesystem;
    use League\Flysystem\Sftp\SftpAdapter;
    
    $adapter = new SftpAdapter(
        'sftp.example.com',
        22,
        'username',
        'password',
        '/remote/path'
    );
    
    $filesystem = new Filesystem($adapter);
    
  3. First Use Case: Upload a File

    $filesystem->write('local-file.txt', 'Hello, SFTP!');
    
  4. Where to Look First


Implementation Patterns

Common Workflows

  1. Dynamic Connection Handling Use dependency injection (e.g., Laravel’s config()) for credentials:

    $adapter = new SftpAdapter(
        config('sftp.host'),
        config('sftp.port'),
        config('sftp.username'),
        config('sftp.password'),
        config('sftp.root')
    );
    
  2. Streaming Large Files Leverage Flysystem’s streaming API to avoid memory issues:

    $filesystem->writeStream('large-file.zip', fopen('local.zip', 'r'));
    
  3. Directory Operations

    // Create a directory
    $filesystem->createDirectory('new-folder');
    
    // List files
    $contents = $filesystem->listContents('remote/path');
    
  4. Temporary Files Use write() + delete() for atomic operations:

    $filesystem->write('temp.txt', $data);
    // Process file...
    $filesystem->delete('temp.txt');
    

Integration Tips

  • Laravel Storage Integration Extend Filesystem in a custom driver:

    // app/Providers/FlysystemServiceProvider.php
    public function register()
    {
        Storage::extend('sftp', function ($app, $config) {
            $adapter = new SftpAdapter(
                $config['host'],
                $config['port'],
                $config['username'],
                $config['password'],
                $config['root']
            );
            return new Filesystem($adapter);
        });
    }
    

    Configure in config/filesystems.php:

    'disks' => [
        'sftp' => [
            'driver' => 'sftp',
            'host' => env('SFTP_HOST'),
            'port' => env('SFTP_PORT', 22),
            // ...
        ],
    ];
    
  • Retry Logic for Failures Wrap operations in a retry loop (e.g., using spatie/laravel-retryable):

    use Retryable;
    
    class SftpUploader {
        use Retryable;
    
        public function upload($path, $contents)
        {
            retry(5, function () use ($path, $contents) {
                $filesystem->write($path, $contents);
            }, function ($e) {
                return $e instanceof \League\Flysystem\Sftp\Exception\ConnectionException;
            });
        }
    }
    
  • SSH Key Authentication Use setSshKeyPath() for key-based auth:

    $adapter->setSshKeyPath('/path/to/private_key');
    

Gotchas and Tips

Pitfalls

  1. Connection Timeouts

    • Issue: SFTP operations may hang silently.
    • Fix: Set a timeout in the adapter:
      $adapter->setTimeout(10); // 10 seconds
      
    • Debug: Check server logs or enable verbose output:
      $adapter->setSshConnectionOptions([
          'verbose' => STDERR,
      ]);
      
  2. Permission Denied

    • Issue: Permission denied errors often stem from incorrect remote paths or user permissions.
    • Fix: Verify:
      • The remote path exists and is writable.
      • The SFTP user has correct permissions (chmod/chown on the server).
      • The root path in the adapter ends with / (e.g., /home/user/).
  3. Passive Mode

    • Issue: Firewalls may block active mode connections.
    • Fix: Force passive mode:
      $adapter->setSshConnectionOptions([
          'passive_mode' => true,
      ]);
      
  4. File Locking

    • Issue: Concurrent writes can corrupt files.
    • Fix: Use atomic operations (e.g., write() + rename()):
      $filesystem->write('temp.txt', $data);
      $filesystem->rename('temp.txt', 'final.txt');
      

Debugging

  • Enable Verbose Logging
    $adapter->setSshConnectionOptions([
        'verbose' => STDERR,
    ]);
    
  • Check for Deprecated Methods Some older versions of phpseclib (used internally) may trigger deprecation warnings. Update:
    composer require phpseclib/phpseclib:^3.0
    

Extension Points

  1. Custom SSH Options Pass additional phpseclib options:

    $adapter->setSshConnectionOptions([
        'timeout' => 30,
        'compression' => 'zlib',
    ]);
    
  2. Event Listeners Extend the adapter to log operations:

    $adapter->addListener('preWrite', function ($event) {
        logger()->debug('Writing to SFTP', ['path' => $event->getPath()]);
    });
    
  3. Fallback to Local Storage Implement a hybrid storage system:

    $filesystem = new Filesystem(new CacheAdapter(
        new SftpAdapter(...),
        new LocalAdapter(new Filesystem())
    ));
    

Configuration Quirks

  • Port Defaults The adapter defaults to port 22. Omit it if using the standard port.
  • Path Normalization The adapter normalizes paths (e.g., ./file/remote/path/file). Ensure your logic accounts for this.
  • Environment Variables Avoid hardcoding credentials. Use Laravel’s .env or a secrets manager.
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours