Abstraction for local and remote filesystems

Overview

League\Flysystem

Author Source Code Latest Version Software License Quality Assurance Total Downloads php 7.2+

About Flysystem

Flysystem is a file storage library for PHP. It provides one interface to interact with many types of filesystems. When you use Flysystem, you're not only protected from vendor lock-in, you'll also have a consistent experience for which ever storage is right for you.

Getting Started

Commonly-Used Adapters

Third party Adapters

You can always create an adapter yourself.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Enjoy

Oh, and if you've come down this far, you might as well follow me on twitter.

Comments
  • Empty Object for zip

    Empty Object for zip

    I get empty Zip object after writing the content from local to zip adapter. No files are listed for the zip object where the source has files.

    Is there any other way to make the object to save the file instead of using null.

    Sorry again for all the trouble.

    $local = new Filesystem(new Local("C:\wamp\www\oxwall\watermark"));
    $zip = new Filesystem(new Zip($zipFilename));
    
    $contents = $local->listContents();
    
    foreach ($contents as $info) {
        if ($info['type'] === 'dir') {
            continue;
        }
    
        $zip->write($info['path'], $local->read($info['path']));
    }
    var_dump($zip->listContents());
    $zip = null;
    
    opened by Purus 50
  • [FTP Driver] Support for implicit SSL

    [FTP Driver] Support for implicit SSL

    Hello,

    current ftp implementation supports only explicit SSL and does not work with implicit SSL connection, which is by default uses 990 port.

    Also, there is no support for implicit SSL in PHP. Research gave me only solution using curl.

    I can make pull request to make implicit SSL connection work using curl. Or community can provide another options?

    opened by vyuldashev 39
  • Download/Upload-Progress

    Download/Upload-Progress

    When working with mid-size or large files it's actual always required to have a kind of progress information. Especially, when the server has not a big bandwidth or the connection is pretty busy and you want to inform your client/user with a progress-bar while uploading/downloading.

    What do you think about providing such a API? I don't know whether all adapters are able to support that or if we have to emulate it somehow.

    I guess a event-based system would be a good method to achieve that.

    Example:

    $fs = new Filesystem();
    $fs->on('upload', function($bytes, $totalBytes, $path){
        echo sprintf("%s: %d of %d\n", $path, $bytes, $totalBytes);
    });
    
    $fs->write('bla', 'hossa');
    

    What do you think?

    enhancement 
    opened by marcj 39
  • Upload large file (> 1GB) with a local adapter.

    Upload large file (> 1GB) with a local adapter.

    I am trying to upload a large file (> 1GB) with a local adapter.

    I am working on Directus https://github.com/directus/api, an opensource headless CMS.

    I am using Slim as a backend framework.

    There is not a specific example of a handling file for slim in the documentation https://flysystem.thephpleague.com/docs/guides/uploads/ So I am following the guide for Plain PHP Upload

    I am getting 500 error for the fopen as the file size is large.

    I search the repo issues and try to use the readStream and writeStream method as suggested. But unfortunately, I am not able to find the correct solution.

    Any reference code example or other resources will be really helpful.

    Thanks a lot for such an amazing package. 😊

    opened by hemratna 30
  • Problem for big files - PHP Fatal error:  Out of memory

    Problem for big files - PHP Fatal error: Out of memory

    Hello,

    i m using flysystem but i can used it for files with 350 MO i have this error ,

    PHP Fatal error:  Out of memory (allocated 763101184) (tried to allocate 380559298 bytes) in /var/www/script/vendor/league/flysystem/src/Adapter/Zip.php on line 64
    
    Fatal error: Out of memory (allocated 763101184) (tried to allocate 380559298 bytes) in /var/www/script/vendor/league/flysystem/src/Adapter/Zip.php on line 64
    
    

    what i can do please :

    opened by ghost 25
  • [READY] Use Any Adapter As Cache

    [READY] Use Any Adapter As Cache

    I've added the ability to use any adapter to cache to. I haven't added any tests yet. Once I get your feedback, I can either close this (if you reject the idea), or modify it (if you want parts changed), then write tests.

    Useage case: I am reading files from dropbox, but don't want to have to cache them to memory. Now I can cache them to the disk using the local filesystem adapter as a cache.

    TODO:

    • [x] Add cache adapter
    • [x] Get the approval of @FrenkyNet
    • [x] Make adjustments
    • [x] Add documentation
    • [x] Add tests
    opened by GrahamCampbell 25
  • Problems with FTP adapter

    Problems with FTP adapter

    I'm trying to use this library to connect to a WS_FTP server. I encounter the same problem I had some time ago with the PHP FTP functions: directory listing, file getting/putting only work if filepaths are sent to the FTP connection with double quotes (") around.

    windows ftp 
    opened by zupolgec 23
  • Trying to access array offset on value of type bool

    Trying to access array offset on value of type bool

    Bug Report

    Error when using streams and S3 on php 7.4 Works fine on php 7.3 But breaks on php 7.4

    How to reproduce

    Upload a file to s3 using fopen

    Storage::disk('some-s3-disk');
    $disk->put('test.jpg', fopen($imageUrl, "r"));
    
    // Works fine
    // $disk->put('test.jpg', file_get_contents($mageUrl));
    
    php74
    opened by bjora857 22
  • FTP ssl problem

    FTP ssl problem

    Hi,

    I am using Laravel 5.2 with the Storage adapter for connecting to a FTP server with SSL. I am getting this error and don't know why...

     [ErrorException]
      ftp_rawlist(): SSL read failed
    
    PHP Fatal error:  Uncaught ErrorException: fclose(): supplied resource is not a valid stream resource in /home/test/public_html/vendor/league/flysystem/src/Adapter/Ftp.php:495
    Stack trace:
    #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'fclose(): suppl...', '/home/test/...', 495, Array)
    #1 /home/test/public_html/vendor/league/flysystem/src/Adapter/Ftp.php(495): fclose(Resource id #209)
    #2 /home/test/public_html/vendor/league/flysystem/src/Adapter/Ftp.php(191): League\Flysystem\Adapter\Ftp->isConnected()
    #3 /home/test/public_html/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php(609): League\Flysystem\Adapter\Ftp->disconnect()
    #4 [internal function]: League\Flysystem\Adapter\AbstractFtpAdapter->__destruct()
    #5 {main}
      thrown in /home/test/public_html/vendor/league/flysystem/src/Adapter/Ftp.php on line 495
    

    This is my config "config/filesystems.php":

    'ftp' => [
                'driver'   => 'ftp',
                'host'     => env('FTP_SERVER'),
                'port'     => env('FTP_PORT'),
                'username' => env('FTP_USERNAME'),
                'password' => env('FTP_PASSWORD'),
                'passive'  => true,
                'ssl'      => true,
                'timeout'  => 30,
                'root'     => '/',
            ],
    

    This is my code:

    Storage::disk('ftp')->allFiles();
    

    My config is correct and I tested it on 2 machines, both giving the same error... Before I used FuelPHP and never had any problems with FTP SSL...

    opened by it-can 21
  • Exception thrown by Local driver attempting to create directory in quick succession

    Exception thrown by Local driver attempting to create directory in quick succession

    I have an application where I allow a user to pick multiple files for upload from a web form. These are then submitted individually and asynchronously using jQuery and HTML FormData.

    If I have several small files submitting at once, it is possible that the server arrives at Local::ensureDirectory() almost simultaneously and the if ( ! is_dir($root)) check returns an incorrect result.

    This can result in an ErrorException "mkdir(): File exists". I'm not sure you can reproduce the error without my app, but steps would be:

    • Laravel 5.2 app running on local Vagrant Homestead instance with PHP7
    • Multiple async submissions to a route which should result in creation of a directory that does not yet exist
    • Produces exception below:

    screen shot 2016-03-24 at 13 40 53

    This may well be a PHP problem and/or Vagrant not running fast enough in a local environment, but I wonder if it's possible to mitigate, perhaps wrapping in try/catch that looks for the "File exists" message? I've checked the Exception thrown for other problems such as permissions and unfortunately it's identical apart from the message - and I guess that may change in different languages.

    opened by dmlogic 20
  • Introduce a common exception for failed commands

    Introduce a common exception for failed commands

    This is somewhat related to #611.

    If I try to write a file on S3 using Flysystem, and a connection problem occurs, I get an S3 exception:

    Aws\S3\Exception\S3Exception: Error executing "PutObject" on ...

    For Dropbox, I get a (subclass of) Dropbox\Exception.

    First of all, these adapters do not respect the AdapterInterface contract by allowing an exception to be thrown, instead of returning false on failure.

    Secondly, I would suggest throwing an exception in all cases when something goes wrong on the underlying storage. And to keep code portable (i.e. allowing to change the storage adapter at the flip of a switch), this exception should belong to the Flysystem package.

    At the moment, I have to do:

    try {
        $filesystem->write($path, $contents);
    } catch (S3Exception $e) {
        // ...
    }
    

    If I decide to switch to Dropbox, I have to search through my entire codebase for Flysystem calls, and update them to something like:

    try {
        $filesystem->write($path, $contents);
    } catch (Dropbox\Exception $e) {
        // ...
    }
    

    And if I'm writing an app that can accept any adapter, using information from a config file, I have to take all possible errors into account:

    try {
        $filesystem->write($path, $contents);
    } catch (S3Exception $e) {
        // ...
    } catch (Dropbox\Exception $e) {
        // ...
    }
    

    And so on, without forgetting any adapter. As you can see, this is not a very good practice.

    Introducing a common interface for these errors would allow us to call:

    try {
        $filesystem->write($path, $contents);
    } catch (AdapterException $e) {
        // ...
    }
    

    This way, there is no need to rewrite any code when switching to another adapter.

    As I understand the project in its current status, you decided to return false in some methods, when something goes wrong. The fact is, the few adapters I had a chance to look at do not respect this contract properly (S3 and Dropbox thrown their own exceptions, Ftp and Local raise PHP errors).

    There are two solutions to this problem:

    • Fix all the adapters to catch any exception or error (including PHP warnings for adapters relying on native functions) and return false where appropriate
    • Change the contract to never return false on methods such as write(), and throw an AdapterException on failure instead

    I would strongly suggest the second option, because it breaks the application flow when something goes wrong; otherwise an error could go unnoticed if the developer forgets to check the return value using something like:

    if (! $fs->write($path, $contents)) {
        ...
    }
    

    Plus, although returning false gives an opportunity to catch failures on operations such as write(), there is no such opportunity on methods that return boolean values, such as has().

    Having all of them throw an exception in case of a failure harmonizes the whole thing.

    Happily waiting for your feedback on this one. I could help rewrite the code if you agree with the idea!

    opened by BenMorel 19
  • Chunk s3 delete calls when deleting huge directories with AsyncAws

    Chunk s3 delete calls when deleting huge directories with AsyncAws

    Fixes https://github.com/thephpleague/flysystem/issues/1615

    As stated in the linked issue AsyncAws is dumb and does no chunking, in the AsyncAws Adapter we also loop over all objects in a "directory", and create one big delete request for all objects.

    This may lead to issues if to many objects should be deleted in one request, as stated in the linked issue. IMHO as AsyncAws already loops through all objects in a "directory" it should also chunk the created delete commands accordingly.

    I'm not sure about the exact chunk size we should use, locally trying to delete a dir with ~5.000 objects failed, using a chunk size of 1.000 worked so I used that.

    We can also think about making the chunk size configurable, but i'm not sure if that is really needed.

    opened by keulinho 0
  • Flysystem-ftp does not take date-format correctly into account for previous year

    Flysystem-ftp does not take date-format correctly into account for previous year

    Bug Report

    | Q | A | |-------------------|---------| | Flysystem Version | 3.0.0 | | Adapter Name | ftp | | Adapter version | 3.0.0 |

    Summary

    Incorrect timestamp. Does not take future dates into account

    How to reproduce

    Since the FTP protocol is broken, the date of files modified in the previous year is not correctly parsed.

    Example output: -r--r--r-- 1 xxx.com xxx.com 994 Oct 11 06:07 .foo This file was modified on october 11 2022, but Flysystem returns October 11 2023.

    Instead on https://github.com/thephpleague/flysystem/blob/fde17dd335b3bd1d1eb6f43070c1cfd5f64f7e73/src/Ftp/FtpAdapter.php#L460 if $dateTime->getTimestamp() is in the future, then the date should be assumed to be in the previous year, not the current.

    opened by tomsommer 0
  • Moving and Copying folder

    Moving and Copying folder

    Feature Request

    Flysystem v3 should support moving and copying folders by default. Currently, also not possible with S3. See also: https://github.com/thephpleague/flysystem/pull/1482

    opened by tinect 2
  • Flysystem/FtpAdapter specific exception should be thrown when root ftp directory does not exist

    Flysystem/FtpAdapter specific exception should be thrown when root ftp directory does not exist

    Bug Report

    | Q | A | |-------------------|---------| | Flysystem Version | 3.12.0 | | Adapter Name | FtpAdapter | | Adapter version | 3.10.3 |

    Summary

    TypeError is thrown when trying to write a file and $rootDirectory is null (and it's null if the root directory doesn't exist)

    How to reproduce

    $fs = new Filesystem(new FtpAdapter(/* options object with non-existing root directory */))
    $fs->write('test', '');
    

    It throws TypeError: ftp_chdir(): Argument #2 ($directory) must be of type string, null given exception in https://github.com/thephpleague/flysystem-ftp/blob/3.x/FtpAdapter.php#L101, although I'm not sure how it's even possible - it initially sets rootDirectory to $this->resolveConnectionRoot($this->connection) which can't return null...

    Anyway it somehow happens in my app and I think that it should check in line 101 whether $this->rootDirectory is not null before calling ftp_chdir and throw for example FtpConnectionException exception instead of TypeError

    opened by jacekkarczmarczyk 0
  • Unable to delete a folder with many files using AsyncAWS

    Unable to delete a folder with many files using AsyncAWS

    Bug Report

    | Q | A | |-------------------|---------| | Flysystem Version | 3.10.4 | | Adapter Name | async-aws| | Adapter version | 3.10.3 |

    Summary

    Unable to delete a large folder. Deleting some files by UI then deleting the whole folder works (Maybe some pagination issues?)

    (Used Minio)

    In Response.php line 422:
                                                                                                           
      HTTP 400 returned for "http://127.0.0.1:9000/asset?delete=".                                         
                                                                                                           
      Code:    MalformedXML                                                                                
      Message: The XML you provided was not well-formed or did not validate against our published schema.  
      Type:                                                                                                
      Detail:
    

    How to reproduce

    Create a folder with 5k files and try to delete them

    needs more input 
    opened by shyim 4
  • LocalFilesystemDriver::listContents() is unusable for real workloads

    LocalFilesystemDriver::listContents() is unusable for real workloads

    Bug Report

    | Q | A | |-------------------|---------| | Flysystem Version | all | | Adapter Name | Local | | Adapter version | all |

    Summary

    Using DirectoryIterator is problematic. The listing is obtained (see php-src/ext/spl_directory.c) by spl_filesystem_dir_open() immediately, then cached. So that when someone iterates on the result, it is guaranteed to be outdated.

    The symptom superficially matches that of #472.

    RuntimeException: SplFileInfo::getType(): Lstat failed for [%s]
    #%d /vendor/league/flysystem/src/Adapter/Local.php(509): SplFileInfo::getType
    #%d /vendor/league/flysystem/src/Adapter/Local.php(509): League\Flysystem\Adapter\Local::mapFileInfo
    #%d /vendor/league/flysystem/src/Adapter/Local.php(452): League\Flysystem\Adapter\Local::normalizeFileInfo
    #%d /vendor/league/flysystem/src/Adapter/Local.php(288): League\Flysystem\Adapter\Local::listContents
    #%d /vendor/league/flysystem/src/Filesystem.php(272): League\Flysystem\Filesystem::listContents
    

    (Note the error example is from 1.x, but the problem exists in 3.x / Laravel 9 as well.)

    How to reproduce

    It is quite hard. It requires a file to be deleted during iteration. So the default "hey, we have a simple request/response workflow in a single thread" mindset is not going to help here.

    I can reproduce it at any time, however, by adding a delete to any file into LocalFilesystemDriver, within the loop, after the DirectoryIterator was created.

    Suggested solution

    I suggest that RuntimeErrors are caught in the foreach loop for the whole of SplFileInfo::whatever() calls, and if it matches the Lstat failed error, just ignore them and continue.

    Sadly, due to the unparalleled foresight of the PHP devs, errno (or something) is not passed as $code for RuntimeException; as such, it is hard (i.e. not quite feasible) to distinguish between different causes of RuntimeExceptions.

    If anything, and this solution is acceptable, I may send a pull request. But first please indicate that you understand the problem in general.

    opened by dvcsiky 2
