Download Laravel App
composer create-project --prefer-dist laravel/laravel my-app
C:\xampp\htdocs\laravel>composer create-project --prefer-dist laravel/laravel my-app
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=root
DB_PASSWORD=
Create Controller PostController
php artisan make:controller PostController
C:\xampp\htdocs\laravel\my-app>php artisan make:controller PostController
app\Http\Controllers\PostController.php
//app\Http\Controllers\PostController.php
<?php
namespace App\Http\Controllers;
use App\Models\Image;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
class PostController extends Controller
{
    public function index()
    {
        $posts=Post::all();
        return view('index')->with('posts',$posts);
    }
    public function create()
    {
        return view('create');
    }
    
    public function store(Request $request)
    {
        if($request->hasFile("cover")){
            $file=$request->file("cover");
            $imageName=time().'_'.$file->getClientOriginalName();
            $file->move(\public_path("cover/"),$imageName);
            $post =new Post([
                "title" =>$request->title,
                "author" =>$request->author,
                "body" =>$request->body,
                "cover" =>$imageName,
            ]);
           $post->save();
        }
        if($request->hasFile("images")){
                $files=$request->file("images");
                foreach($files as $file){
                    $imageName=time().'_'.$file->getClientOriginalName();
                    $request['post_id']=$post->id;
                    $request['image']=$imageName;
                    $file->move(\public_path("/images"),$imageName);
                    Image::create($request->all());
                }
        }
        return redirect("/");
    }
    public function edit($id)
    {
        $posts=Post::findOrFail($id);
        return view('edit')->with('posts',$posts);
    }
    public function update(Request $request,$id)
    {
     $post=Post::findOrFail($id);
     if($request->hasFile("cover")){
         if (File::exists("cover/".$post->cover)) {
             File::delete("cover/".$post->cover);
         }
         $file=$request->file("cover");
         $post->cover=time()."_".$file->getClientOriginalName();
         $file->move(\public_path("/cover"),$post->cover);
         $request['cover']=$post->cover;
     }
        $post->update([
            "title" =>$request->title,
            "author"=>$request->author,
            "body"=>$request->body,
            "cover"=>$post->cover,
        ]);
        if($request->hasFile("images")){
            $files=$request->file("images");
            foreach($files as $file){
                $imageName=time().'_'.$file->getClientOriginalName();
                $request["post_id"]=$id;
                $request["image"]=$imageName;
                $file->move(\public_path("images"),$imageName);
                Image::create($request->all());
            }
        }
        return redirect("/");
    }
    public function destroy($id)
    {
         $posts=Post::findOrFail($id);
         if (File::exists("cover/".$posts->cover)) {
             File::delete("cover/".$posts->cover);
         }
         $images=Image::where("post_id",$posts->id)->get();
         foreach($images as $image){
            if (File::exists("images/".$image->image)) {
                File::delete("images/".$image->image);
            }
         }
         $posts->delete();
         return back();
    }
    public function deleteimage($id){
        $images=Image::findOrFail($id);
        if (File::exists("images/".$images->image)) {
           File::delete("images/".$images->image);
        }
       Image::find($id)->delete();
       return back();
    }
    public function deletecover($id){
        $cover=Post::findOrFail($id)->cover;
        if (File::exists("cover/".$cover)) {
            File::delete("cover/".$cover);
        }
        return back();
    }
}
Database Migration php artisan make:model Post -m
php artisan make:model Image -m
C:\xampp\htdocs\laravel\my-app>php artisan make:model Post -m
C:\xampp\htdocs\laravel\my-app>php artisan make:model Image -m
database/migrations/create_post_table.php
database/migrations/create_image_table.php
//database/migrations/create_post_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string("author");
            $table->string("title");
            $table->text("body");
            $table->text("cover");
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::dropIfExists('posts');
    }
};
database/migrations/create_image_table.php
//database/migrations/create_image_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string("image");
            $table->foreignId("post_id")->constraint("posts")->onDelete("cascade");
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::dropIfExists('images');
    }
};
Model Post and Images app/models/Post.php
//app/models/Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Image;
class Post extends Model
{
    use HasFactory;
    protected $fillable=[
        'title',
        'author',
        'body',
        'cover',
    ];
    public function images(){
        return $this->hasMany(Image::class);
    }
}
app/models/Image.php
//app/models/Image.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;
class Image extends Model
{
    use HasFactory;
    protected $fillable=[
        'image',
        'post_id',
    ];
    public function posts(){
        return $this->belongsTo(Post::class);
    }
}
run this migration
C:\xampp\htdocs\laravel\my-app>php artisan migrate
Bootstrap 5
https://getbootstrap.com/docs/5.0/getting-started/introduction/
https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css
resources/views/index.blade.php
//resources/views/index.blade.php
@extends('layout')
    
