Web Development May 25, 2026 · 6 min read · 0 dilihat

Laravel 13 #10: Upload File & Manajemen Storage

Fitur upload file adalah salah satu kebutuhan paling sering di aplikasi web real-world — mulai dari foto profil user, gambar artikel, sampai dokumen lampiran. Di episode kesepuluh series "Belajar Laravel 13 dari Nol sampai Deploy", kita akan belajar cara menangani upload file dengan aman, benar, dan sesuai best practice Laravel. Artikel ini akan membimbing kamu membangun dua fitur umum: upload foto profil user dan thumbnail artikel blog. Kita akan cover validasi file (tipe, ukuran, ekstensi), penyimpanan file di storage directory yang aman, akses file via Storage facade, dan cara menghapus file lama saat user melakukan update. Semua konsep dijelaskan dengan kode praktis yang langsung bisa kamu terapkan ke project nyata.

IKHSAN MAULANA

IKHSAN MAULANA

Web, Android, and RPA Development

Laravel 13 #10: Upload File & Manajemen Storage

Di episode sebelumnya kamu sudah mempelajari relasi Eloquent — sekarang saatnya menambahkan fitur yang membuat aplikasi lebih menarik: upload file. Laravel menyediakan sistem storage yang robust dan mudah digunakan, jadi kamu tidak perlu khawatir tentang masalah teknis yang rumit.

Pada artikel ini, kita akan fokus pada dua use case paling sering ditemui di project blog: upload foto profil user dan thumbnail artikel. Kamu akan belajar cara setup storage, membuat form upload, validasi file dengan ketat, menyimpan file dengan aman, dan menghapus file lama saat perlu update. Mari kita mulai!

Konfigurasi Storage di Laravel 13

Pertama-tama, mari pahami struktur storage Laravel. Setiap project Laravel memiliki folder storage/app yang digunakan untuk menyimpan file upload. Namun, folder ini secara default tidak dapat diakses langsung dari web browser karena alasan keamanan — kamu tidak mau file tersimpan di public directory dan bisa diakses sembarangan.

Untuk membuat file storage bisa diakses, Laravel menyediakan fitur symlink. Buka terminal kamu dan jalankan perintah Artisan berikut:

php artisan storage:link

Perintah ini akan membuat symbolic link dari folder storage/app/public ke folder public/storage. Setelah itu, file yang tersimpan di storage/app/public bisa diakses melalui URL /storage/nama-file. Sangat praktis!

Secara default, konfigurasi storage Laravel sudah menggunakan local driver yang menyimpan file di server lokal. Kamu bisa lihat setting ini di file config/filesystems.php. Untuk keperluan development dan testing, setup default sudah cukup. Ketika deploy ke production, kamu bisa mengubah driver ke cloud storage seperti S3 jika diperlukan.

Membuat Form Upload di Blade

Sekarang mari buat form untuk upload file. Kita akan mulai dari form upload foto profil user. Pastikan form kamu menggunakan attribute enctype="multipart/form-data" — ini penting agar browser bisa mengirim file ke server.

Berikut contoh form sederhana di Blade template:

<form action="{{ route('profile.update') }}" method="POST" enctype="multipart/form-data">
    @csrf
    @method('PUT')
    
    <div class="form-group">
        <label for="avatar">Foto Profil</label>
        <input type="file" id="avatar" name="avatar" class="form-control" accept="image/*" />
        @error('avatar')
            <span class="text-danger">{{ $message }}</span>
        @enderror
    </div>
    
    <button type="submit" class="btn btn-primary">Update Profil</button>
</form>

Perhatikan beberapa hal penting di sini:

  • enctype="multipart/form-data" — wajib ada untuk form upload file
  • @csrf — token CSRF untuk keamanan
  • accept="image/*" — filter file picker agar hanya tampilkan file gambar (UX improvement, bukan validasi server)
  • Error handling dengan @error untuk menampilkan pesan validasi

Untuk fitur preview gambar sebelum upload, kamu bisa tambahkan JavaScript sederhana. Tapi artikel ini fokus pada backend, jadi kamu bisa coba kode tersebut sendiri di project kamu.

Validasi File: Tipe, Ukuran, dan Ekstensi

Validasi file adalah bagian paling krusial dari upload feature. Jangan pernah percaya input dari user — selalu validasi di server side. Laravel menyediakan validation rules yang powerful untuk file:

public function update(Request $request, User $user)
{
    $validated = $request->validate([
        'avatar' => 'nullable|image|mimes:jpeg,png,gif|max:2048',
        'name' => 'required|string|max:255',
    ]);
    
    // proses update...
}