Releases(3.0.0)
  • 3.0.0(Jan 14, 2022)

    What's Changed

    • [NEW] FilesystemAdapter::directoryExists to check for directory existence
    • [NEW] FilesystemReader::directoryExists to check for directory existence
    • [NEW] FilesystemAdapter::has to check for file or directory existence
    • [NEW] FilesystemReader::has to check for file or directory existence
    • PHP minimum version is upgraded to 8.0.2

    Full Changelog: https://github.com/thephpleague/flysystem/compare/2.4.0...3.0.0

    Blog post: https://blog.frankdejonge.nl/flysystem-3-0-0-is-released/

    Source code(tar.gz)
    Source code(zip)
  • 1.0.62(Dec 29, 2019)

    When resources are not actually file pointers, but fopen results from URL, the fstat call fails. This resulted in an error in PHP 7.4 because it's more strict about variable handling. This affected the Util::getStreamSize utility method.

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Mar 23, 2014)

    A new minor version for Flysystem has been released due to a (very minor) backwards incompatibility for custom adapters.

    The adapter now accepts visibility and config settings for the put and update methods. This added a new parameter to those functions which breaks the public interface. All user-land code will be backwards compatible, this change only affects custom adapters.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.14(Mar 9, 2014)

    • Cache Adapter addad: Adapter: It's now possible to use a filesystem adapter as a cache storage.
    • Noop cache fixes: Noop now handles directory listings better and respects the recursive setting.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.13(Mar 4, 2014)

    • The AWS S3 Adapter now uses a prefix when listing object resulting in much better performance.
    • The Rackspace Adapter now handles non-existing files.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.3(Feb 1, 2014)

  • 0.1.16(Dec 12, 2013)

    Flysystem will now resolve relative paths, when unresolvable it will throw an exception (LogicException). file (or dir) paths that reach outside of the specified root are now disallowed which makes the entire API more secure and friendly to use. A path like some/nested/../location will be converted to some/location, making sure the cached metadata is correct and protecting you from possible security exploits when building file managers.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.6(Nov 16, 2013)

