Laravel menyediakan kemudahan bagi kita untuk bekerja dengan sistem file dan memiliki berbagai macam metode yang bisa kita gunakan. Kita bisa menyimpan, mengambil atau menampilkan, dan menghapus file di laravel dengan mudah dan dengan penyimpanan sistem baik local ataupun ke server cloud.
Sebagai contoh mari kita coba menggunakan file sistem mengupload atau membuat fungsi menyimpan gambar ke database.
Yang akan dibuat:
- Membuat metode request file upload gambar di laravel
- Membuat component vue dan element input
- Menyimpan gambar ke public path dan database MySQL
- Membuat permintaan http menggunakan Axios
Instalasi Laravel dan Library Vue
Kita siapkan projek terlebih dahulu. Kita install laravel, membuat tabel kolom database, dan menambahkan library vue ke projek.
Install laravel
laravel new example-app
Database
Silahkan buat database MySQL baru dan hubungkan dengan projek.
MariaDB [(none)]> create database db_images; Query OK, 1 row affected (0.009 sec) //.env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=db_images DB_USERNAME=root DB_PASSWORD=
Membuat File Migrasi
Kita tambahkan file migrasi baru untuk tabel khusus Images
.
php artisan make:model Image -m
Lalu tambahkan sebuah kolom dan lakukan migrasi.
//...create_images_table.php public function up() { Schema::create('images', function (Blueprint $table) { $table->id(); $table->string('image'); $table->timestamps(); }); }
php artisan migrate
MariaDB [uploadimage]> show tables; +-----------------------+ | Tables_in_uploadimage | +-----------------------+ | failed_jobs | | images | | migrations | | password_resets | | users | +-----------------------+ 5 rows in set (0.001 sec)
Konfigurasi Vue
Selanjutnya kita install vue, membuat instance dan component vue.
npm install vue vue-loader vue-template-compiler --save-dev
Setelah depedensi diatas ditambahkan, silahkan buka file app.js dan buat vue instance seperti dibawah ini.
//resources/js/app.js import Vue from 'vue'; import App from './components/App.vue' new Vue({ el: '#app', components: { App } });
Kemudian buat folder baru di direktori js dengan nama components dan tambahkan sebuah component App.vue didalamnya lalu copas template dibawah ini.
//js/components/App.js <template> <div class="container"> <h1>Upload New Image</h1> </div> </template>
Selanjutnya buka file welcome.blade.php dan ubah html yang ada dengan dibawah ini.
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Upload New Image</title> <!-- Fonts --> <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Nunito', sans-serif; } </style> </head> <body> <div id="app"> <app></app> </div> <script src="{{ mix('js/app.js') }}"></script> </body> </html>
Terakhir, kita buka file webpack.mix.js dan buat seperti dibawah ini kemudian lakukan compiling.
const mix = require('laravel-mix'); mix.js('resources/js/app.js', 'public/js') .vue();
Kita gunakan saja mix watch
yang akan tetap aktif untuk meng-compile secara otomatis setiap ada perubahan pada file js kita.
npm run watch
Setelah selesai silahkan buat tab baru pada terminal lalu jalankan php artisan serve
. Kemudian buka aplikasi pada browser dan kita pastikan vue.js sudah terinstal.
Model, Controller, dan Route
Selanjutnya kita akan buat sebuah controller dan membuat metode permintaan, route, dan mass assignment model.
Pertama mari kita buka model Image.php dan tambahkan metode $fillable
seperti dibawah ini.
... class Image extends Model { use HasFactory; protected $fillable = [ 'image' ]; }
Kemudian kita buat controller dengan nama ImageController lalu kita buat request seperti dibawah.
php artisan make:controller ImageController
//ImageController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Image; class ImageController extends Controller { public function uploadImage(Request $request) { $request->validate([ 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg', ]); $name = time()."-".$request->file('image')->getClientOriginalName(); $request->file('image')->move(public_path('images'), $name); Image::create([ 'image' => $name ]); return response()->json([ 'data' => asset("images/$name"), 'message' => 'Gambar baru berhasil disimpan.' ]); } }
Mari kita lihat controller diatas. Kita tambahkan validasi dimana value tidak boleh kosong saat mengirim permintaan dan hanya file dengan extensi jpeg, png, jpg, gif, svg
yang diperbolehkan.
Kemudian kita gunakan metode getClientOriginalName()
untuk menyimpan file dengan nama asli dari file tersebut, dan gambar yang berhasil disimpan akan masuk ke direktori public di dalam folder images.
Kita tidak perlu membuat folder images karena nanti akan otomatis terbuat.
Dan karena tidak bisa menyimpan gambar dengan nama yang sama, kita gunakan metode time()
untuk membuat atau menambahkan nama unik ke setiap file.
Kita juga simpan file gambar ke database menggunakan metode create
, dan akan menghasilkan response barupa informasi file gambar dan pesan berhasil.
Setelah metode uploadImage()
diatas dibuat, selanjutnya kita buka file route web.php dan tambahkan route dibawah ini.
use App\Http\Controllers\ImageController; Route::post('/addimage', [ImageController::class, 'uploadImage']);
Kita buka kembali component App.vue dan silahkan buat seperti dibawah ini.
<template> <div class="container"> <h1>Upload New Image</h1> <p>{{message}}</p> <div v-if="errors" class="errors"> <p v-for="(error,index) in errors" :key="index" >{{error}}</p> </div> <div class="preview" v-if="preview"> <p>Preview: </p> <img :src="preview" width="200" height="150"> </div> <div> <input type="file" ref="file" id="file" @change="fileImage"> <button class="modal-default-button" @click="uploadFile"> Save </button> </div> </div> </template> <script> import axios from 'axios' export default { data(){ return { image : null, message : null, preview : null, errors: null } }, methods : { fileImage(event){ this.image = event.target.files[0]; this.preview = URL.createObjectURL(event.target.files[0]); }, uploadFile(event){ var formData = new FormData(); formData.append("image", this.image) axios.post("/addimage", formData) .then(response => { this.image = response.data.data this.message = response.data.message this.preview = null this.$refs.file.value = null; this.errors = null //console.log(response); }) .catch(error => { this.errors = error.response.data.errors.image this.message = null }) } } } </script> <style scoped> .container{ border: 1px solid; width: 28rem; margin: 2rem auto 0; padding: 2rem; } .errors{ color: #f44336; } h1{ margin-top: 0; } </style>
Kita gunakan metode URL.createObjectURL
untuk menghasilkan url
dari object file gambar yang dipilih yang kita gunakan untuk membuat preview sebelum dikirim, dan $refs
untuk mengakses value inputan untuk dikosongkan setelah berhasil mengirim permintaan.
Sekarang mari kita mencobanya. Silahkan coba untuk upload gambar baru dan coba juga munculkan validasi dengan mengirim permintaan tanpa gambar.
Hasilnya seperti gambar dibawah ini.
Setelah berhasil mengirim gambar, silahkan buka folder images di direktori public dan juga database untuk melihat file gambar yang tersimpan.
Selesai. Kita sampai disini, silahkan dicoba dan dikembangkan.