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> @endsectionresources/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> @endsectionresources/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> @endsectionRoutes
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