Hampir setiap aplikasi butuh fitur unggah file: foto profil, gambar produk, atau lampiran dokumen. Laravel menyediakan sistem penyimpanan (Storage) yang rapi dan aman untuk menangani ini. Artikel ini membahas cara upload file dan gambar di Laravel secara lengkap, dari validasi hingga menghapus file lama.
Konsep Penyimpanan di Laravel
Laravel menyimpan file yang diunggah di folder storage/app/public, bukan langsung di public. Ini demi keamanan dan keteraturan. Agar file bisa diakses browser, kita membuat “jembatan” (symbolic link) dari public/storage ke folder tersebut.

Langkah 1: Menyiapkan Storage
Jalankan perintah ini sekali saja di awal proyek:
php artisan storage:link
Perintah ini membuat tautan public/storage → storage/app/public. Sekarang file di storage/app/public/foto/a.jpg bisa diakses lewat URL /storage/foto/a.jpg.
Langkah 2: Membuat Form Upload
Form upload wajib punya atribut enctype="multipart/form-data", jika tidak, file tidak akan terkirim:
<form action="/produk" method="POST" enctype="multipart/form-data">
@csrf
<input type="text" name="nama" placeholder="Nama produk">
<input type="file" name="gambar" accept="image/*">
@error('gambar') <span style="color:red">{{ $message }}</span> @enderror
<button type="submit">Simpan</button>
</form>
Langkah 3: Memproses Upload di Controller
Di controller, validasi file lalu simpan. Laravel menyediakan method store() yang otomatis membuat nama file unik:
<?php
public function store(Request $request)
{
// 1. validasi
$request->validate([
'nama' => 'required',
'gambar' => 'required|image|mimes:jpg,jpeg,png|max:2048', // maks 2MB
]);
// 2. simpan file ke storage/app/public/produk
// store() otomatis memberi nama acak yang unik
$path = $request->file('gambar')->store('produk', 'public');
// 3. simpan path ke database
Produk::create([
'nama' => $request->nama,
'gambar' => $path, // contoh: "produk/9xKq2....jpg"
]);
return redirect('/produk')->with('sukses', 'Produk ditambahkan!');
}
?>
Anda juga bisa menentukan nama file sendiri dengan storeAs('produk', 'namafile.jpg', 'public'), tetapi store() lebih aman karena namanya pasti unik (tidak saling menimpa).
Langkah 4: Menampilkan Gambar
Gunakan helper asset('storage/...') untuk membuat URL gambar di Blade:
@foreach ($produk as $p)
<div>
<img src="{{ asset('storage/' . $p->gambar) }}" width="150">
<p>{{ $p->nama }}</p>
</div>
@endforeach
Langkah 5: Mengganti Gambar Saat Edit (Hapus yang Lama)
Saat pengguna mengganti gambar, file lama harus dihapus agar storage tidak penuh sampah:
<?php
use Illuminate\Support\Facades\Storage;
public function update(Request $request, Produk $produk)
{
$data = $request->validate([
'nama' => 'required',
'gambar' => 'nullable|image|max:2048',
]);
// jika ada gambar baru diunggah
if ($request->hasFile('gambar')) {
// hapus gambar lama
Storage::disk('public')->delete($produk->gambar);
// simpan gambar baru
$data['gambar'] = $request->file('gambar')->store('produk', 'public');
}
$produk->update($data);
return redirect('/produk');
}
?>
Perhatikan aturan nullable pada gambar — artinya gambar boleh tidak diisi saat edit (tetap pakai yang lama).
Menghapus File Saat Data Dihapus
<?php
public function destroy(Produk $produk)
{
Storage::disk('public')->delete($produk->gambar);
$produk->delete();
return redirect('/produk');
}
?>
Upload Banyak File Sekaligus
Untuk input <input type="file" name="foto[]" multiple>:
<?php
foreach ($request->file('foto') as $file) {
$path = $file->store('galeri', 'public');
Galeri::create(['path' => $path]);
}
?>
Kesalahan Umum
- Gambar tidak muncul (404) — lupa menjalankan
php artisan storage:link. - File tidak terkirim — lupa
enctype="multipart/form-data"pada form. - Error “file too large” — batas
upload_max_filesizediphp.inilebih kecil dari validasi Anda. - Storage penuh sampah — lupa menghapus file lama saat edit/hapus data.
Kesimpulan
Anda telah menguasai upload file dan gambar di Laravel secara menyeluruh: setup storage, validasi, menyimpan dengan nama unik, menampilkan, mengganti dengan menghapus file lama, hingga upload banyak file. Sistem Storage Laravel membuat pengelolaan file jauh lebih aman dan rapi dibanding PHP native. Untuk aplikasi besar, Anda bahkan bisa mengarahkan penyimpanan ke cloud (Amazon S3) hanya dengan mengubah konfigurasi disk.
Referensi: untuk pendalaman, kunjungi dokumentasi resmi Laravel.

