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
