Fitur upload file adalah salah satu kebutuhan umum di banyak aplikasi web โ mulai dari upload foto profil, dokumen PDF, hingga file CSV untuk impor data. PHP menyediakan mekanisme upload file bawaan yang mudah digunakan, namun perlu kehati-hatian ekstra dalam hal keamanan. Artikel ini akan memandu kamu membuat sistem upload file yang fungsional dan aman dari awal.
Cara Kerja Upload File di PHP
Ketika pengguna mengirim form dengan file, PHP menerima file tersebut sebagai array $_FILES. File disimpan sementara di folder temporary server sebelum kita pindahkan ke lokasi tujuan menggunakan move_uploaded_file(). Penting: file temporary akan terhapus otomatis jika kamu tidak segera memindahkannya.
Membuat Form Upload
Form HTML untuk upload file wajib memiliki atribut enctype="multipart/form-data" dan method POST:
<!-- upload.html -->
<form action="proses_upload.php" method="POST" enctype="multipart/form-data">
<label for="foto">Pilih Foto:</label>
<input type="file" name="foto" id="foto" accept="image/*" required>
<br>
<button type="submit">Upload</button>
</form>
Atribut accept="image/*" di HTML hanya sebagai petunjuk ke browser โ tidak bisa diandalkan sebagai validasi keamanan. Validasi sesungguhnya tetap harus dilakukan di sisi server.
Memproses Upload di PHP
Buat file proses_upload.php yang menangani penerimaan dan penyimpanan file:
<?php
// proses_upload.php
$upload_dir = __DIR__ . '/uploads/';
// Pastikan folder uploads ada
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Cek apakah file berhasil dikirim
if (!isset($_FILES['foto']) || $_FILES['foto']['error'] !== UPLOAD_ERR_OK) {
$kode_error = $_FILES['foto']['error'] ?? -1;
die("Upload gagal. Kode error: $kode_error");
}
$file = $_FILES['foto'];
// 1. Validasi ukuran maksimal (2 MB)
$maks_ukuran = 2 * 1024 * 1024; // 2 MB dalam byte
if ($file['size'] > $maks_ukuran) {
die("File terlalu besar. Maksimal 2 MB.");
}
// 2. Validasi tipe MIME yang diizinkan
$tipe_diizinkan = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$finfo = new finfo(FILEINFO_MIME_TYPE);
$tipe_mime = $finfo->file($file['tmp_name']);
if (!in_array($tipe_mime, $tipe_diizinkan)) {
die("Tipe file tidak diizinkan. Hanya JPEG, PNG, GIF, dan WebP.");
}
// 3. Buat nama file unik untuk menghindari tabrakan
$ekstensi = pathinfo($file['name'], PATHINFO_EXTENSION);
$nama_file_baru = uniqid('img_', true) . '.' . strtolower($ekstensi);
$tujuan = $upload_dir . $nama_file_baru;
// 4. Pindahkan file dari temporary ke tujuan
if (move_uploaded_file($file['tmp_name'], $tujuan)) {
echo "Upload berhasil! File disimpan sebagai: $nama_file_baru";
} else {
echo "Gagal memindahkan file. Periksa permission folder uploads.";
}
Memahami Array $_FILES
Saat file diupload, PHP mengisi $_FILES['nama_input'] dengan lima kunci:
nameโ nama asli file dari komputer pengguna.typeโ tipe MIME yang dikirim browser (jangan dipercaya sepenuhnya).tmp_nameโ path file sementara di server.errorโ kode error (0 berarti sukses /UPLOAD_ERR_OK).sizeโ ukuran file dalam byte.
Upload Multiple File
Untuk mengizinkan upload banyak file sekaligus, tambahkan atribut multiple di input dan nama field dengan tanda kurung siku:
<input type="file" name="dokumen[]" multiple accept=".pdf,.doc,.docx">
<?php
if (isset($_FILES['dokumen'])) {
$files = $_FILES['dokumen'];
$jumlah = count($files['name']);
for ($i = 0; $i < $jumlah; $i++) {
if ($files['error'][$i] === UPLOAD_ERR_OK) {
$nama_asli = basename($files['name'][$i]);
$tujuan = __DIR__ . '/uploads/' . uniqid() . '_' . $nama_asli;
move_uploaded_file($files['tmp_name'][$i], $tujuan);
echo "File '$nama_asli' berhasil diupload.<br>";
}
}
}
Kode Error Upload yang Umum
UPLOAD_ERR_OK (0)โ sukses.UPLOAD_ERR_INI_SIZE (1)โ file melampauiupload_max_filesizedi php.ini.UPLOAD_ERR_FORM_SIZE (2)โ file melampauiMAX_FILE_SIZEdi form HTML.UPLOAD_ERR_PARTIAL (3)โ file hanya terupload sebagian.UPLOAD_ERR_NO_FILE (4)โ tidak ada file yang dipilih.
Tips Keamanan Upload File
- Selalu validasi tipe MIME menggunakan
finfo, bukan hanya ekstensi file atau$_FILES['type']. - Gunakan nama file baru yang di-generate server (misalnya dengan
uniqid()) โ jangan pakai nama asli dari pengguna langsung. - Simpan file di luar folder
publicjika memungkinkan, atau pastikan folder uploads tidak bisa mengeksekusi PHP. - Tambahkan file
.htaccessdi folder uploads dengan isi:php_flag engine offuntuk mencegah eksekusi PHP.
Kesimpulan
Upload file dengan PHP cukup mudah, namun keamanan adalah hal yang tidak boleh diabaikan. Validasi selalu di sisi server dengan mengecek ukuran file, tipe MIME secara akurat menggunakan finfo, dan gunakan nama file yang aman. Dengan mengikuti panduan ini, kamu sudah memiliki sistem upload yang berfungsi dengan baik dan terlindungi dari potensi eksploitasi.