File Storage - niccolomeloni/laracert-5.5 GitHub Wiki

Laravel provides filesystem abstraction thanks to Flysystem, which make easy to use drivers for working with local filesystems, Amazon S3 and Rackspace Cloud Storage.

Configuration

File configurations are stored in config/filesystems.php. Each disk represents a particular storage driver and storage location. Of course, you can configure many disks and have multiple disks that use same driver.

Public Disk

Public disk is intended for files that are going to be publicly accessible. By default, public disk uses local driver and stores files in storage/app/public. To make them accessible from web, run storage:link to create a symbolic link from public/storage to storage/app/public. Then, you can create URL to files using asset helper.

$fileURL = asset('storage/file.txt');

The Local Driver

When using local driver, all file operations are relative to root directory defined in configuration file. By default, this value is set to storage/app.

// store file in storage/app/file.txt
Storage::disk('local')->put('file.txt', 'Contents');

Driver Prerequisites

S3 Driver Configuration

Run composer require league/flysystem-aws-s3-v3 ~1.0 and customize S3 driver configuration.

FTP Driver Configuration

Use following FTP filesystem configuration.

'ftp' => [
    'driver'   => 'ftp',
    'host'     => 'ftp.example.com',
    'username' => 'your-username',
    'password' => 'your-password',

    // Optional FTP Settings...
    // 'port'     => 21,
    // 'root'     => '',
    // 'passive'  => true,
    // 'ssl'      => true,
    // 'timeout'  => 30,
],

Rackspace Driver Configuration

Run composer require league/flysystem-rackspace ~1.0 and use following Rackspace filesystem configuration.

'rackspace' => [
    'driver'    => 'rackspace',
    'username'  => 'your-username',
    'key'       => 'your-key',
    'container' => 'your-container',
    'endpoint'  => 'https://identity.api.rackspacecloud.com/v2.0/',
    'region'    => 'IAD',
    'url_type'  => 'publicURL',
],

Obtaining Disk Instances

Use Illuminate\Support\Facades\Storage facede to interact with configured disk. Note that if you don't call disk, Storage will use default disk.

// store an avatar on default disk 
Storage::put('avatars/1', $fileContents;

// store an avatar on s3 disk 
Storage::disk('s3')->put('avatars/1', $fileContents);

Retrieving Files

Use Storage::get to retrieve raw string contents of a file. Note that all file paths should be specified relative to root location configured for the disk.

$contents = Storage::get('file.jpg');

Use exists to determine if a file exists on the disk.

Storage::disk('s3')->exists('file.jpg');

File URLs

Use Storage::url to get URL for a given file. Note that if you are using local driver, this will typically just prepend /storage to the given path and return a relative URL to the file. If you are using s3 or rackspace driver, the fully qualified remote URL will be returned.

Storage::url('file1.jpg');

Temporary URLs

Use temporaryUrl to create temporary URL to a given file stored using s3 or rackspace driver. This methods accepts a path and a DateTime instance specifying when the URL should expire.

$url = Storage::temporaryUrl(
    'file1.jpg', now()->addMinutes(5)
);

Local URL Host Customization

Add url option to disk's configuration to pre-define the host for files stored on a disk using local driver.

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

File Metadata

In addition to reading and writing files, Laravel can also provide metadata about files.

//  get the size of the file in bytes
$size = Storage::size('file1.jpg');

// returns the UNIX timestamp of the last time the file was modified
$time = Storage::lastModified('file1.jpg');

Storing Files

Use Storage::put to store raw file contents on a disk. You can pass a PHP resource, which will use Flysystem's underlying stream support. Using streams is greatly recommended when dealing with large files.

Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);

Automatic Streaming

Use putFile or putFileAs to automatically manage streaming a file to storage location. Methods accepts either Illuminate\Http\File or Illuminate\HttpUploadedFile and will automatically stream the file to desired location.

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// automatically generate a unique ID for file name
Storage::putFile('photos', new File('/path/to/photo'));

// manually specify a file name
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

Prepending & Appending To Files

Use Storage::prepend and Storage::append to write to the beginning or end of a file.

Storage::prepend('file.log', 'Prepended Text');
Storage::append('file.log', 'Appended Text');

Copying & Moving Files

Use Storage::copy and Storage::move to respectively copy and rename or move file to a new location.

Storage::copy('old/file1.jpg', 'new/file1.jpg');
Storage::move('old/file1.jpg', 'new/file1.jpg');

File Uploads

Laravel makes it very easy to store uploaded files using store on an uploaded file instance.

class UserAvatarController extends Controller
{
    public function update($request)
    {
        $path = $request->file('avatar')->store('avatars');
        // $path = Storage::putFile('avatars', $request->file('avatar'));

        return $path;
    }
}

By default, store will generate a unique ID to serve as file name. The path to file will be returned by store so you can store path, including generated file name, in database. If you want to specify file name use storeAs.

$path = $request->file('avatar')->storeAs(
    'avatars', $request->user()->id
);

$path = Storage::putFileAs(
    'avatars', $request->file('avatar'), $request->user()->id
);

Specifying A Disk

If you would like to specify another disk, pass the disk name as second argument to store.

$path = $request->file('avatar')->store(
    'avatars/'.$request->user()->id, 's3'
);

File Visibility

In Laravel's Flysystem integration, visibility is an abstraction of file permissions across multiple platforms. Files can be declared public or private. The putFile and putFileAs also accept an argument to specify visibility of stored file. This is useful when store file on a cloud disk and would like the file to be publicly accessible.

Storage::put('file.jpg', $contents, 'public');
Storage::putFile('photos', new File('/path/to/photo'), 'public');

If the file has already been stored, its visibility can be getted and setted via getVisibility and setVisibility.

$visibility = Storage::getVisibility('file.jpg');
Storage::setVisibility('file.jpg', 'public')

Deleting Files

Use Storage::delete to perform file deletion from a disk.

Storage::delete('file.jpg');
Storage::delete(['file1.jpg', 'file2.jpg']);
Storage::disk('s3')->delete('folder_path/file_name.jpg');

Directories

Get All Files Within A Directory

Use Storage::files to return an array of all files in a given directory. Use Storage::allFiles to retrieve a list of all files within a given directory including sub-directories.

$files = Storage::files($directory);

// recursive
$files = Storage::allFiles($directory);

Get All Directories Within A Directory

Use Storage::directories to return an array of all directories within a given directory. Use Storage::allDirectories to get a list of all directories within a give directory and all of its sub-directories.

$directories = Storage::directories($directory);

// recursive
$directories = Storage::allDirectories($directory);

Create A Directory

Use Storage::makeDirectory to create a directory.

Storage::makeDirectory($directory);

Delete A Directory

Use Storage::deleteDirectory to remove a directory and all of its files.

Storage::deleteDirectory($directory);

Custom Filesystems

In order to set up custom filesystem you will need League\Flysystem\Filesystem adapter. Let's add a community maintained Dropbox adapter by running composer require spatie/flysystem-dropbox. Next, create a DropboxServiceProvider and use Storage::extend in boot to define custom driver.

namespace App\Providers;

use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use Illuminate\Support\ServiceProvider;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

class DropboxServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Storage::extend('dropbox', function ($app, $config) {
            $client = new DropboxClient(
                $config['authorizationToken']
            );

            return new Filesystem(new DropboxAdapter($client));
        });
    }
}

The first argument of extend is driver's name and the second is a Closure that receives $app and $config variables and return an instance of League\Flysystem\Filesystem adapter. The $config contains the values defined in config/filesystems.php for the specified disk. Then you can use dropbox driver in config/filesystems.php.