Sebelum aplikasi membaca, menyalin, atau menghapus sebuah berkas, aplikasi terlebih dahulu perlu memastikan kondisi berkas tersebut: apakah berkasnya ada, berapa ukurannya, kapan terakhir diubah, dan termasuk entri jenis apa. PHP menyediakan sekumpulan fungsi informasi berkas yang menjawab pertanyaan-pertanyaan tersebut tanpa perlu membuka isinya. Pada Chapter ini kita akan mempelajari fungsi-fungsi tersebut satu per satu, mulai dari pemeriksaan sederhana seperti file_exists() hingga deteksi tipe MIME berdasarkan isi berkas. Semua contoh memakai direktori temporer sistem agar dapat dijalankan langsung tanpa perlu menyiapkan berkas proyek.

Memeriksa Keberadaan Berkas #

Fungsi file_exists() menerima sebuah path dan mengembalikan nilai boolean: true jika path tersebut merujuk ke berkas maupun direktori yang ada, dan false jika sebaliknya. Pemeriksaan seperti ini biasa dilakukan sebelum membaca berkas dengan file_get_contents() supaya skrip tidak memicu warning ketika berkas ternyata tidak ada. Perlu dicatat bahwa file_exists() juga mengembalikan true untuk direktori, sehingga kita akan membedakan keduanya memakai fungsi khusus di bagian selanjutnya.

Contoh berikut memakai sys_get_temp_dir() — fungsi yang mengembalikan path direktori penampung berkas sementara milik sistem operasi (di Linux umumnya /tmp). Dengan pendekatan ini, contoh dapat dijalankan dari folder mana pun tanpa meninggalkan jejak berkas di proyek Anda karena berkas contoh langsung dihapus kembali.

php
<?php
$berkas = sys_get_temp_dir() . "/catatan-kursus.txt";
file_put_contents($berkas, "Belajar PHP itu menyenangkan.\n");

var_dump(file_exists($berkas));
var_dump(file_exists(sys_get_temp_dir() . "/berkas-tidak-ada.txt"));
unlink($berkas);

Output yang Dihasilkan:

text
bool(true)
bool(false)

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 2: variabel $berkas diisi path berkas baru di dalam direktori temporer, misalnya /tmp/catatan-kursus.txt.
  2. Baris 3: file_put_contents() membuat berkas tersebut sekaligus menulis isinya.
  3. Baris 5–6: file_exists() memeriksa path berkas yang barusan dibuat (hasilnya true) dan sebuah path yang memang tidak pernah dibuat (hasilnya false).
  4. Baris 7: unlink() menghapus berkas contoh agar tidak menumpuk di direktori temporer.

Ukuran dan Waktu Modifikasi Berkas #

filesize() mengembalikan ukuran berkas dalam satuan byte sebagai integer, sedangkan filemtime() mengembalikan waktu modifikasi terakhir sebagai Unix timestamp — jumlah detik sejak 1 Januari 1970. Untuk menampilkan timestamp tersebut dalam format yang mudah dibaca manusia, nilai tersebut diteruskan ke fungsi date() bersama string format.

Ada satu hal penting untuk contoh yang reproducible: filemtime() pada berkas yang baru dibuat selalu mengikuti waktu eksekusi skrip, sehingga mencetaknya mentah-mentah menghasilkan output yang berbeda setiap dijalankan. Karena itu contoh di bawah mengunci waktu modifikasi berkas dengan touch() yang menerima timestamp sebagai argumen kedua, lalu memasang zona waktu UTC melalui date_default_timezone_set() agar hasil format tanggal tidak bergantung pada pengaturan zona waktu mesin.

php
<?php
date_default_timezone_set("UTC");

$berkas = sys_get_temp_dir() . "/laporan-penjualan.txt";
file_put_contents($berkas, "Laporan penjualan kuartal pertama\n");
touch($berkas, 1767225600); // kunci waktu modifikasi: 1 Januari 2026

echo "Ukuran berkas: " . filesize($berkas) . " byte\n";
echo "Waktu modifikasi: " . date("d-m-Y H:i:s", filemtime($berkas)) . "\n";
unlink($berkas);

