Laravel 9 CRUD with Image Upload Tutorial

By Hardik Savani April 6, 2022 Category : Laravel

Hello All,

This tutorial shows you laravel 9 crud with image upload. if you want to see an example of crud with image upload in laravel 9 then you are the right place. it's simple example of laravel 9 image upload crud. This article goes in detail on laravel 9 image upload with crud. Let's see bellow the example laravel 9 crud example with image upload.

You just need to follow a few steps and you will get basic crud with image upload stuff using controller, model, route, bootstrap 5, and blade..

In this tutorial, you will learn a very basic crud with image upload operation with laravel new version 9. I am going to show you step by step from scratch so, I will better understand if you are new to Laravel.

Preview:

Step 1: Install Laravel 9

This is optional; however, if you have not created the laravel app, then you may go ahead and execute the below command:

composer create-project laravel/laravel example-app

Step 2: Database Configuration

In second step, we will make database configuration for example database name, username, password etc for our crud application of laravel 9. So let's open .env file and fill all details like as bellow:

.env

DB_CONNECTION=mysql

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=here your database name(blog)

DB_USERNAME=here database username(root)

DB_PASSWORD=here database password(root)

Step 3: Create Migration

we are going to create crud application for product. so we have to create migration for "products" table using Laravel 9 php artisan command, so first fire bellow command:

php artisan make:migration create_products_table --create=products

After this command you will find one file in following path "database/migrations" and you have to put bellow code in your migration file for create products table.

<?php

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

return new class extends Migration

{

/**

* Run the migrations.

*

* @return void

*/

public function up()

{

Schema::create('products', function (Blueprint $table) {

$table->id();

$table->string('name');

$table->text('detail');

$table->string('image');

$table->timestamps();

});

}

/**

* Reverse the migrations.

*

* @return void

*/

public function down()

{

Schema::dropIfExists('products');

}

};

Now you have to run this migration by following command:

php artisan migrate

Step 4: Add Controller and Model

In this step, now we should create new controller as ProductController. in this controller we write logic to store image, we store images in "images" folder of public folder. So run bellow command and create new controller. bellow controller for create resource controller.

php artisan make:controller ProductController --resource --model=Product

After bellow command you will find new file in this path "app/Http/Controllers/ProductController.php".

In this controller will create seven methods by default as bellow methods:

1)index()

2)create()

3)store()

4)show()

5)edit()

6)update()

7)destroy()

So, let's copy bellow code and put on ProductController.php file.

app/Http/Controllers/ProductController.php

<?php

namespace App\Http\Controllers;

use App\Models\Product;

use Illuminate\Http\Request;

class ProductController extends Controller

{

/**

* Display a listing of the resource.

*

* @return \Illuminate\Http\Response

*/

public function index()

{

$products = Product::latest()->paginate(5);

return view('products.index',compact('products'))

->with('i', (request()->input('page', 1) - 1) * 5);

}

/**

* Show the form for creating a new resource.

*

* @return \Illuminate\Http\Response

*/

public function create()

{

return view('products.create');

}

/**

* Store a newly created resource in storage.

*

* @param \Illuminate\Http\Request $request

* @return \Illuminate\Http\Response

*/

public function store(Request $request)

{

$request->validate([

'name' => 'required',

'detail' => 'required',

'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',

]);

$input = $request->all();

if ($image = $request->file('image')) {

$destinationPath = 'images/';

$profileImage = date('YmdHis') . "." . $image->getClientOriginalExtension();

$image->move($destinationPath, $profileImage);

$input['image'] = "$profileImage";

}

Product::create($input);

return redirect()->route('products.index')

->with('success','Product created successfully.');

}

/**

* Display the specified resource.

*

* @param \App\Product $product

* @return \Illuminate\Http\Response

*/

public function show(Product $product)

{

return view('products.show',compact('product'));

}

/**

* Show the form for editing the specified resource.

*

* @param \App\Product $product

* @return \Illuminate\Http\Response

*/

public function edit(Product $product)

{

return view('products.edit',compact('product'));

}

/**

* Update the specified resource in storage.

*

* @param \Illuminate\Http\Request $request

* @param \App\Product $product

* @return \Illuminate\Http\Response

*/

public function update(Request $request, Product $product)

{

$request->validate([

'name' => 'required',

'detail' => 'required'

]);

$input = $request->all();

if ($image = $request->file('image')) {

$destinationPath = 'images/';

$profileImage = date('YmdHis') . "." . $image->getClientOriginalExtension();

$image->move($destinationPath, $profileImage);

$input['image'] = "$profileImage";

}else{

unset($input['image']);

}

$product->update($input);

return redirect()->route('products.index')

->with('success','Product updated successfully');

}

/**

* Remove the specified resource from storage.

*

* @param \App\Product $product

* @return \Illuminate\Http\Response

*/

public function destroy(Product $product)

{

$product->delete();

return redirect()->route('products.index')

->with('success','Product deleted successfully');

}

}

Ok, so after run bellow command you will find "app/Models/Product.php" and put bellow content in Product.php file:

app/Models/Product.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

class Product extends Model

{

use HasFactory;

protected $fillable = [

'name', 'detail', 'image'

];

}

Step 5: Add Resource Route

Here, we need to add resource route for product crud application. so open your "routes/web.php" file and add following route.

routes/web.php

<?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\ProductController;

