Laravel Image or File Upload with Validations

Every project has a primary requirement of Image or File Upload with Validation to Laravel Controller. If you want to upload an image or a file from “blade form” or “JQuery Ajax request” using the HTTP POST method then you are at the place to go with it. In this post, we provide a very simple way to upload, store, and delete files from a project directory. We will use the default Laravel validator class to handled validations for the file upload or multiple file uploads. Upload validation of file extensions like jpeg, png, jpg, gif or SVG, and other file extensions.

However, we are starting from creating the Controller, Blade template and adding an entry into the routes.php file. I believe you know your logic and further implementation according to your requirements. Mostly we will focus on a complete understanding of file uploading rather than creating a project from scratch.

Laravel Image or File Upload Controller

A controller is a simple class that extends the default Controller for handling the request either from blade template form or ajax request, we need a controller for Laravel image or file upload so that we could handle a request for uploading files. In this class, we also need a method for the specific purpose of file uploading.

A method with validation

In the following method, we have used a default Laravel Validator class. A validator class has a “make method” that takes an array of input of parameters and the rules as an array.

public function imageUpload(Request $request){
	$validator = Validator::make($request->all(),[
		'file' => 'required',
		'file.*' => 'mimes:jpeg,jpg,png'
	]);
	
	if ($validator->fails()) {
		return redirect()->back()->withErrors($validator)->withInput();
	}
}

The image upload method has a request parameter, from this parameter you can retrieve all request parameters. Parameters can be a single file or a list of files. In the rules, we have set the file as required and mime-type should be an image. If validation fails then return back with error and old inputs.

A method with upload logic

When you want to save a single file or list of files then you need to get all files from the request and save the information into the database. You can use this database information about files according to your usage.

public function imageUpload(Request $request){
	if($request->hasfile('file')) {
		foreach($request->file('file') as $file)
		{
			$fileName = time().rand(0, 1000).pathinfo('-'.$file->getClientOriginalName(), PATHINFO_FILENAME);
			$fileName = $fileName.'.'.$file->getClientOriginalExtension();
			$file->move(public_path().'\\images\\profile_images\\',$fileName);
			
			$image = new Image();
			$image->name = $fileName;
			$image->save();                      
		}  
   }
}

The image upload method contains a logic, If a request has a file or list of files then it should move to the public directory of images for profiles. We are appending each file name at a random time so that each file name must be a unique name.

Complete controller with method code

A controller class contains namespace and the use of other classes in Laravel Image or File Upload. It also contains a delete method. A delete method has a $id parameter. If the $id parameter is not null then search the image record from the database where $id matches in other words you need to send a unique identifier for deleting an image. There are many other HTTP methods that are used for different purposes for instance GET, DELETE, POST, PUT, CONNECT, and HEAD. If a record found then get the name of the file from it and remove it from the project directory also.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Image;
use Illuminate\Support\Facades\Validator;

class ImageController extends Controller
{
    public function imageUpload(Request $request){
        $validator = Validator::make($request->all(),[
            'file' => 'required',
            'file.*' => 'mimes:jpeg,jpg,png'
        ]);
        
        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

		if($request->hasfile('file')) {
			foreach($request->file('file') as $file)
			{
				$fileName = time().rand(0, 1000).pathinfo('-'.$file->getClientOriginalName(), PATHINFO_FILENAME);
				$fileName = $fileName.'.'.$file->getClientOriginalExtension();
				$file->move(public_path().'\\images\\profile_images\\',$fileName);
	
				$image = new Image();
				$image->name = $fileName;
				$image->save();                      
			}  
	   }
        return redirect()->back();
    }
	
      public function imageDelete($imgId){
        if($imgId){
            $image = Image::find($imgId);
            if($image){
                unlink(public_path().'\\images\\profile_images\\'.$image->name);
                $image->delete();
            }
        }
       return redirect()->back();
    }
}

Form and Ajax Request

In this section, we are going to learn about form request to the controller using form request and ajax request. These are two famous and most common ways to request. For testing purposes, you can also use Postman to test the functionality of the controller.

Form Http POST request for image file upload

A form, which contains an HTML input field and a button for submitting a request. An input type is a file and the name of the input has two brackets that show this field can have multiple values.

<form method="POST" action="{{URL::route('imagePost')}}" enctype="multipart/form-data">
  @csrf
  <div class="form-group">
	<div class="custom-file">
	  <input type="file" class="custom-file-input" name="file[]" multiple required>
	  <label class="custom-file-label" for="customFile">Select Image(s)</label>
	</div>
  </div>
	<button type="submit" class="btn btn-block btn-outline-primary">Upload</button>
</form> 

There are some important things in html form. we are discussing each one by one.

  • Method: The POST request method is a secured method for sending large data to the server therefore we have used the POST method instead of the HTTP GET method. The data is enclosed in the request body.
  • action: It is an attribute of the form element, that specifies the URL of the server where to submit the data.
  • enctype: It is an attribute that states to encode the form data while submitting it to the server. multipart/formdata is a single value of enctype attribute that divides into multiple parts and send to the server.
  • @csrf: In the Laravel, It generates automatically a CSRF “token” for each user that is managed by the application session. It is for the verification of logged-in users.

Ajax Http Post request for Image file upload

In the ajax request, it works as same but you need CRSF token before sending request to the server.

$.ajaxSetup({
	headers: {
		'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
	}
});

$('#image-form').submit(function(e) {
   e.preventDefault();
   let formData = new FormData(this);
   var file_data = $("#profileImage").prop("files");
   formData .append("profileImage", file_data);
   
   $.ajax({
	  type:'POST',
	  url: '/upload-images',
	   data: formData,
	   contentType: false,
	   processData: false,
	   success: (resp) => {
		 if (resp) {               
		   console.log(resp);
		 }
	   },
	   error: function(resp]){
		  console.log(resp);                
	   }
   });
});
<meta name="csrf-token" content="{{ csrf_token() }}">

Firstly in ajax code, we are doing an ajax setup for the CSRF token. we assume that in the blade template there is a meta tag that contains csrf token and An example is given above. We have added the event or submitting a form that prevents the default action of the file. By using fileImage input form id, we are getting all files and sending them to the server. In the response, Either we have a successful response or an error, it shows in the console log.

Routes

A route is a simple URL that provides a way to the method of the controller therefore we have two methods in our scenario, the first method is used for image uploading and the second method is used for deleting an existing image. In the is this case we also need two route URLs to serve these functions at the client-side request or in the HTML template form.

Route::post('/upload-image','App\Http\Controllers\ImageController@imageUpload')->name('imagePost');
Route::delete('upload-image/{imgId}','App\Http\Controllers\ImageController@imageDelete')->name('deleteImage');

In the above code, you have defined two different routes. The first parameter of the method is the URL path. The second parameter is for controller@methodName. These routes also have given names. These names can be used in blade templates or in controllers to redirect paths.

Conclusion

In conclusion, we have learned about image file uploading in Laravel. There are two different HTTP request methods, Form request, and Ajax request. The controller has validations and moving images from request to the public path of the project.

Leave a Reply

Your email address will not be published. Required fields are marked *