Mengunggah banyak file sekaligus adalah fitur umum yang sangat berguna dalam banyak aplikasi web. Daripada harus memilih file satu per satu, pengguna bisa mengunggah semuanya sekaligus, menghemat waktu dan meningkatkan pengalaman. Tutorial ini akan memandu Anda membuat sistem upload multiple file menggunakan JavaScript (untuk bagian frontend) dan PHP (untuk bagian backend).
Kita akan membuat formulir sederhana di mana pengguna dapat memilih beberapa file. Dengan sedikit JavaScript, kita akan menangani proses pemilihan dan menampilkan pratinjau file sebelum diunggah. Di sisi PHP, kita akan memproses file-file tersebut, memvalidasinya, dan menyimpannya di server.
Struktur Project
Mari kita mulai dengan membuat struktur folder dasar untuk proyek kita:
multiple-upload/
├── index.html
├── upload.php
└── css/
└── style.css
1. Frontend: HTML dan CSS
Buat file index.html
<!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Multiple File Upload</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <h1>Upload Banyak File Sekaligus!</h1> <form id="uploadForm" enctype="multipart/form-data"> <input type="file" id="fileInput" name="files[]" multiple accept="image/*, .pdf, .doc, .docx"> <button type="submit" id="uploadButton">Unggah File</button> </form> <div id="fileList"> <h2>File Terpilih:</h2> <ul id="selectedFiles"> </ul> </div> <div id="uploadStatus"></div> </div> <script src="js/script.js"></script> </body> </html>
Buat file style.css dan masukkan ke dalam folder css
body { font-family: sans-serif; background-color: #f4f4f4; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; } .container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); text-align: center; width: 90%; max-width: 600px; } h1 { color: #333; margin-bottom: 20px; } form { margin-bottom: 20px; } input[type="file"] { display: block; margin: 0 auto 15px auto; padding: 10px; border: 1px solid #ddd; border-radius: 4px; width: calc(100% - 22px); } button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease; } button:hover { background-color: #0056b3; } #fileList { text-align: left; margin-top: 20px; border-top: 1px solid #eee; padding-top: 20px; } #selectedFiles { list-style: none; padding: 0; margin: 0; } #selectedFiles li { background-color: #e9ecef; padding: 8px 12px; margin-bottom: 5px; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; font-size: 0.9em; } #selectedFiles li span { font-weight: bold; } #uploadStatus { margin-top: 20px; padding: 10px; border-radius: 4px; font-weight: bold; } .success { background-color: #d4edda; color: #155724; } .error { background-color: #f8d7da; color: #721c24; }
2. Frontend: JavaScript
Buat file script.js dan masukkan ke dalam folder js
document.addEventListener('DOMContentLoaded', () => { const fileInput = document.getElementById('fileInput'); const uploadForm = document.getElementById('uploadForm'); const selectedFilesList = document.getElementById('selectedFiles'); const uploadStatus = document.getElementById('uploadStatus'); // Menampilkan daftar file yang dipilih fileInput.addEventListener('change', () => { selectedFilesList.innerHTML = ''; // Bersihkan daftar sebelumnya uploadStatus.innerHTML = ''; // Bersihkan status const files = fileInput.files; if (files.length === 0) { selectedFilesList.innerHTML = '<li>Tidak ada file terpilih.</li>'; return; } for (let i = 0; i < files.length; i++) { const file = files[i]; const listItem = document.createElement('li'); listItem.innerHTML = `<span>${file.name}</span> (${(file.size / 1024).toFixed(2)} KB)`; selectedFilesList.appendChild(listItem); } }); // Mengirim formulir via AJAX uploadForm.addEventListener('submit', async (e) => { e.preventDefault(); // Mencegah pengiriman formulir default const formData = new FormData(); const files = fileInput.files; if (files.length === 0) { uploadStatus.className = 'error'; uploadStatus.textContent = 'Pilih setidaknya satu file untuk diunggah!'; return; } // Tambahkan setiap file ke FormData for (let i = 0; i < files.length; i++) { formData.append('files[]', files[i]); } uploadStatus.className = ''; uploadStatus.textContent = 'Mengunggah...'; try { const response = await fetch('upload.php', { method: 'POST', body: formData, }); const result = await response.json(); // Mengasumsikan respons adalah JSON if (result.status === 'success') { uploadStatus.className = 'success'; uploadStatus.textContent = result.message; // Opsional: Bersihkan daftar file setelah berhasil upload selectedFilesList.innerHTML = ''; fileInput.value = ''; // Reset input file } else { uploadStatus.className = 'error'; uploadStatus.textContent = result.message || 'Terjadi kesalahan saat mengunggah.'; } } catch (error) { console.error('Error:', error); uploadStatus.className = 'error'; uploadStatus.textContent = 'Terjadi kesalahan jaringan atau server.'; } }); });
3. Backend: PHP
Sekarang, kita akan membuat upload.php
yang akan memproses file yang dikirim dari frontend. Pastikan Anda memiliki folder uploads/
di direktori yang sama dengan upload.php
. Folder ini akan menjadi tempat file disimpan.
<?php header('Content-Type: application/json'); // Beri tahu browser bahwa respons adalah JSON $uploadDirectory = 'uploads/'; // Direktori tempat file akan disimpan // Buat direktori jika belum ada if (!is_dir($uploadDirectory)) { mkdir($uploadDirectory, 0777, true); } if (isset($_FILES['files']) && is_array($_FILES['files'])) { $uploadedFiles = $_FILES['files']; $totalFiles = count($uploadedFiles['name']); $errors = []; $uploadedCount = 0; for ($i = 0; $i < $totalFiles; $i++) { $fileName = $uploadedFiles['name'][$i]; $fileTmpName = $uploadedFiles['tmp_name'][$i]; $fileSize = $uploadedFiles['size'][$i]; $fileError = $uploadedFiles['error'][$i]; $fileType = $uploadedFiles['type'][$i]; $fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx']; // Jenis file yang diizinkan if ($fileError === UPLOAD_ERR_OK) { // Validasi jenis file if (in_array($fileExt, $allowed)) { // Validasi ukuran file (misalnya, maks 5MB) if ($fileSize < 5000000) { // 5MB $fileDestination = $uploadDirectory . $fileName; if (move_uploaded_file($fileTmpName, $fileDestination)) { $uploadedCount++; } else { $errors[] = "Gagal memindahkan file '$fileName'."; } } else { $errors[] = "Ukuran file '$fileName' terlalu besar (maks 5MB)."; } } else { $errors[] = "Jenis file '$fileName' tidak diizinkan."; } } else { $errors[] = "Terjadi kesalahan saat mengunggah '$fileName' (Kode error: $fileError)."; } } if ($uploadedCount > 0 && empty($errors)) { echo json_encode([ 'status' => 'success', 'message' => "$uploadedCount file berhasil diunggah!", ]); } elseif ($uploadedCount > 0 && !empty($errors)) { echo json_encode([ 'status' => 'warning', 'message' => "$uploadedCount file berhasil diunggah, tetapi ada kesalahan: " . implode(', ', $errors), ]); } else { echo json_encode([ 'status' => 'error', 'message' => "Gagal mengunggah semua file. " . implode(', ', $errors), ]); } } else { echo json_encode([ 'status' => 'error', 'message' => 'Tidak ada file yang diterima.', ]); } ?>
Sekarang silahkan uji coba source code tersebut.
0 Komentar