[{"data":1,"prerenderedAt":95},["ShallowReactive",2],{"\u002Fposts\u002Fupload-file-gambar-dan-validasi-cpw3?{\"username\":\"irezabdullah\"}":3},{"success":4,"message":5,"data":6},true,"Post retrieved successfully",{"post":7,"seriesInfo":25,"seriesItems":28,"seoDescription":94},{"id":8,"title":9,"slug":10,"body":11,"cover_image_path":12,"view_count":13,"part_number":14,"created_at":15,"updated_at":16,"category":17,"author":20},63,"Upload File (Gambar) dan Validasi","upload-file-gambar-dan-validasi-cpw3","### 🎯 Tujuan Pembelajaran\n\nDi materi ini, diharapkan pembaca mampu:\n\n* Menambahkan fitur upload gambar pada form tambah dan edit produk di Laravel.\n* Memahami alur upload file di Laravel, mulai dari menerima input file, validasi, menyimpan, hingga menampilkannya kembali.\n* Melakukan validasi file termasuk tipe file (image), ukuran maksimal, serta keamanan dasar dalam proses upload.\n* Menyimpan file secara aman ke folder `public\u002Fstorage\u002Fproducts` menggunakan `store()` bawaan Laravel.\n* Menyimpan nama file ke database melalui kolom `image` pada tabel `products`.\n\n---\n\n#### 1. Memahami Alur Upload File di Laravel\n\nSebelum menulis kode, penting memahami alur teknis upload file di Laravel:\n\n**Request**\n\nFile dikirim dari form menggunakan `multipart\u002Fform-data`, dan Laravel menyiapkan objek file di `$request->file('image')`.\n\n**Validasi**\n\nRule `image` memastikan file adalah gambar (jpg, jpeg, png, gif, svg, webp).\nRule `max` membatasi ukuran file dalam kilobytes.\n\n**Store \u002F Penyimpanan File**\n\nFungsi `store()` digunakan untuk:\n\n* membuat nama file unik otomatis,\n* mencegah file tertimpa,\n* memastikan file berada di folder yang sesuai konfigurasi.\n\n**Menyimpan Nama File ke Database**\n\nYang disimpan bukan file-nya, tetapi *nama file (path)* agar bisa ditampilkan kembali.\n\n**Menampilkan Gambar**\n\nGambar dapat ditampilkan melalui `asset('storage\u002F...')`.\n\n**Dokumentasi Laravel:**\n\n📌 Filesystem Uploads: [https:\u002F\u002Flaravel.com\u002Fdocs\u002F11.x\u002Ffilesystem#file-uploads](https:\u002F\u002Flaravel.com\u002Fdocs\u002F11.x\u002Ffilesystem#file-uploads)\n📌 Validation Rule Image: [https:\u002F\u002Flaravel.com\u002Fdocs\u002F11.x\u002Fvalidation#rule-image](https:\u002F\u002Flaravel.com\u002Fdocs\u002F11.x\u002Fvalidation#rule-image)\n\n---\n\n#### 2. Konfigurasi Storage (Dijalankan Sekali)\n\nFolder `storage\u002Fapp\u002Fpublic` tidak otomatis bisa diakses secara publik.\nJalankan perintah berikut:\n\n```bash\nphp artisan storage:link\n```\n\nPenjelasan:\n\n* Perintah ini membuat folder `public\u002Fstorage` sebagai symbolic link.\n* Semua file yang di-upload ke disk `public` akan tersedia melalui URL `storage\u002F...`.\n* Tanpa symbolic link ini, gambar tidak akan muncul meski upload berhasil.\n\n---\n\n#### 3. Tambahkan Input File Pada Form Create & Edit\n\nDua aturan penting:\n\n1. Form wajib memakai `enctype=\"multipart\u002Fform-data\"`.\n2. Input harus `\u003Cinput type=\"file\">`.\n\n###### resources\u002Fviews\u002Fproducts\u002Fcreate.blade.php\n\n```html\n\u003Cform action=\"{{ route('products.store') }}\" method=\"POST\" enctype=\"multipart\u002Fform-data\">\n    @csrf\n\n    \u003C!-- input lainnya -->\n\n    \u003Cdiv class=\"mb-3\">\n        \u003Clabel>Gambar Produk\u003C\u002Flabel>\n        \u003Cinput type=\"file\" name=\"image\" class=\"form-control\">\n    \u003C\u002Fdiv>\n\n    \u003Cbutton class=\"btn btn-primary\">Simpan\u003C\u002Fbutton>\n\u003C\u002Fform>\n```\n\n###### resources\u002Fviews\u002Fproducts\u002Fedit.blade.php\n\nBiasanya form edit menampilkan gambar lama sebagai preview (opsional).\n\n---\n\n#### 4. Controller: Store Produk + Upload Gambar\n\n```php\npublic function store(Request $request)\n{\n    $request->validate([\n        'name' => 'required|min:3',\n        'price' => 'required|numeric|min:100',\n        'stock' => 'required|numeric|min:1',\n        'image' => 'nullable|image|max:2048' \u002F\u002Fvalidasi file upload\n    ]);\n\n    if ($request->hasFile('image')) {\n        $image = $request->file('image')->store('products', 'public');\n    }\n\n    Product::create([\n        'name' => $request->name,\n        'price' => $request->price,\n        'description' => $request->description,\n        'stock' => $request->stock,\n        'image' => $image ?? null\n    ]);\n\n    return redirect()->route('products.index');\n}\n```\n\nPenjelasan:\n\n* `image` memvalidasi file gambar.\n* `max:2048` = maksimal 2MB.\n* Laravel membuat nama file hash agar menghindari duplikasi.\n\n---\n\n#### 📌 Penjelasan Tambahan: Validasi Format File\n\nJika ingin membatasi ekstensi tertentu, seperti:\n\n**Hanya PNG**\n\n```php\n'image' => 'nullable|mimes:png|max:2048',\n```\n\n**Hanya JPG\u002FJPEG**\n\n```php\n'image' => 'nullable|mimes:jpg,jpeg|max:2048',\n```\n\n**PNG + JPG**\n\n```php\n'image' => 'nullable|mimes:png,jpg,jpeg|max:2048',\n```\n\n---\n\n#### 5. Controller: Update Produk + Replace Gambar Lama\n\n```php\npublic function update(Request $request, $id)\n{\n    $request->validate([\n        'name' => 'required|min:3',\n        'price' => 'required|numeric|min:100',\n        'stock' => 'required|numeric|min:1',\n        'image' => 'nullable|image|max:2048'\n    ]);\n\n    $product = Product::findOrFail($id);\n    if ($request->hasFile('image')) {\n        if ($product->image && Storage::disk('public')->exists($product->image)) {\n            Storage::disk('public')->delete($product->image);\n        }\n        $image = $request->file('image')->store('products', 'public');\n    }\n\n    $product->update([\n        'name' => $request->name,\n        'price' => $request->price,\n        'stock' => $request->stock,\n        'description' => $request->description,\n        'image' => $image ?? $product->image\n    ]);\n\n    return redirect()->route('products.index');\n}\n```\n\nKelebihan pola update ini:\n\n* File lama tidak menumpuk.\n* Upload baru hanya dilakukan jika user memilih gambar baru.\n\n---\n\n#### 6. Controller: Hapus Produk + Hapus File\n\n```php\npublic function destroy($id)\n{\n    $product = Product::findOrFail($id);\n    if ($product->image && Storage::disk('public')->exists($product->image)) {\n        Storage::disk('public')->delete($product->image);\n    }\n    $product->delete();\n\n    return redirect()->route('products.index');\n}\n```\n\n---\n\n#### 7. Menampilkan Gambar di Halaman Index\n\n```html\n\u003Ctd>\n    @if ($product->image)\n        \u003Cimg src=\"{{ asset('storage\u002F' . $product->image) }}\" width=\"70\">\n    @else\n        \u003Csmall class=\"text-muted\">Tidak ada gambar\u003C\u002Fsmall>\n    @endif\n\u003C\u002Ftd>\n```\n\n---\n\n#### 8. Ringkasan Keunggulan `store()`\n\n✔ Nama file unik otomatis \\\n✔ Menghindari overwrite \\\n✔ Lebih aman \\\n✔ Direkomendasikan oleh Laravel \\\n✔ Struktur penyimpanan lebih rapi\n\n---\n\n### 📁 Struktur Folder Penting\n\n```\n📁 project-laravel\u002F\n├── 📁 app\u002F\n│   └── 📁 Http\u002F\n│       └── 📁 Controllers\u002F\n│           └── 📄 ProductController.php      \u003C-- Logika upload file & simpan nama gambar\n│\n├── 📁 public\u002F\n│   └── 📁 storage\u002F\n│       └── 📁 products\u002F                      \u003C-- Hasil upload gambar (akses publik)\n│\n├── 📁 resources\u002F\n│   └── 📁 views\u002F\n│       └── 📁 products\u002F\n│           ├── 📄 create.blade.php           \u003C-- Form tambah produk + upload gambar\n│           ├── 📄 edit.blade.php             \u003C-- Form edit produk + upload gambar\n│           └── 📄 index.blade.php            \u003C-- Menampilkan daftar produk\n│\n├── 📁 routes\u002F\n│   └── 📄 web.php                             \u003C-- Route CRUD termasuk delete\n│\n├── 📁 storage\u002F\n│   └── 📁 app\u002F\n│       └── 📁 public\u002F\n│           └── 📁 products\u002F                   \u003C-- File asli sebelum di-link ke public\n│\n```","https:\u002F\u002Fcdn.rezweb.my.id\u002Fposts\u002FBc2XQKn0YoISfViM4zj5FlDuX4XWz45edW6ucgFU.jpg",920,10,"2025-11-23T13:28:44+07:00","2026-09-07T11:59:37+07:00",{"name":18,"slug":19},"LARAVEL","laravel",{"id":21,"name":22,"username":23,"avatar":24},1,"Irez Abdullah","irezabdullah","https:\u002F\u002Fcdn.rezweb.my.id\u002Favatars\u002Fd139726e-348f-4dab-95c6-bb87e2ad125e.jpeg",{"name":26,"slug":27},"Belajar Laravel dari Nol (Praktikum Web Framework) – Ringkas & Praktis","belajar-laravel-dari-nol-praktikum-web-framework-ringkas-praktis",[29,33,38,43,48,53,58,63,68,73,74,79,84,89],{"id":30,"slug":31,"title":32,"part_number":21},48,"pengenalan-web-framework-instalasi-laravel","Pengenalan Web Framework & Instalasi Laravel",{"id":34,"slug":35,"title":36,"part_number":37},49,"struktur-folder-routing-dasar","Struktur Folder & Routing Dasar",2,{"id":39,"slug":40,"title":41,"part_number":42},50,"blade-template-layouting-dengan-bootstrap-5-dmwo","Blade Template & Layouting dengan Bootstrap 5",3,{"id":44,"slug":45,"title":46,"part_number":47},51,"database-migration-qbsa","Database & Migration",4,{"id":49,"slug":50,"title":51,"part_number":52},52,"model-seeder","Model & Seeder",5,{"id":54,"slug":55,"title":56,"part_number":57},53,"controller-read-data-menampilkan-produk","Controller & Read Data (Menampilkan Produk)",6,{"id":59,"slug":60,"title":61,"part_number":62},54,"form-tambah-produk-create","Form Tambah Produk (Create)",7,{"id":64,"slug":65,"title":66,"part_number":67},55,"edit-update-produk","Edit & Update Produk",8,{"id":69,"slug":70,"title":71,"part_number":72},56,"hapus-produk-validasi-form","Hapus Produk & Validasi Form",9,{"id":8,"slug":10,"title":9,"part_number":14},{"id":75,"slug":76,"title":77,"part_number":78},62,"menampilkan-grafik-stok-produk","Menampilkan Grafik Stok Produk",11,{"id":80,"slug":81,"title":82,"part_number":83},64,"login-dan-implementasi-middleware-at","Login Dan Implementasi Middleware",12,{"id":85,"slug":86,"title":87,"part_number":88},61,"membuat-dashboard-admin-dengan-statistik-dan-grafik","Membuat Dashboard Admin dengan Statistik dan Grafik",13,{"id":90,"slug":91,"title":92,"part_number":93},65,"teknik-debugging-di-laravel","Teknik Debugging di Laravel",15,"🎯 Tujuan Pembelajaran Di materi ini, diharapkan pembaca mampu: Menambahkan fitur upload gambar pada form tambah dan edit produk di Laravel. Memahami alur uploa...",1788757404411]