Dalam lanjutan tutorial PHP web dinamis kali ini, kita akan mulai mempelajari sesuatu yang penting lagi seru. Sesuatu yang pasti ada dalam kebanyakan sistem web yang kita buat. Apa itu? Upload file.
Dalam seri tutorial PHP menengah beberapa waktu lalu, kita telah mempelajari tentang manipulasi file dengan PHP. Dan materi yang akan kita pelajari sekarang ini, masih termasuk salah satu bagian dari manipulasi file.
Hanya saja, dalam pertemuan kali ini kita akan mengambil pembahasan sederhana tentang upload file. Dan insyaallah pada pertemuan-pertemuan berikutnya kita akan membahas lebih dalam tentang variasi upload file dan juga cara pengamanannya.
Persiapan File
Langsung saja.
Siapkan kopi kalian, jangan lupa diseduh.
Lalu buka teks editor favorit. Dan buat projek baru dengan struktur file sebagai berikut:
upload-file/
├── form.html
└── proses.php
Biasanya kita membuat form dengan ekstensi .php
. Tapi agar tidak dikira bahwa halaman form wajib berekstensi .php
, di sini kita akan gunakan ektensi .html
terlebih dahulu.
Membuat Form
Untuk form yang akan kita buat, sederhana saja. Hanya terdiri dari satu buah input file, dan satu buah tombol upload.
Silakan tuliskan kode program berikut:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Upload File</title>
</head>
<body>
<h1>Belajar Upload File</h1>
<form action="proses.php" method="POST" enctype="multipart/form-data">
<div>
<label>Foto</label> <br>
<input type="file" name="foto">
</div>
<div style="margin-top: 1rem">
<button>Upload</button>
</div>
</form>
</body>
</html>
Penjelasan:
- Form upload (html) harus menggunakan method POST
- Data yang dikirim harus dienkripsi dengan metode
multipart/form-data
. Yang artinya bahwa data yang berisi form tersebut akan dipecah menjadi beberapa bagian (multipart), untuk kemudian dikirimkan ke server [1]. - Atribut
action
pada tag<form>
di atas mengarah ke fileproses.php
. Penampakanform.html
:
Penampakan file form.html
:
Memahami Struktur Data
Sebelum kita mulai proses upload. Kita harus memahami dulu bagaimana “bentuk” data file dikirimkan dari form HTML ke dalam server (dalam hal ini yang menangani sisi server adalah PHP).
Untuk itu, tambahkan kode program berikut pada file proses.php
:
<?php
$files = $_FILES;
echo "<pre>";
print_r($files);
echo "</pre>";
Jalankan form.html
, pilih salah satu file gambar. Lalu klik tombol Upload.
Jika tidak terjadi error apa pun, anda akan mendapatkan output kira-kira sebagai berikut:
Array
(
[foto] => Array
(
[name] => foto-ku-3x4.png
[type] => image/png
[tmp_name] => /tmp/phpuwTh9e
[error] => 0
[size] => 70476
)
)
Penjelasan
Jika kita melihat isi dari variabel $_FILES
, kita akan dapatkan kesimpulan:
- Bahwa variabel
$_FILES
merupakan sebuah array asosiatif - Setiap file yang dikirim dari HTML form akan menjadi item dari array
$_FILES
- Setiap item tersebut menyimpan beberapa informasi seperti
name
untuk nama file,type
untuk tipe dari file yang diupload,tmp_name
lokasi sementara dari file yang diupload,error
jika bernilai0
berarti tidak ada error, dan juga atributsize
yang berarti ukuran gambar dalam satuan bytes.
Coba Tambahkan Field Baru
Untuk lebih memahami struktur data dari variabel $_FILES
, kita akan menambahkan satu buah inputan file sekali lagi.
Kita input yang baru ini akan kita beri nama sebagai ktp
.
Langsung saja, tambahkan kode programnya:
<div style="margin-top: 1rem">
<label>Berkas KTP</label> <br>
<input type="file" name="ktp">
</div>
Setelah itu jalankan lagi file form.html
, coba upload dua buah file untuk masing-masing field input.
Klik tombol Upload, anda akan mendapatkan output dari variabel $_FILES
kira-kira sebagai berikut:
Array
(
[foto] => Array
(
[name] => foto-3x4.webp
[type] => image/webp
[tmp_name] => /tmp/phpdUVqae
[error] => 0
[size] => 23150
)
[ktp] => Array
(
[name] => scan-ktp.jpeg
[type] => image/jpeg
[tmp_name] => /tmp/phpYF9t7e
[error] => 0
[size] => 34794
)
)
Sampai sini, kita sudah memiliki gambaran yang cukup jelas tentang struktur data sederhana dari variabel $_FILES
.
Kita akan melanjutkan ke tahap berikutnya yaitu upload file.
Sebenarnya File Sudah Otomatis Terupload
Iya, sebenarnya tanpa melakukan proses apa pun: file sudah terupload. Karena ketika form.html
di-submit, browser akan mengirimkan file tersebut untuk diterima oleh server.
Nah, proses pengiriman seperti ini: itu dinamakan upload.
Akan tetapi, file yang terkirim tersebut tidak langsung masuk ke dalam direktori file projek kita.
Lalu di mana ia disimpan?
Ia disimpan di dalam direktori sementara. Dan lokasi sementara dari file tersebut disimpan dalam nilai tmp_name
pada tiap file.
Lalu bagaimana agar file tersebut bisa berada di dalam direktori projek?
Gampang, tinggal kita pindah aja file-nya dari direktori sementara, ke direktori projek kita.
Memindahkan File Yang Terupload
Untuk memindahkannya, kita akan menggunakan fungsi bawaan PHP bernama move_uploaded_file()
. Fungsi tersebut menerima 2 buah parameter:
- Parameter pertama adalah lokasi sementara dari file yang dikirim.
- Dan yang kedua adalah lokasi dimana file tersebut akan dipindahkan.
Hapus Semua Kode
Sebelum kita mulai, kita hapus dulu semua baris program dari file proses.php
.
Buat Direktori Upload
Lalu (pada file yang sama), tambahkan kode program berikut:
<?php
$folderUpload = "./assets/uploads";
# periksa apakah folder sudah ada
if (!is_dir($folderUpload)) {
# jika tidak maka folder harus dibuat terlebih dahulu
mkdir($folderUpload, 0777, $rekursif = true);
}
Penjelasan:
- Kode program di atas bertujuan untuk membuat direktori baru dengan nama
/assets/uploads/
- Lokasi tersebut nantinya akan kita gunakan sebagai tujuan pemberhentian akhir dari file yang kita upload
Simpan Masing-Masing File Ke Dalam Variabel
Pada baris selanjutnya, tambahkan kode program berikut:
<?php
...
# simpan masing-masing file ke dalam array
# dan casting menjadi objek 😎
$fileFoto = (object) @$_FILES['foto'];
$fileKtp = (object) @$_FILES['ktp'];
Penjelasan:
- Kita akan menyimpan masing-masing file dari file foto mau pun ktp dalam sebuah variabel terpisah.
- Kita konversi tipe data array asosiatif masing-masing file menjadi tipe data object alias instant dari stdClass.
- Apakah wajib dikonversi menjadi objek? Tidak. Tidak wajib. Kita tetap bisa menggunakan tipe data aslinya yaitu array. Saya mengkonversinya ke dalam objek hanya karena saya lebih suka menggunakan tanda panah
->
dari pada tanda kurung siku[]
untuk mengakses data 😎
Mulai Memindahkan File
Jika semuanya sudah beres, kita bisa langsung memindahkan dua file di atas seperti berikut:
<?php
...
# mulai upload file
$uploadFotoSukses = move_uploaded_file(
$fileFoto->tmp_name, "{$folderUpload}/{$fileFoto->name}"
);
$uploadKtpSukses = move_uploaded_file(
$fileKtp->tmp_name, "{$folderUpload}/{$fileKtp->name}"
);
Jika kita periksa file manager dan tidak terjadi error, dua file tersebut harusnya sudah berhasil terupload.
Menampilkan Link File Yang Terupload
Link dari file yang terupload adalah gabungan dari nama folder upload dan nama file tujuan. Kira-kira seperti ini:
<?php
...
if ($uploadFotoSukses) {
$link = "{$folderUpload}/{$fileFoto->name}";
echo "Sukses Upload Foto: <a href='{$link}'>{$fileFoto->name}</a>";
echo "<br>";
}
if ($uploadKtpSukses) {
$link = "{$folderUpload}/{$fileKtp->name}";
echo "Sukses Upload KTP: <a href='{$link}'>{$fileKtp->name}</a>";
echo "<br>";
}
Validasi Ukuran Maksimal File
Oiya, sebelum proses pemindahan file. Kita juga bisa melakukan beberapa validasi. Seperti misalnya: validasi ukuran maksimum file.
Kita bisa memanfaatkan attribut size
pada tiap file untuk melakukannya, contohnya adalah seperti berikut:
<?php
if ($fileFoto->size > 1000 * 2000) {
die("File tidak boleh lebih dari 2MB");
}
Validasi Tipe File
Atau kita juga bisa memanfaatkan atribut type
pada file yang terupload untuk memvalidasi tipe dari file yang bersangkutan:
<?php
if ($fileKtp->type !== 'image/jpeg') {
die("File ktp harus jpeg!");
}
Akan tetapi, atribut type
pada file upload masih rentan untuk dimanipulasi. Bisa jadi file yang sebenarnya bertipe data gambar, ternyata itu adalah sebuah malware yang berbahaya.
Oleh karena itu, cara teraman untuk memeriksa tipe dari suatu file adalah: dengan memeriksa mime type-nya. Insyaallah nanti akan kita bahas hal ini pada kesempatan yang lainnya.
Kesimpulan
Upload file di-PHP tidak lah susah. Sangat sederhana. Kita hanya membuat form, mengatur method menjadi POST, mengatur enctype menjadi multipart/form-data
. Lalu browser lah yang akan mengupload file tersebut ke dalam server.
Hanya saja, file yang terupload tersebut, tidak otomatis berada pada direktori yang kita inginkan. Melainkan masih disimpan pada direktori sementara atau temporary directory, untuk kemudian kita simpan pada lokasi yang kita inginkan menggunakan fungsi move_uploaded_file()
.
Kode Program Lengkap
Untuk kode program lengkap, anda bisa dapatkan di repository PHP Web Dinamis pada akun github jagongoding.
Pembahasan Selanjutnya
Karena pembahasan sudah terlalu panjang, kita sudahi dulu pertemuan ini sampai di sini.
Pada pertemuan selanjutnya, insyaallah kita akan membahas tentang bagaimana cara mengupload multiple files dengan satu input sekaligus.
Jangan lupa share tutorial ini ke teman-teman kalian, ya! Terima kasih banyak.
Referensi
[1] https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean - diakses 18 April 2020