Owner
The League of Extraordinary Packages
A group of developers who have banded together to build solid, well tested PHP packages using modern coding standards.
The League of Extraordinary Packages
PHP library that provides a filesystem abstraction layer − will be a feast for your files!

Gaufrette Gaufrette provides a filesystem abstraction layer. Why use Gaufrette? Imagine you have to manage a lot of medias in a PHP project. Lets see

KNP Labs 2.4k Jan 7, 2023
A Flysystem proxy adapter that enables compression and encryption of files and streams on the fly

Slam / flysystem-compress-and-encrypt-proxy Compress and Encrypt files and streams before saving them to the final Flysystem destination. Installation

Filippo Tessarotto 27 Jun 4, 2022
Private file storage and share with user build with laravel and vue inspired by google drive

LaravelDrive is a file storage system that allows store private file and share with users build wiht laravel and vue inspired by google drive. Laravel

Shahadat Hossain 70 Dec 22, 2022
Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel.

Laravel Flysystem Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel. It utilises my Larave

Graham Campbell 492 Feb 4, 2022
Detects file type by filename or content and generates correct mimetype.

FileTypeDetector Files type detector based on file name extension or file content (binary content). Usage Installation Supported formats Usage File Ty

Sergey 31 Oct 6, 2022
Uguu is a simple lightweight temporary file host with support for drop, paste, click and API uploading.

