5 Laravel Storage Tips

Here are 5 things I've learned from working with file storage in Laravel. Feel free to use the below code examples in your own projects or tweet me with questions.

1) Define an .env variable for the default storage driver

In local development I often use the local storage driver for speed, but in a production environment I use Amazon S3. Defining an environment variable for the driver we wish to use means we don’t have to write messy conditional logic in our controllers. In my projects I then call this variable in config/filesystems.php using the ENV function (see below).

    
        
    ...

    'default' => ENV(DEFAULT_STORAGE_DRIVER, 'local'),

    ...

    

Laravel conveniently provides us with the ability to create a symlink between the storage directory and our public directory so our files can be accessed publicly. This is done very simply with the command:

    
        
    php artisan storage link

    

3) Use mutators & accessors when defining custom file names

Laravel’s mutator and accessor methods allow us to modify the way we store or retrieve a model’s attribute. To keep file naming conventions consistent I’d recommed defining a method in this way.

    
        
    use Storage;

    public function setFilenameAttribute($value)
    {
        $this->attributes['filename'] = str_replace(' ', '-', strtolower($value));
    }

    public function getFilepathAttribute($value)
    {
        return Storage::url($value);
    }

    

4) Setting a file’s Content-Type in S3

Something that’s not documented in Laravel 5.4 is the ability to set the content type of S3 uploads. Previously all files were saved as the type ‘application/octet-stream’ which resulted in files being downloaded by users not viewed. The following illustrates this:

    
        
    Storage::putFile('/path/to/file', new File($file), array(
        'visibility' => 'public',
        'mimetype' => 'video/mp4'
    ));

    

5) Write custom validation to allow only certain filetypes to be uploaded

By writing our own Request we can validate a form’s file upload. Using an asterisk we can validate multiple files and declare which mimetypes we want to accept.

    
        
    $rules = array(
        'files.*' => 'mimetypes:video/avi,video/mpeg,video/mp4,video/webm|required'
    );