Output yang Dihasilkan:

text
Ukuran berkas: 34 byte
Waktu modifikasi: 01-01-2026 00:00:00

Isi "Laporan penjualan kuartal pertama\n" tersimpan sebagai 34 byte — PHP menghitung seluruh karakter termasuk spasi dan baris baru. Timestamp 1767225600 kemudian terformat menjadi 01-01-2026 00:00:00 sesuai zona waktu UTC yang kita pasang di awal. Selain filemtime(), PHP juga menyediakan fileatime() (waktu akses terakhir) dan filectime() (waktu perubahan metadata) dengan pola pemakaian yang sama.

Membedakan Berkas dan Direktori #

Fungsi filetype() mengembalikan string jenis entri filesystem: "file" untuk berkas biasa, "dir" untuk direktori, dan "link" untuk symbolic link. Untuk pengujian yang lebih langsung di dalam kondisi if, pasangan is_file() dan is_dir() mengembalikan boolean. Keempat fungsi ini mengembalikan false tanpa memicu error ketika path yang diperiksa tidak ada — berbeda dengan fungsi baca/tulis yang memicu warning pada situasi serupa.

php
<?php
$berkas = sys_get_temp_dir() . "/data-pelanggan.txt";
file_put_contents($berkas, "Budi, Bandung\nSiti, Surabaya\n");

echo "filetype berkas: " . filetype($berkas) . "\n";
echo "filetype folder temporer: " . filetype(sys_get_temp_dir()) . "\n";
var_dump(is_file($berkas));
var_dump(is_dir($berkas));
var_dump(is_dir(sys_get_temp_dir()));
unlink($berkas);

Output yang Dihasilkan:

text
filetype berkas: file
filetype folder temporer: dir
bool(true)
bool(false)
bool(true)

Hasilnya konsisten dengan dugaan kita: berkas teks dilaporkan sebagai "file" dan direktori temporer sebagai "dir". Pemeriksaan is_dir($berkas) mengembalikan false karena $berkas memang berkas, bukan folder. Kombinasi keempat fungsi ini cukup untuk memetakan jenis entri pada path mana pun sebelum diproses lebih lanjut.

Mengambil Banyak Informasi Sekaligus dengan stat() #

Memanggil fungsi informasi satu per satu menjadi repetitif ketika kita membutuhkan banyak metadata sekaligus. Fungsi stat() menyelesaikan masalah tersebut dengan mengembalikan array berisi seluruh informasi filesystem tentang sebuah berkas dalam satu panggilan. Array tersebut memiliki kunci ganda: kunci string yang mudah dibaca dan indeks numerik yang merupakan warisan antarmuka sistem operasi C — keduanya selalu menunjuk ke nilai yang sama.

Kunci stringIndeks numerikArti
size7Ukuran berkas dalam byte
atime8Waktu akses terakhir (Unix timestamp)
mtime9Waktu modifikasi terakhir (Unix timestamp)
uid4ID numerik pemilik berkas
php
<?php
$berkas = sys_get_temp_dir() . "/stat-demo.txt";
file_put_contents($berkas, "PHP 8.4\n");
touch($berkas, 1767225600);

$info = stat($berkas);
echo "ukuran: " . $info["size"] . " byte\n";
echo "mtime: " . $info["mtime"] . "\n";
var_dump($info["size"] === $info[7]);
var_dump($info["mtime"] === $info[9]);
unlink($berkas);

Output yang Dihasilkan:

text
ukuran: 8 byte
mtime: 1767225600
bool(true)
bool(true)

Perbandingan identik === pada dua baris terakhir membuktikan bahwa $info["size"] dan $info[7] benar-benar bernilai sama — keduanya hanyalah alias bagi data yang sama. Gunakan kunci string dalam kode Anda karena jauh lebih mudah dibaca; indeks numerik cukup dikenali saat membaca kode warisan lama. Untuk berkas berupa symbolic link, gunakan lstat() apabila Anda menginginkan informasi tentang tautannya, bukan tentang berkas tujuan tautan.

Mengurai Nama Berkas dengan pathinfo() #