/*

|--------------------------------------------------------------------------

| Web Routes

|--------------------------------------------------------------------------

|

| Here is where you can register web routes for your application. These

| routes are loaded by the RouteServiceProvider within a group which

| contains the "web" middleware group. Now create something great!

|

*/

Route::resource('products', ProductController::class);

Step 6: Add Blade Files

In last step. In this step we have to create just blade files. So mainly we have to create layout file and then create new folder "products" then create blade files of crud app. So finally you have to create following bellow blade file:

1) layout.blade.php

2) index.blade.php

3) create.blade.php

4) edit.blade.php

5) show.blade.php

So let's just create following file and put bellow code.

resources/views/products/layout.blade.php

<!DOCTYPE html>

<html>

<head>

<title>Laravel 9 CRUD with Image Upload Application - ItSolutionStuff.com</title>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">

</head>

<body>

<div class="container">

@yield('content')

</div>

</body>

</html>

resources/views/products/index.blade.php

@extends('products.layout')

@section('content')

<div class="row">

<div class="col-lg-12 margin-tb">

<div class="pull-left">

<h2>Laravel 9 CRUD with Image Upload Example from scratch - ItSolutionStuff.com</h2>

</div>

<div class="pull-right">

<a class="btn btn-success" href="{{ route('products.create') }}"> Create New Product</a>

</div>

</div>

</div>

@if ($message = Session::get('success'))

<div class="alert alert-success">

<p>{{ $message }}</p>

</div>

@endif

<table class="table table-bordered">

<tr>

<th>No</th>

<th>Image</th>

<th>Name</th>

<th>Details</th>

<th width="280px">Action</th>

</tr>

@foreach ($products as $product)

<tr>

<td>{{ ++$i }}</td>

<td><img src="/images/{{ $product->image }}" width="100px"></td>

<td>{{ $product->name }}</td>

<td>{{ $product->detail }}</td>

<td>

<form action="{{ route('products.destroy',$product->id) }}" method="POST">

<a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a>

<a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">Edit</a>

@csrf

@method('DELETE')

<button type="submit" class="btn btn-danger">Delete</button>

</form>

</td>

</tr>

@endforeach

</table>

{!! $products->links() !!}

@endsection

resources/views/products/create.blade.php

@extends('products.layout')

@section('content')

<div class="row">

<div class="col-lg-12 margin-tb">

<div class="pull-left">

<h2>Add New Product</h2>

</div>

<div class="pull-right">

<a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>

</div>

</div>

</div>

@if ($errors->any())

<div class="alert alert-danger">

<strong>Whoops!</strong> There were some problems with your input.<br><br>

<ul>

@foreach ($errors->all() as $error)

<li>{{ $error }}</li>

@endforeach

</ul>

</div>

@endif

<form action="{{ route('products.store') }}" method="POST" enctype="multipart/form-data">

@csrf

<div class="row">

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Name:</strong>

<input type="text" name="name" class="form-control" placeholder="Name">

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Detail:</strong>

<textarea class="form-control" style="height:150px" name="detail" placeholder="Detail"></textarea>

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Image:</strong>

<input type="file" name="image" class="form-control" placeholder="image">

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12 text-center">

<button type="submit" class="btn btn-primary">Submit</button>

</div>

</div>

</form>

@endsection

resources/views/products/edit.blade.php

@extends('products.layout')

@section('content')

<div class="row">

<div class="col-lg-12 margin-tb">

<div class="pull-left">

<h2>Edit Product</h2>

</div>

<div class="pull-right">

<a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>

</div>

</div>

</div>

@if ($errors->any())

<div class="alert alert-danger">

<strong>Whoops!</strong> There were some problems with your input.<br><br>

<ul>

@foreach ($errors->all() as $error)

<li>{{ $error }}</li>

@endforeach

</ul>

</div>

@endif

<form action="{{ route('products.update',$product->id) }}" method="POST" enctype="multipart/form-data">

@csrf

@method('PUT')

<div class="row">

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Name:</strong>

<input type="text" name="name" value="{{ $product->name }}" class="form-control" placeholder="Name">

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Detail:</strong>

<textarea class="form-control" style="height:150px" name="detail" placeholder="Detail">{{ $product->detail }}</textarea>

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Image:</strong>

<input type="file" name="image" class="form-control" placeholder="image">

<img src="/images/{{ $product->image }}" width="300px">

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12 text-center">

<button type="submit" class="btn btn-primary">Submit</button>

</div>

</div>

</form>

@endsection

resources/views/products/show.blade.php

@extends('products.layout')

@section('content')

<div class="row">

<div class="col-lg-12 margin-tb">

<div class="pull-left">

<h2> Show Product</h2>

</div>

<div class="pull-right">

<a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>

</div>

</div>

</div>

<div class="row">

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Name:</strong>

{{ $product->name }}

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Details:</strong>

{{ $product->detail }}

</div>

</div>

<div class="col-xs-12 col-sm-12 col-md-12">

<div class="form-group">

<strong>Image:</strong>

<img src="/images/{{ $product->image }}" width="500px">

</div>

</div>

</div>

@endsection

Run Laravel App:

All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:

php artisan serve

Now, Go to your web browser, type the given URL and view the app output:

http://localhost:8000/products

Make sure, you have created "images" folder in public directory

You will see layout as like bellow:

List Page:

Add Page:

Edit Page:

Show Page:

I hope it can help you....