@section('content')
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
              <h2>Laravel CRUD (create read update and delete) With Multiple Image Upload</h2>
            </div>
            <div class="card-body">
                <a href="{{ url('/create') }}" class="btn btn-success btn-sm" title="Add New Post">Add New Post</a>
                <br/><br/>
                <div class="table-responsive">
                <h2>Blog Post List</h2>
                <table class="table">
                <thead>
                    <tr>
                      <th>ID</th>
                      <th>Title</th>
                      <th>Author</th>
                      <th>Description</th>
                      <th>Cover</th>
                      <th>Update</th>
                      <th>Delete</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($posts as $post)
                      <tr>
                          <th scope="row">{{ $post->id }}</th>
                          <td>{{ $post->title }}</td>
                          <td>{{ $post->author }}</td>
                          <td>{{ $post->body }}</td>
                          <td><img src="cover/{{ $post->cover }}" class="img-responsive" style="max-height:100px; max-width:100px" alt="" srcset=""></td>
                          <td><a href="/edit/{{ $post->id }}" class="btn btn-outline-primary">Edit</a></td>
                          <td>
                              <form action="/delete/{{ $post->id }}" method="post">
                                <button class="btn btn-outline-danger" onclick="return confirm('Are you sure?');" type="submit">Delete</button>
                                @csrf
                                @method('delete')
                              </form>
                          </td>
                      </tr>
                    @endforeach
                  </tbody>
              </table>
                </div>  
            </div>                  
        </div>
    </div>                        
</div>
@endsection
resources/views/layout.blade.php
//resources/views/layout.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel CRUD (create read update and delete) With Multiple Image Upload</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
</head>
<body>
<div class="container" style="padding-top:20px;">
    @yield('content')
</div>
   
@yield('scripts')
</body>
</html>
resources/views/create.blade.php
//resources/views/create.blade.php
@extends('layout')
    
@section('content')
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
              <h2>Add New Post</h2>
            </div>
            <div class="card-body">
                <form action="/post" method="post" enctype="multipart/form-data">
                    @csrf
        			<input type="text" name="title" class="form-control m-2" placeholder="title">
        			<input type="text" name="author" class="form-control m-2" placeholder="author">
                    <Textarea name="body" cols="20" rows="4" class="form-control m-2" placeholder="body"></Textarea>
                    <label class="m-2">Cover Image</label>
                    <input type="file" id="input-file-now-custom-3" class="form-control m-2" name="cover">
                    <label class="m-2">Images</label>
                    <input type="file" id="input-file-now-custom-3" class="form-control m-2" name="images[]" multiple>
                    <button type="submit" class="btn btn-success mt-3 ">Submit</button>
                </form>
            </div>                  
        </div>
    </div>                        
</div>
@endsection
resources/views/edit.blade.php
//resources/views/edit.blade.php
@extends('layout')
    
@section('content')
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
              <h2>Edit Post</h2>
            </div>
            <div class="card-body">
                <form action="/update/{{ $posts->id }}" method="post" enctype="multipart/form-data">
                    @csrf
                    @method("put")
                    <input type="text" name="title" class="form-control m-2" placeholder="title" value="{{ $posts->title }}">
        			<input type="text" name="author" class="form-control m-2" placeholder="author" value="{{ $posts->author }}">
                    <Textarea name="body" cols="20" rows="4" class="form-control m-2" placeholder="body">{{ $posts->body }}</Textarea>
                    
                    <label class="m-2">Cover Image</label>
                    <input type="file" id="input-file-now-custom-3" class="form-control m-2" name="cover">
                    <label class="m-2">Images</label>
                    <input type="file" id="input-file-now-custom-3" class="form-control m-2" name="images[]" multiple>
                    <button type="submit" class="btn btn-success mt-3 ">Submit</button>
                </form>
                
                    <label class="m-2">Cover Image</label>
                    <form action="/deletecover/{{ $posts->id }}" method="post">
                    <button class="btn text-danger">X</button>
                    @csrf
                    @method('delete')
                    </form>
                    <img src="/cover/{{ $posts->cover }}" class="img-responsive" style="max-height: 100px; max-width: 100px;" alt="" srcset="">
                    <br>
                    
                    <label class="m-2">Images</label>
                    @if (count($posts->images)>0)
                    @foreach ($posts->images as $img)
                    <form action="/deleteimage/{{ $img->id }}" method="post">
                         <button class="btn text-danger">X</button>
                         @csrf
                         @method('delete')
                    </form>
                    <img src="/images/{{ $img->image }}" class="img-responsive" style="max-height: 100px; max-width: 100px;" alt="" srcset="">
                    @endforeach
                    @endif
                    
            </div>                  
        </div>
    </div>                        
</div>
@endsection
Routes routes/web.php
//routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
//Route::get('/', function () {
//    return view('welcome');
//});
Route::get('/',[PostController::class,'index']);
Route::get('/create',function(){
return view('create');
});
Route::post('/post',[PostController::class,'store']);
Route::delete('/delete/{id}',[PostController::class,'destroy']);
Route::get('/edit/{id}',[PostController::class,'edit']);
Route::delete('/deleteimage/{id}',[PostController::class,'deleteimage']);
Route::delete('/deletecover/{id}',[PostController::class,'deletecover']);
Route::put('/update/{id}',[PostController::class,'update']);
Create Folder under public cover and images public/cover Run C:\xampp\htdocs\laravel\my-app>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000

 
 
 
 
 
 
 
 
 
 