Mari kita breakdown validation rules di atas:

  • nullable — field ini optional, jika tidak ada file tidak akan error
  • image — file harus berupa gambar (MIME type image/*)
  • mimes:jpeg,png,gif — hanya terima file dengan ekstensi jpeg, png, atau gif
  • max:2048 — ukuran file maksimal 2 MB (dalam kilobyte)

Untuk upload thumbnail artikel yang bisa berbentuk jpg, png, atau webp, kamu bisa tulis rule serupa:

'thumbnail' => 'required|image|mimes:jpeg,png,webp|max:5120'

Rule image dan mimes bekerja sama dengan memeriksa MIME type file yang sesungguhnya, bukan hanya nama ekstensionnya. Ini berarti user tidak bisa mengakali dengan rename file .exe menjadi .jpg — Laravel akan mendeteksi dan menolak.

Menyimpan dan Mengakses File

Setelah file divalidasi, saatnya menyimpannya. Laravel menyediakan method store() pada object file yang sangat mudah digunakan:

public function update(Request $request, User $user)
{
    $validated = $request->validate([
        'avatar' => 'nullable|image|mimes:jpeg,png,gif|max:2048',
        'name' => 'required|string|max:255',
    ]);
    
    // Hapus file lama jika ada
    if ($user->avatar && Storage::exists('public/avatars/' . $user->avatar)) {
        Storage::delete('public/avatars/' . $user->avatar);
    }
    
    // Simpan file baru
    if ($request->hasFile('avatar')) {
        $filename = $request->file('avatar')->store('public/avatars');
        $validated['avatar'] = basename($filename);
    }
    
    $user->update($validated);
    return redirect()->route('profile.show')->with('success', 'Profil berhasil diupdate!');
}

Method store() akan menyimpan file ke folder yang kamu tentukan dan return nama file (dengan path). Dengan memanfaatkan basename(), kita hanya menyimpan nama file ke database, bukan path lengkapnya.

Untuk mengakses file yang sudah disimpan, gunakan Storage::url():

<!-- Di Blade template -->
<img src="{{ Storage::url('public/avatars/' . $user->avatar) }}" alt="Foto Profil" />

Atau, kamu bisa membuat accessor di model User untuk mempermudah:

protected function avatar(): Attribute
{
    return Attribute::make(
        get: fn ($value) => $value ? Storage::url('public/avatars/' . $value) : null,
    );
}

Dengan cara ini, di template kamu cukup tulis $user->avatar dan Laravel akan otomatis return URL lengkap.

Hapus File Lama Saat Update

Scenario yang sering terjadi: user upload foto profil, lalu beberapa hari kemudian upload ulang dengan foto baru. Kamu perlu menghapus file lama agar storage tidak penuh dengan file tidak terpakai.

Gunakan Storage::delete() untuk menghapus file:

// Cek apakah file ada sebelum hapus
if (Storage::exists('public/avatars/' . $oldFilename)) {
    Storage::delete('public/avatars/' . $oldFilename);
}

Best practice adalah selalu cek keberadaan file terlebih dahulu sebelum delete, agar tidak ada error jika file sudah dihapus sebelumnya. Kamu juga bisa membuat event listener atau middleware untuk auto-cleanup file orphaned (file yang tidak ada referensi di database lagi) secara berkala, tapi itu topik advanced yang bisa kamu pelajari lebih lanjut.

Upload Multiple File dan Batch Processing

Bagaimana jika user ingin upload beberapa file sekaligus? Laravel juga support ini. Gunakan loop foreach untuk proses multiple file:

if ($request->hasFile('attachments')) {
    foreach ($request->file('attachments') as $file) {
        $filename = $file->store('public/attachments');
        Attachment::create([
            'post_id' => $post->id,
            'filename' => basename($filename),
        ]);
    }
}

Untuk form Blade, gunakan name="attachments[]" (perhatikan tanda kurung untuk array) dan tambah attribute multiple pada input file.

Kesimpulan

Upload file di Laravel 13 adalah fitur yang powerful namun mudah digunakan berkat system storage yang matang. Ingat selalu tiga pilar keamanan: validasi file di server (jangan percaya client), simpan file di storage bukan public folder, dan kelola file dengan baik (hapus yang tidak terpakai).

Di project blog kamu, kini kamu sudah bisa menambahkan fitur upload foto profil user dan thumbnail artikel dengan aman dan benar. Selanjutnya di episode #11, kita akan belajar membuat API dan JSON Response — fitur yang essential untuk membuat aplikasi modern yang terintegrasi dengan frontend atau mobile app. Sampai jumpa di episode berikutnya!

Tags:

#Laravel 13 #Web Development #Upload File #Storage #File Management

Share this article:

IKHSAN MAULANA

Tentang Penulis

IKHSAN MAULANA

Web, Android, and RPA Development

I am an experienced IT programmer specializing in Web Development (Laravel/PHP), Android (Dart/Flutter), and RPA (UiPath). I love building clean, efficient solutions that solve real-world problems. With 4+ years of hands...

Download CV

Sebelum download, boleh kenalan dulu? Form ini opsional — kosongin juga gak apa-apa, langsung klik Download.