9,179 views
In this guide we will be looking at uploading files and/or images (single and multiple) in Laravel 5.6.
ALSO ADDED BONUS HOW TO RESIZE UPLOADED IMAGES (it will be at the very bottom).
We'll use a real world example on where file upload features would be useful.
Let's say you're build a site where you have a users table and these users can have images or documents attached to them.
So let's first make a table in which we can connect the users with the files they have uploaded.
For that let's first make a model using cmd:
php artisan make:model UserFile -m
The '-m' in the command will also make a migration based on that model.
Now If you go to the database/migrations folder and you'll see a new migration created _create_user_files.php.
Let's modify the migration and add a couple columns and include the Model we just made.
It should look something like this:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserFilesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_files', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_files');
}
}
Now It's time to edit the User and UserFile models.
Edit the UserFile model like so:
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserFile extends Model
{
protected $fillable = ['job_id', 'file'];
}
And the User model like so:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function files(){
return $this->hasMany('App\UserFile');
}
public function delete() {
$this->files()->delete();
parent::delete();
}
}
Finally it's time to create a global class that could be included and called in any controller with which you can upload files.
Go to app/Http/Controllers and create a folder called Traits.
Then right click inside and create a file called FileUpload.php
Paste the following code inside the newly created file:
namespace App\Http\Controllers\Traits;
use Illuminate\Http\Request;
trait FileUpload
{
/**
* File upload trait used in controllers to upload files
*/
public function saveFiles($file, $folder)
{
$destinationPath = '/uploads/'.$folder;
$file_name = time().'-'.$file->getClientOriginalName();
$file->move($_SERVER['DOCUMENT_ROOT'].$destinationPath, $file_name);
return $file_name;
}
}
MAKE SURE YOU MAKE A FOLDER CALLED UPLOADS INSIDE OF YOU PUBLIC FOLDER IN YOUR LARAVEL PROJECT!
As you can see the parametars passed to the traits are the file eg. $request->file('files') and the subfolder name inside of your uploads folder eg. 'user_files'.
This is how you include the trait inside of your controller:
use App\Http\Controllers\Traits\FileUpload;
class UserController extends Controller
{
use FileUpload;
So your destionation folder in this case would be public/uploads/user_files
For image resizing we will need to include a package called Intervention Image, you can find the documentation here.
Run the following command in cmd:
php composer.phar require intervention/image
Now go into your config/app.php and add the provider to the $providers array:
Intervention\Image\ImageServiceProvider::class
And the fascade of this package to the $aliases array:
'Image' => Intervention\Image\Facades\Image::class
After that publish the configuration using cmd while in the laravel project root folder:
php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"
Now you're finally ready to intergrate it in your project!
Let's make a new file in the Traits folder be created earlier and call in ImageUpload.php
Also go into your uploads folder and make a folder called user_images and inside of the folder create a folder called thumbnails.
To recap you should now have app/Http/Controllers/Traits/ImageUpload.php and public/uploads/user_images and public/uploads/user_images/thumbnails
Edit your ImageUpload.php to look like so:
namespace App\Http\Controllers\Traits;
use Illuminate\Http\Request;
trait ImageUpload
{
/**
* Image upload trait used in controllers to upload files
*/
public function saveImages($file, $folder)
{
$destinationPath = '/uploads/'.$folder;
$file_name = time().'-'.$file->getClientOriginalName();
$image = Image::make($file);
$image->resize(1920, 1080, function ($constraint) {
$constraint->aspectRatio();
})->save(public_path() . $destinationPath . $file_name);
$image->resize(350, 240, function ($constraint) {
$constraint->aspectRatio();
})->save(public_path() . $destinationPath .'/thumbnails/'. $file_name);
return $file_name;
}
}
In short the code above uses two parametars the same as the FileUpload trait that we created earlier, but here we intergrate the Image class with which we can resize the image to the size we want.
The first parametar is like in the last example $request->file('files') and the second one is the subfolder name, in this example that would be user_images.
We save one image to 1920x1080 which is the max size of the image we want and 350x240 (or the size you desire) for the thumbnail.
The reason we do this is because when i user is browsing your site for example your products we don't want the whole image to load, or should I say the max size of the image. The loading would be too slow.
If you have any questions be sure to email me!
By: Ivan Javorović