Pernah nggak kamu download sebuah aplikasi web, terus bisa upload foto profil, kirim PDF lamaran, atau bahkan upload file Excel? Nah, fitur itu semua butuh sistem upload file yang solid di baliknya. Di Laravel, proses ini jauh lebih rapi dibanding PHP murni — tapi tetap butuh pemahaman yang benar agar file kamu nggak berserakan di server atau malah bocor ke publik.
Di artikel ke-20 dari seri 50 Artikel Belajar Laravel Lengkap ini, kita bakal kupas tuntas cara upload file di Laravel — mulai dari gambar, dokumen, sampai file umum lainnya. Oh iya, nanti kita juga nyinggung sedikit soal migration laravel karena tabel database juga perlu kita siapkan untuk menyimpan path file. Let's go!
Upload file di Laravel bekerja lewat tiga komponen utama: Form HTML (dengan enctype multipart), Request Handler di Controller (menggunakan $request->file()), dan Storage Facade dari Laravel yang mengurus penyimpanan file secara aman dan terorganisir.
🗂️ Kenapa Upload File di Laravel Lebih Aman dari PHP Biasa?
Bayangkan kamu punya loker penyimpanan. Di PHP murni, kamu sering langsung lempar barang ke loker tanpa dicek dulu — siapa tahu yang masuk itu bom waktu alias file berbahaya. Laravel hadir dengan sistem yang lebih "dewasa": ada penjaga loker (validasi), ada label nama (rename otomatis), dan ada ruangan khusus yang terkunci (storage disk).
Laravel mengabstraksi kompleksitas upload file lewat beberapa fitur unggulan:
| Fitur | PHP Murni | Laravel |
|---|---|---|
| Validasi tipe file | Manual dengan mime_content_type() | ✅ Rules bawaan (mimes, max) |
| Rename otomatis | Kode manual diperlukan | ✅ hashName() / store() |
| Multi-disk storage | ❌ Tidak ada | ✅ Local, S3, GCS, dll |
| Akses publik vs privat | Konfigurasi server manual | ✅ Storage::url() / disk() |
| Migration & path di DB | Tidak ada integrasi | ✅ Via migration laravel + Eloquent |
Menurut data OWASP, unrestricted file upload masuk dalam daftar 10 kerentanan web paling berbahaya. Artinya, salah handle upload file bisa bikin servermu jadi playground hacker. Laravel sudah punya mekanisme perlindungan bawaan — tapi kamu tetap harus menggunakannya dengan benar!
⚙️ Persiapan: Migration Laravel untuk Menyimpan Path File
Sebelum mulai upload, kita perlu menyiapkan database dulu. Nah, di sinilah migration laravel berperan penting — kita butuh kolom untuk menyimpan path file yang sudah diupload. Anggap saja migration seperti "blueprintnya" loker tempat kita simpan alamat file.
Sebagai contoh, kita akan membuat fitur upload foto profil untuk user. Berikut langkah-langkahnya:
Jalankan perintah ini di terminal untuk membuat file migration laravel baru:
Buka file migration yang baru dibuat, lalu tambahkan kolom avatar:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar')->nullable();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar');
});
}
Eksekusi migration laravel agar perubahan diterapkan ke database:
Agar file bisa diakses publik melalui URL, jalankan perintah ini (cukup sekali per project):
Selalu tambahkan ->nullable() pada kolom path file di migration laravel. Ini mencegah error ketika user belum mengupload file sama sekali — karena nilainya boleh kosong (NULL) di database.
📤 Implementasi Upload File: Form, Controller, dan Storage
Sekarang kita masuk ke inti dari migration laravel dan implementasi fitur upload. Ada tiga bagian yang perlu kita buat: form di Blade view, logika di Controller, dan konfigurasi storage. Kita akan buat semuanya step by step.
Kunci utama: tambahkan enctype="multipart/form-data" di tag form. Tanpa ini, file tidak akan terkirim!
<form action="{{ route('profile.update') }}"
method="POST"
enctype="multipart/form-data">
@csrf
@method('PUT')
<input type="file"
name="avatar"
accept="image/*">
<button type="submit">Upload Foto</button>
</form>
Inilah inti logikanya — validasi dulu, baru simpan. Metode store() otomatis memberi nama unik pada file:
use Illuminate\Support\Facades\Storage;
public function update(Request $request)
{
$request->validate([
'avatar' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
]);
if ($request->hasFile('avatar')) {
// Hapus file lama jika ada
if (auth()->user()->avatar) {
Storage::disk('public')->delete(auth()->user()->avatar);
}
// Simpan file baru
$path = $request->file('avatar')->store('avatars', 'public');
auth()->user()->update(['avatar' => $path]);
}
return back()->with('success', 'Foto profil berhasil diperbarui!');
}
Gunakan Storage::url() untuk mendapatkan URL publik dari file yang tersimpan:
@if(auth()->user()->avatar)
<img src="{{ Storage::url(auth()->user()->avatar) }}"
alt="Foto Profil"
style="width:100px;border-radius:50%;">
@else
<img src="{{ asset('images/default-avatar.png') }}"
alt="Avatar Default">
@endif
store('avatars', 'public') menyimpan file dengan nama acak (hash) — lebih aman dan mencegah overwrite. Sedangkan storeAs('avatars', 'namafile.jpg', 'public') memberi kamu kontrol penuh atas nama file. Untuk upload user-generated content, selalu gunakan nama acak!
📄 Upload Dokumen & File Lainnya di Laravel
Upload bukan cuma soal gambar! Kamu mungkin butuh menerima PDF, Excel, atau file ZIP dari user. Konsepnya sama — yang berbeda hanya validasi rule-nya dan bagaimana kamu menyajikan file itu kembali ke user (preview vs download).
Dokumen sensitif (KTP, kontrak, laporan keuangan) jangan disimpan di disk public! Gunakan disk local (default) dan sediakan route khusus dengan autentikasi untuk men-download file tersebut via Storage::download().
- Foto profil user
- Thumbnail artikel/produk
- Aset yang perlu URL publik
- File yang di-embed di halaman web
- Dokumen identitas (KTP, SIM)
- Kontrak & dokumen legal
- Laporan keuangan
- File internal perusahaan
Jangan lupa tambahkan kolom avatar atau path ke array $fillable di Model kamu. Tanpa ini, Laravel akan menolak mass assignment dan file path tidak akan tersimpan ke database — bug yang sering bikin bingung pemula!
No comments:
Post a Comment