Fitur unggah file ada di mana-mana: foto profil, lampiran dokumen, galeri produk. Konsep umumnya: file fisik disimpan ke folder di server, sedangkan nama/path-nya disimpan ke database. Pada tutorial ini kita akan membuat upload file dengan PHP dan MySQL untuk mengunggah gambar dengan aman — lengkap dengan validasi ukuran, tipe, dan penamaan ulang file.

Langkah 1: Tabel & Folder
CREATE TABLE galeri (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_asli VARCHAR(255) NOT NULL,
nama_file VARCHAR(255) NOT NULL,
diunggah TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Buat juga folder uploads/ di dalam folder proyek untuk menampung file fisiknya.
Langkah 2: Form Upload
Form upload wajib memiliki atribut enctype="multipart/form-data", jika tidak, file tidak akan terkirim:
<form method="post" enctype="multipart/form-data">
<input type="file" name="gambar" accept="image/*" required>
<button type="submit">Unggah</button>
</form>
Langkah 3: Memproses Upload dengan Aman
Buat upload.php. Perhatikan lapisan validasi — inilah bagian terpenting demi keamanan:
<?php
require "koneksi.php";
$pesan = "";
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_FILES["gambar"])) {
$file = $_FILES["gambar"];
// 1. Cek error bawaan upload
if ($file["error"] !== UPLOAD_ERR_OK) {
die("Terjadi kesalahan saat upload.");
}
// 2. Batasi ukuran (maks 2 MB)
$maks = 2 * 1024 * 1024;
if ($file["size"] > $maks) {
die("Ukuran file maksimal 2 MB.");
}
// 3. Validasi tipe berdasarkan isi file (bukan cuma nama)
$izin = ["jpg" => "image/jpeg", "png" => "image/png", "gif" => "image/gif"];
$tipe = mime_content_type($file["tmp_name"]);
$ext = array_search($tipe, $izin, true);
if ($ext === false) {
die("Hanya file JPG, PNG, atau GIF yang diperbolehkan.");
}
// 4. Buat nama file baru yang unik & aman
$nama_baru = uniqid("img_", true) . "." . $ext;
$tujuan = "uploads/" . $nama_baru;
// 5. Pindahkan file dari lokasi sementara ke folder tujuan
if (move_uploaded_file($file["tmp_name"], $tujuan)) {
// 6. Simpan info ke database
$asli = basename($file["name"]);
$stmt = $koneksi->prepare("INSERT INTO galeri (nama_asli, nama_file) VALUES (?, ?)");
$stmt->bind_param("ss", $asli, $nama_baru);
$stmt->execute();
$pesan = "File berhasil diunggah!";
} else {
$pesan = "Gagal memindahkan file.";
}
}
?>
Penjelasan lapisan keamanan
- Cek ukuran mencegah file raksasa membebani server.
- Validasi
mime_content_type()memeriksa isi file, bukan sekadar ekstensi nama yang mudah dipalsukan. - Penamaan ulang dengan
uniqid()mencegah file saling menimpa sekaligus menutup celah path traversal dari nama asli. move_uploaded_file()adalah fungsi khusus yang aman untuk memindahkan file hasil upload.
Langkah 4: Menampilkan Galeri
<?php
$hasil = $koneksi->query("SELECT * FROM galeri ORDER BY id DESC");
while ($row = $hasil->fetch_assoc()):
?>
<img src="uploads/<?= htmlspecialchars($row["nama_file"]) ?>"
alt="<?= htmlspecialchars($row["nama_asli"]) ?>" width="150">
<?php endwhile; ?>
Kesalahan Umum
- Lupa
enctype="multipart/form-data"—$_FILESakan kosong. - Hanya mengecek ekstensi nama file — mudah dipalsukan; validasi juga MIME type.
- Memakai nama asli file — berisiko menimpa file lain atau path traversal. Selalu ganti nama.
- Folder
uploads/tidak bisa ditulis — atur izin folder (permission). - Batas
upload_max_filesizedi php.ini terlalu kecil untuk file besar.
Kesimpulan
Anda telah membuat fitur upload file PHP dan MySQL yang aman: menyimpan file ke folder, mencatat path ke database, dengan validasi ukuran, tipe, dan penamaan ulang. Pola ini bisa dikembangkan untuk unggah dokumen, avatar, atau galeri produk. Selalu utamakan validasi karena fitur upload adalah salah satu titik paling rawan diserang.
Referensi: untuk penjelasan fungsi lebih mendalam, kunjungi dokumentasi resmi PHP (php.net).