Sebuah path berkas tersusun dari komponen yang bisa diurai: nama direktori, nama berkas, dan ekstensi. Fungsi pathinfo() mengembalikan array asosiatif berisi dirname, basename, extension, dan filename, sedangkan basename() dan dirname() masing-masing mengambil satu komponen tersebut secara mandiri. Ketiganya bekerja murni pada string — berkas yang dirujuk tidak perlu benar-benar ada di disk.

php
<?php
$path = "uploads/laporan-2026.pdf";

echo "basename: " . basename($path) . "\n";
echo "dirname: " . dirname($path) . "\n";

$info = pathinfo($path);
echo "extension: " . $info["extension"] . "\n";
echo "filename: " . $info["filename"] . "\n";
var_dump(pathinfo($path, PATHINFO_EXTENSION));
var_dump(pathinfo("arsip/foto-liburan.JPG", PATHINFO_EXTENSION));
var_dump(pathinfo("README", PATHINFO_EXTENSION) === "");

Output yang Dihasilkan:

text
basename: laporan-2026.pdf
dirname: uploads
extension: pdf
filename: laporan-2026
string(3) "pdf"
string(3) "JPG"
bool(true)

Ada dua perilaku penting dari hasil di atas. Pertama, ekstensi JPG dikembalikan apa adanya — huruf besar-kecil dipertahankan, sehingga perbandingan ekstensi sebaiknya melewati strtolower() lebih dahulu. Kedua, berkas tanpa ekstensi seperti README menghasilkan string kosong. Dengan mengirimkan konstanta seperti PATHINFO_EXTENSION sebagai argumen kedua, pathinfo() hanya mengembalikan komponen yang dibutuhkan dalam bentuk string alih-alih array penuh.

Mendeteksi Tipe MIME dengan finfo #

Ekstensi berkas mudah dipalsukan — berkas skrip.php bisa saja di-rename menjadi skrip.jpg. Ketika keaslian jenis berkas penting, misalnya saat memvalidasi upload, ekstensi fileinfo membaca magic bytes — pola byte khas di awal isi berkas — untuk mendeteksi tipe MIME sebenarnya. Kita membuat objek finfo dengan flag FILEINFO_MIME_TYPE agar hasilnya ringkas seperti text/plain, lalu memanggil metode file() dengan path berkas yang ingin diperiksa.

php
<?php
$berkas = sys_get_temp_dir() . "/mime-demo.txt";
$finfo = new finfo(FILEINFO_MIME_TYPE);

file_put_contents($berkas, "Halo, ini isi dokumen teks biasa.\n");
echo "Tipe MIME: " . $finfo->file($berkas) . "\n";

file_put_contents($berkas, "<?php echo 'Halo dari PHP';\n");
echo "Tipe MIME: " . $finfo->file($berkas) . "\n";
unlink($berkas);

Output yang Dihasilkan:

text
Tipe MIME: text/plain
Tipe MIME: text/x-php

Meskipun namanya masih mime-demo.txt, isi kedua versi berkas terdeteksi berbeda: teks biasa terbaca sebagai text/plain, sedangkan kode PHP terbaca sebagai text/x-php — deteksi sepenuhnya berbasis isi, bukan nama atau ekstensi berkas. Kemampuan ini akan menjadi komponen penting pada rantai validasi di Chapter Uploads dan File Storage. Untuk memeriksa string yang belum tersimpan ke berkas, gunakan metode finfo::buffer() dengan pola pemakaian yang sama.

Ringkasan #

PHP menyediakan lapisan fungsi informasi berkas yang lengkap: file_exists() untuk keberadaan, filesize() dan filemtime() untuk ukuran serta waktu, is_file()/is_dir() untuk jenis entri, stat() untuk semuanya sekaligus, pathinfo() untuk mengurai nama, dan ekstensi finfo untuk mendeteksi tipe MIME dari isi berkas. Seluruh fungsi tersebut bekerja di atas sebuah path. Justru konsep path itulah yang belum kita bedah secara khusus — Chapter Filesystem Paths berikutnya mengupas cara membangun path yang benar dengan __DIR__, dirname(), dan realpath().

Referensi #