Uguu What is Uguu? Uguu is a simple lightweight temporary file hosting and sharing platform, but can also be used as a permanent file host. Features O

Eric Johansson (neku) 547 Dec 28, 2022
A PHP library to deal with all those media services around, parsing their URLs and displaying their audios/videos.

MediaEmbed A utility library that generates HTML embed tags for audio or video located on a given URL. It also parses and validates given media URLs.

Mark Sch. 165 Nov 10, 2022
This small PHP package assists in the loading and parsing of VTT files.

VTT Transcriptions This small PHP package assists in the loading and parsing of VTT files. Usage use Laracasts\Transcriptions\Transcription; $transcr

Laracasts 52 Nov 28, 2022
Basic anonymous and registered upload storage for temporary share file self hosted.

TMPShareX Basic anonymous and registered upload storage for temporary share file self hosted. Server Requirement PHP 7.4.8 [Support PHP 8] Nginx 1.19.

Sandy Hermansyah 1 Feb 3, 2022
Oxygen Builder's better workflow and environment

Oxygen Builder's better workflow and environment Built with ❤️ Official Website | Documentation | Change Log Supporting Artifact is an open source pro

dPlugins 10 Dec 3, 2022
Media gallery with CKEditor, TinyMCE and Summernote support. Built on Laravel file system.

