CRUD Resize Gambar Laravel 9 – Tutorial Create, Read, Update, dan Delete Gambar dan Resize Laravel 9 dengan Bootstrap 5 dan MySQL. Pada tutorial ini, menggunakan kasus mengolah data posting (artikel). Pada artikel sebelumnya sudah membahas tentang Crud User Laravel 8.
Langkah 1: Membuat Project Laravel
Pastikan Anda sudah menginstall composer, kemudian jalankan perintah berikut di command prompt.
composer create-project laravel/laravel laravel-crud-image
Langkah 2: Mengatur Database MySQL
Buat database dengan nama laravel_crud_image
di http://localhost/phpmyadmin
jika Anda menginstall XAMPP untuk server MySQL.
Sesuaikan pengaturan koneksi mysql di project laravel pada file .env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_crud_image DB_USERNAME=root DB_PASSWORD=
Sesuaikan DB_HOST
, DB_PORT
, DB_DATABASE
, DB_USERNAME
, dan DB_PASSWORD
sesuai server MySQL.
Langkah 2: Membuat Migration Post
Buat migration untuk posts
dengan perintah berikut.
php artisan make:migration create_posts_table
Kemudian sesuaikan field pada post migration yang ada di direktori database/migrations
sebagai berikut
<?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('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('image'); $table->string('description')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } };
Perintah insert
berfungsi untuk menambahkan data post langsung ketika selesai membuat tabel.
Lakukan migration dengan mengetikan perintah berikut.
php artisan migrate
Setelah berhasil menjalankan perintah migrate, maka di database akan ada tabel posts
.
Langkah 3: Membuat Model Post
Buat model Post menggunakan perintah berikut.
php artisan make:model Post
Sesuaikan app/models/Post.php
sebagai berikut.
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model { use HasFactory; protected $fillable = ['title', 'image', 'description']; function image($real_size = false) { $thumbnail = $real_size ? '' : 'small_'; if ($this->image && file_exists(public_path('images/post/' . $thumbnail . $this->image))) return asset('images/post/' . $thumbnail . $this->image); else return asset('images/no_image.png'); } function delete_image() { if ($this->image && file_exists(public_path('images/post/' . $this->image))) unlink(public_path('images/post/' . $this->image)); if ($this->image && file_exists(public_path('images/post/small_' . $this->image))) unlink(public_path('images/post/small_' . $this->image)); } }
Properti $fillable
untuk mengatur field apa saja yang bisa diinput/ubah ketika melakukan crud di tabel post.
Langkah 4: Menambahkan Intervention/Image
Gunakan perintah berikut untuk menambahkan library Intervention/Image ke project laravel.
composer require intervention/image
Tambahkan Intervention\Image\ImageServiceProvider::class
pada providers di config/app.php
<?php /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, Intervention\Image\ImageServiceProvider::class, ],
Langkah 5: Membuat Controller Post Tipe Resource
Gunakan perintah berikut untuk membuat controller resource sekaligus mengatur model menjadi Post.
php artisan make:controller PostController --resource --model=Post
Sesuaikan app/controllers/PostController.php
sebagai berikut.
<?php namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Http\Request; use Intervention\Image\Facades\Image; class PostController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(Request $request) { $data['title'] = 'Posts'; $data['q'] = $request->query('q'); $data['posts'] = Post::where('title', 'like', '%' . $data['q'] . '%')->get(); return view('post.index', $data); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $data['title'] = 'Add Post'; return view('post.create', $data); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $request->validate([ 'title' => 'required', 'image' => 'required', ]); $image = $request->file('image'); $file_name = rand(1000, 9999) . $image->getClientOriginalName(); $img = Image::make($image->path()); $img->resize('180', '120') ->save(public_path('images/post') . '/small_' . $file_name); $image->move('images/post', $file_name); $post = new Post(); $post->title = $request->title; $post->image = $file_name; $post->description = $request->description; $post->save(); return redirect()->route('post.index')->with('success', 'Post added successfully'); } /** * Display the specified resource. * * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function show(Post $post) { $data['title'] = $post->title; $data['post'] = $post; return view('post.show', $data); } /** * Show the form for editing the specified resource. * * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function edit(Post $post) { $data['title'] = 'Edit Post'; $data['post'] = $post; return view('post.edit', $data); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function update(Request $request, Post $post) { $request->validate([ 'title' => 'required', ]); if ($request->hasFile('image')) { $post->delete_image(); $image = $request->file('image'); $file_name = rand(1000, 9999) . $image->getClientOriginalName(); $img = Image::make($image->path()); $img->resize('180', '120') ->save(public_path('images/post') . '/small_' . $file_name); $image->move('images/post', $file_name); $post->image = $file_name; } $post->title = $request->title; $post->description = $request->description; $post->save(); return redirect()->route('post.index')->with('success', 'Post edited successfully'); } /** * Remove the specified resource from storage. * * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function destroy(Post $post) { $post->delete_image(); $post->delete(); return redirect()->route('post.index')->with('success', 'Post deleted successfully'); } }
Buat folder public/images/post
untuk menyimpan gambar hasil upload. Sediakan juga file gambar public/images/no_image.png
untuk post yang tidak berisi gambar.
Langkah 5: Menambahkan Route Post
Tambahkan route untuk crud post di routes/web.php
bertipe resource
seperti berikut.
<?php use App\Http\Controllers\PostController; use Illuminate\Support\Facades\Route; /* |-------------------------------------------------------------------------- | 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::get('/', function () { return view('welcome'); }); Route::resource('post', PostController::class);
Langkah 6: Membuat View
View Template
Buat view untuk template di direktori resources/views/app.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.0"> <title>@yield('title', $title)</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <h1>@yield('title', $title)</h1> @yield('content') </div> </body> </html>
View Tampil
Buat view untuk menampilkan data post di direktori resources/views/post/index.blade.php
.
@extends('app') @section('content') @if(session('success')) <p class="alert alert-success">{{ session('success') }}</p> @endif <div class="card"> <div class="card-header"> <form class="row row-cols-lg-auto g-1"> <div class="col"> <input class="form-control" type="text" name="q" value="{{ $q}}" placeholder="Search here..." /> </div> <div class="col"> <button class="btn btn-success">Refresh</button> </div> <div class="col"> <a class="btn btn-primary" href="{{ route('post.create') }}">Add</a> </div> </form> </div> <div class="card-body p-0 table-responsive"> <table class="table table-bordered table-striped table-hover mb-0"> <thead> <tr> <th>#</th> <th>Title</th> <th>Image</th> <th>Action</th> </tr> </thead> @foreach($posts as $key => $post) <tr> <td>{{ $key + 1 }}</td> <td>{{ $post->title }}</td> <td> <img src="{{ $post->image() }}" height="75" /> </td> <td class="text-nowrap"> <a class="btn btn-sm btn-info" href="{{ route('post.show', $post) }}">Show</a> <a class="btn btn-sm btn-warning" href="{{ route('post.edit', $post) }}">Edit</a> <form method="POST" action="{{ route('post.destroy', $post) }}" style="display: inline-block;"> @csrf @method('DELETE') <button class="btn btn-sm btn-danger" onclick="return confirm('Hapus Data?')">Delete</button> </form> </td> </tr> @endforeach </table> </div> </div> @endsection
View Tambah
Buat view untuk menambah data post di direktori resources/views/post/create.blade.php
.
@extends('app') @section('content') <div class="row"> <div class="col-md-6"> @if($errors->any()) @foreach($errors->all() as $err) <p class="alert alert-danger">{{ $err }}</p> @endforeach @endif <form action="{{ route('post.store') }}" method="POST" enctype="multipart/form-data"> @csrf <div class="mb-3"> <label>Title <span class="text-danger">*</span></label> <input class="form-control" type="text" name="title" value="{{ old('title') }}" /> </div> <div class="mb-3"> <label>Image <span class="text-danger">*</span></label> <input class="form-control" type="file" name="image" /> </div> <div class="mb-3"> <label>Description</label> <textarea class="form-control" name="description" rows="10">{{ old('description') }}</textarea> </div> <div class="mb-3"> <button class="btn btn-primary">Save</button> <a class="btn btn-danger" href="{{ route('post.index') }}">Back</a> </div> </form> </div> </div> @endsection
View Ubah
Buat view untuk menambah data post di direktori resources/views/post/edit.blade.php
.
@extends('app') @section('content') <div class="row"> <div class="col-md-6"> @if($errors->any()) @foreach($errors->all() as $err) <p class="alert alert-danger">{{ $err }}</p> @endforeach @endif <form action="{{ route('post.update', $post) }}" method="POST" enctype="multipart/form-data"> @csrf @method('PUT') <div class="mb-3"> <label>Title <span class="text-danger">*</span></label> <input class="form-control" type="text" name="title" value="{{ old('title', $post->title) }}" /> </div> <div class="mb-3"> <label>Image <span class="text-danger">*</span></label> <input class="form-control" type="file" name="image" /> <div class="form-text"> <img src="{{ $post->image() }}" height="75" /> </div> </div> <div class="mb-3"> <label>Description</label> <textarea class="form-control" name="description" rows="10">{{ old('description', $post->description) }}</textarea> </div> <div class="mb-3"> <button class="btn btn-primary">Save</button> <a class="btn btn-danger" href="{{ route('post.index') }}">Back</a> </div> </form> </div> </div> @endsection
Langkah 7: Menjalankan Crud Gambar Laravel 8
Silahkan gunakan perintah berikut untuk mengaktifkan server laravel.
php artisan serve
Ketikkan alamat sesuai server diikuti dengan /post di browser (http://127.0.0.1:8000/post
). Hasilnya seperti berikut.
Itulah tutorial membuat CRUD Resize gambar laravel 9. Jika ada yang ditanyakan, silahkan berkomentar.
Samsul Arifin
says:File view untuk view tampil ke bawah tidak ada ya?
admin
says:Maaf ketinggalan, silahkan cek lagi.
Samsul Arifin
says:Oke, thanks. Satu lagi, sepertinya ada fungsi yang hilang di Model Post.php, fungsi delete_image tidak ada, barangkali perlu dicek.
Terimakasih
admin
says:Baik, sudah saya update. Terimakasih atas koreksinya.
aszen
says:min, jika function image() yang dipanggil di view mendapatkan eror seperti ini
“Call to undefined method stdClass”
itu bagaimana ya
admin
says:Itu berarti belum ditambahkan method image di Model Post.
function image()
{
if ($this->image && file_exists(public_path(‘images/post/’ . $this->image)))
return asset(‘images/post/’ . $this->image);
else
return asset(‘images/no_image.png’);
}
aszen
says:sudah ditambahkan min, pada modelnya. sesuai dengan tutorial yang admin tulis diatas.
sama untuk line code ini row diambil dari mana ya min?
$data[‘rows’] = Post::where(‘post_title’, ‘like’, ‘%’ . $request->q . ‘%’)->get();
sama yang ini apa beda nya min row dengan ‘s’ dan row tanpa ‘s’
$data[‘row’] = $post;
admin
says:Row itu hanya sebuah penamaan variabel untuk 1 baris data, bebas bisa diganti, yang jelas nanti sesuaikan di view ketika memanggil datanya. Untuk rows itu menampilkan banyak baris data post untuk halaman tampil post, kalau row hanya 1 baris data post saja untuk ubah atau hapus.
Afif
says:Min posisi udah ke upload tapi datanya masuk db tpi gambar gak bisa kesimpan. udah saya cek berkali2 sama aja min
admin
says:– Pastikan gambar sudah berhasil diupload di folder images/post
– Pastikan nama gambar sudah tersimpan di field gambar di tb_post
Siska
says:Saat di save tdk bisa ditampilkan, error di PostController.php:50
$img = image::make($image->path());