Working with Laravel 5.2 File System and Storage


For this tutorial what we want to achieve is to have a file upload and download system in our Laravel 5 application using the new Storage features. The example is intentionally easy but you can easily extend the concept.

For the purpose we are going to create a database table where we store the file informations. This is needed when we  download the file from the application. With the abstraction of the Storage API you can save the file where you like, locally on the local disk like in the example or Amazon S3 servers, or others.

Let’s begin creating a table migration for our fileentries model.

php artisan make:migration create_fileentries_table --table="fileentries"

Edit the code of the created file and add the fields we need.

<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateFileEntryTable extends Migration {
 
/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
Schema::create('fileentries', function(Blueprint $table)
{
$table->increments('id');
$table->string('filename');
$table->string('mime');
$table->string('original_filename');
$table->timestamps();
});
}
 
/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
Schema::drop('fileentries');
 
}
 
}

Migrate the DB and go on :

php artisan migrate

To get advantage from the ORM feature let’s create also the model for our fileentries.

php artisan make:model Fileentry

Before implementing the controller and the view, to get an idea of what we need is better to define the routes needed. We need basically 2 route, one for adding file entries, one for download it. We are going to add a third route to have an index page with a form and where we will display our files.

Route::get('fileentry', 'FileEntryController@index');
Route::get('fileentry/get/{filename}', [
    'as' => 'getentry', 'uses' => 'FileEntryController@get']);
Route::post('fileentry/add',[ 
        'as' => 'addentry', 'uses' => 'FileEntryController@add']);

With our routes in place let’s create the controller.

php artisan make:controller FileEntryController --plain

The index method of the controller will render only the view where we have the form for the upload and a list of the image.

Upload a file to the Storage

The add method have to make two things, one is to save our file to the Storage, other is to insert a row into DB to take track of the file info.

Below the first part of the controller code :

<?php namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Fileentry;
use Request;
 
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use Illuminate\Http\Response;
 
class FileEntryController extends Controller {
 
/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
$entries = Fileentry::all();
 
return view('fileentries.index', compact('entries'));
}
 
public function add() {
 
$file = Request::file('filefield');
$extension = $file->getClientOriginalExtension();
Storage::disk('local')->put($file->getFilename().'.'.$extension,  File::get($file));
$entry = new Fileentry();
$entry->mime = $file->getClientMimeType();
$entry->original_filename = $file->getClientOriginalName();
$entry->filename = $file->getFilename().'.'.$extension;
 
$entry->save();
 
return redirect('fileentry');
}
}

And the code for the form  with a first list of the files name. We will modify this part later adding a display for the pictures.

@extends('app')
@section('content')
 
    <form action="add" method="post" enctype="multipart/form-data">
        <input type="file" name="filefield">
        <input type="submit">
    </form>
 
 <h1> Pictures list</h1>
 
 <div class="row">
 
    <ul>
 @foreach($entries as $entry)
        <li>{{entry->filename}}</li>
 @endforeach
    </ul>
 </div>
 
@endsection

At this point we are able to upload files to the app and save them into the Storage. But how to vew or download this files ? We didn’t save it int he public directory so we need a method to get it retrieved from the Storage and the present to the broswer.

Download files from Storage

To get the file back to the storage and also have it in response we saved a row in the database. On this example we retrieve the file based on it random name assigned but easily it can be changed to get it via the original name or the id.

It’s important to note that we saved in the database also the mime type of the file. It’s important now to geenrate the correct response header, adding this method to the controller we are now able to retrieve the files.

public function get($filename){
    
        $entry = Fileentry::where('filename', '=', $filename)->firstOrFail();
        $file = Storage::disk('local')->get($entry->filename);

        return (new Response($file, 200))
              ->header('Content-Type', $entry->mime);
    }

To complete the tutorial we can implement a list of the picture calling for every picture the method to retrieve the image. Change the index.blade.php to this


@extends('app')
@section('content')
 
    <form action="{{route('addentry', [])}}" method="post" enctype="multipart/form-data">
        <input type="file" name="filefield">
        <input type="submit">
    </form>
 
 <h1> Pictures list</h1>
 <div class="row">
        <ul class="thumbnails">
 @foreach($entries as $entry)
            <div class="col-md-2">
                <div class="thumbnail">
                    <img src="{{route('getentry', $entry->filename)}}" alt="ALT NAME" class="img-responsive" />
                    <div class="caption">
                        <p>{{$entry->original_filename}}</p>
                    </div>
                </div>
            </div>
 @endforeach
 </ul>
 </div>
 
@endsection

 Conclusion

That’s a first step in the file managment for a Laravel 5 application. Using the Storage API we can abstract our filesystem and we can save the files where we like or where it’s better for our app. In a future tutorial i would like to cover the file upload and retrieve with a single page application made with AngularJS

Written by Akram Wahid 8 years ago

are you looking for a chief cook who can well craft laravel and vuejs, to make some awsome butterscotch,
yes then it is right time for you to look at my profile.

Do you want to write Response or Comment?

You must be a member of techalyst to proceed!

Continue with your Email ? Sign up / log in

Responses

Be the first one to write a response :(

{{ item.member.name }} - {{ item.created_at_human_readable }}

{{ reply.member.name }} - {{ reply.created_at_human_readable }}