Documents ・ Installation ・ Integration ・ Config ・ Customization ・ Events ・ Upgrade ・ Demo ・ FAQ Features File upload and management Uploading validati

UniSharp 1.9k Jan 1, 2023
A lightweight file manager with full ShareX, Screencloud support and more

XBackBone is a simple, self-hosted, lightweight PHP file manager that support the instant sharing tool ShareX and *NIX systems. It supports uploading

Sergio Brighenti 751 Jan 8, 2023
PictShare is an open source image, mp4, pastebin hosting service with a simple resizing and upload API that you can host yourself.

PictShare is an open source image, mp4, pastebin hosting service with a simple resizing and upload API that you can host yourself.

Haschek Solutions 709 Jan 3, 2023
Pomf is a simple lightweight file host with support for drop, paste, click and API uploading.

Pomf Pomf is a simple file uploading and sharing platform. Features One click uploading, no registration required A minimal, modern web interface Drag

Pomf 772 Jan 8, 2023
FileGator - a free, open-source, self-hosted web application for managing files and folders.

FileGator - Powerful Multi-User File Manager FileGator is a free, open-source, self-hosted web application for managing files and folders. You can man

FileGator 1.3k Jan 3, 2023
FIle Uploader is a php package to aid fast , easy and safe file upload

FILE UPLOADER FIle Uploader is a php package to aid fast , easy and safe file upload installation composer require codad5/file-helper Features Fast an

Aniezeofor Chibueze Michael 2 Sep 3, 2022
Abstraction for local and remote filesystems

League\Flysystem About Flysystem Flysystem is a file storage library for PHP. It provides one interface to interact with many types of filesystems. Wh

The League of Extraordinary Packages 11.9k Apr 22, 2021
Provides a unified interface to local and remote authentication systems.

Aura.Auth Provides authentication functionality and session tracking using various adapters; currently supported adapters are: Apache htpasswd files S

Aura for PHP 125 Sep 28, 2022