IO #
Standard library I/O PHP mencakup ratusan fungsi untuk berinteraksi dengan filesystem, jaringan, dan stream. Tidak semua perlu dihapal — yang penting adalah mengetahui fungsi apa yang ada untuk setiap kebutuhan agar tidak menulis ulang sesuatu yang sudah tersedia bawaan. Artikel ini menjadi referensi cepat untuk fungsi I/O yang paling sering dibutuhkan: operasi file dan direktori, informasi filesystem, fungsi jaringan dasar, dan beberapa pola idiomatik yang membuat kode I/O PHP lebih bersih dan aman.
Fungsi File — Baca #
<?php
// file_get_contents — baca seluruh file ke string
$isi = file_get_contents('/path/to/file.txt');
$json = file_get_contents('https://api.example.com/data'); // juga bisa URL
$binerB64 = base64_encode(file_get_contents('gambar.jpg'));
// file_get_contents dengan context (header, timeout, dll.)
$ctx = stream_context_create(['http' => ['timeout' => 10]]);
$isi = file_get_contents('https://api.example.com', false, $ctx);
// file — baca sebagai array of lines
$baris = file('data.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($baris as $i => $baris) {
echo "$i: $baris\n";
}
// readfile — baca dan langsung output (untuk download)
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="laporan.pdf"');
readfile('/path/to/laporan.pdf');
exit;
// fopen/fread/fclose — kontrol penuh, baik untuk file besar
$handle = fopen('/path/to/besar.csv', 'r');
if ($handle === false) {
throw new \RuntimeException("Gagal membuka file");
}
try {
while (!feof($handle)) {
$baris = fgets($handle, 4096); // satu baris, max 4KB
if ($baris !== false) {
// proses baris...
}
}
} finally {
fclose($handle);
}
// Baca CSV khusus
$handle = fopen('data.csv', 'r');
$header = fgetcsv($handle); // baca header
while (($row = fgetcsv($handle)) !== false) {
$data = array_combine($header, $row);
// proses $data...
}
fclose($handle);
// Baca byte di posisi tertentu
$handle = fopen('data.bin', 'rb'); // 'b' = binary mode
fseek($handle, 1024); // loncat ke byte 1024
$chunk = fread($handle, 256); // baca 256 byte
$posisi = ftell($handle); // posisi sekarang: 1280
rewind($handle); // kembali ke awal
fclose($handle);
Fungsi File — Tulis #
<?php
// file_put_contents — tulis string ke file
$bytes = file_put_contents('output.txt', "Isi file\n");
echo "Ditulis $bytes byte\n";
// FILE_APPEND — tambahkan di akhir file
file_put_contents('log.txt', date('Y-m-d H:i:s') . " — event\n", FILE_APPEND);
// LOCK_EX — exclusive lock (aman untuk multi-proses)
file_put_contents('data.json', json_encode($data), LOCK_EX);
// Keduanya sekaligus
file_put_contents('app.log', $entry, FILE_APPEND | LOCK_EX);
// fopen/fwrite/fclose — kontrol penuh
$handle = fopen('output.csv', 'w'); // 'w' = tulis baru, 'a' = append
try {
fputcsv($handle, ['ID', 'Nama', 'Email']); // header
foreach ($data as $row) {
fputcsv($handle, [$row['id'], $row['nama'], $row['email']]);
}
} finally {
fclose($handle);
}
// Mode file lengkap:
// 'r' — baca saja, pointer di awal
// 'r+' — baca & tulis, pointer di awal
// 'w' — tulis baru/truncate, pointer di awal
// 'w+' — baca & tulis baru/truncate
// 'a' — append, pointer di akhir
// 'a+' — baca & append
// 'x' — tulis baru, GAGAL jika sudah ada
// 'x+' — baca & tulis baru, GAGAL jika sudah ada
// 'c' — tulis, tidak truncate, pointer di awal
// 'c+' — baca & tulis, tidak truncate
// Tulis dengan locking manual
$handle = fopen('counter.txt', 'c+');
flock($handle, LOCK_EX);
$nilai = (int) fread($handle, 20);
$nilai++;
rewind($handle);
ftruncate($handle, 0);
fwrite($handle, (string) $nilai);
flock($handle, LOCK_UN);
fclose($handle);
Informasi File dan Direktori #
<?php
$path = '/var/www/app/public/index.php';
// Cek keberadaan dan tipe
var_dump(file_exists($path)); // bool(true/false)
var_dump(is_file($path)); // true jika file (bukan direktori)
var_dump(is_dir(dirname($path))); // true jika direktori
var_dump(is_link($path)); // true jika symlink
// Izin akses
var_dump(is_readable($path)); // bisa dibaca oleh proses saat ini
var_dump(is_writable($path)); // bisa ditulis
var_dump(is_executable($path)); // bisa dieksekusi
// Informasi file
echo filesize($path); // ukuran dalam byte
echo date('Y-m-d H:i:s', filemtime($path)); // waktu modifikasi terakhir
echo date('Y-m-d H:i:s', filectime($path)); // waktu perubahan inode
echo date('Y-m-d H:i:s', fileatime($path)); // waktu akses terakhir
echo fileowner($path); // UID pemilik
echo filegroup($path); // GID grup
echo decoct(fileperms($path) & 0777); // permission octal: "755"
// stat — info lengkap
$stat = stat($path);
echo $stat['size']; // ukuran file
echo $stat['mtime']; // waktu modifikasi (Unix timestamp)
// Informasi path
echo basename($path); // "index.php"
echo basename($path, '.php'); // "index"
echo dirname($path); // "/var/www/app/public"
echo dirname($path, 2); // "/var/www/app" (2 level ke atas)
echo realpath('../relative/path'); // path absolut yang sudah di-resolve
echo pathinfo($path, PATHINFO_EXTENSION); // "php"
echo pathinfo($path, PATHINFO_FILENAME); // "index"
echo pathinfo($path, PATHINFO_DIRNAME); // "/var/www/app/public"
$info = pathinfo($path); // semua sekaligus
// ['dirname'=>'...', 'basename'=>'index.php', 'extension'=>'php', 'filename'=>'index']
// Ukuran direktori (rekursif)
function ukuranDir(string $dir): int
{
$ukuran = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $file) {
if ($file->isFile()) {
$ukuran += $file->getSize();
}
}
return $ukuran;
}
echo round(ukuranDir('/var/www/app') / 1024 / 1024, 2) . " MB\n";
Operasi File — Salin, Pindah, Hapus #
<?php
// copy — salin file
copy('/source/file.txt', '/dest/file.txt');
// rename — pindah atau rename (bisa antar direktori di filesystem yang sama)
rename('/old/path/file.txt', '/new/path/file.txt');
// unlink — hapus file
unlink('/path/to/file.txt');
// Hapus dengan konfirmasi
if (file_exists('/path/to/file.txt')) {
if (!unlink('/path/to/file.txt')) {
throw new \RuntimeException("Gagal menghapus file");
}
}
// touch — buat file kosong atau update timestamp
touch('/path/to/file.txt'); // buat jika belum ada, update mtime jika ada
touch('/path/to/file.txt', time() - 3600); // set mtime ke 1 jam lalu
// chmod / chown — ubah permission dan pemilik
chmod('/path/to/file.php', 0644); // rw-r--r--
chmod('/path/to/dir', 0755); // rwxr-xr-x
chown('/path/to/file', 'www-data'); // butuh privilege
chgrp('/path/to/file', 'www-data');
// Operasi simbolik
symlink('/real/path/file.txt', '/link/path/link.txt'); // buat symlink
readlink('/link/path/link.txt'); // "/real/path/file.txt"
Operasi Direktori #
<?php
// mkdir — buat direktori
mkdir('/new/dir'); // satu level
mkdir('/new/nested/dir', 0755, true); // rekursif, dengan permission
// rmdir — hapus direktori (harus kosong)
rmdir('/empty/dir');
// getcwd — direktori kerja saat ini
echo getcwd(); // "/var/www/app"
// chdir — pindah direktori kerja
chdir('/tmp');
// scandir — daftar isi direktori
$entries = scandir('/var/www/app');
// ['.', '..', 'composer.json', 'public', 'src', 'vendor']
$bersih = array_filter(
scandir('/var/www/app'),
fn($e) => !in_array($e, ['.', '..'])
);
// glob — pattern matching untuk file
$phpFiles = glob('/var/www/app/src/**/*.php'); // semua file PHP
$csvFiles = glob('/data/*.csv');
$multi = glob('/tmp/{*.log,*.txt}', GLOB_BRACE);
// RecursiveDirectoryIterator — traversal rekursif
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/var/www/app', RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
if ($file->getExtension() === 'php') {
echo $file->getPathname() . "\n";
}
}
// DirectoryIterator — satu level saja
$dir = new DirectoryIterator('/var/www/app');
foreach ($dir as $item) {
if ($item->isDot()) continue;
echo ($item->isDir() ? '[DIR] ' : '[FILE] ') . $item->getFilename() . "\n";
}
// Informasi disk
echo disk_free_space('/'); // byte tersedia
echo disk_total_space('/'); // total byte
$persen = (1 - disk_free_space('/') / disk_total_space('/')) * 100;
echo round($persen, 1) . "% terpakai\n";
File Sementara #
<?php
// tmpfile — file sementara yang otomatis dihapus saat ditutup
$tmp = tmpfile();
fwrite($tmp, "data sementara\n");
rewind($tmp);
$isi = stream_get_contents($tmp);
fclose($tmp); // file otomatis dihapus
// tempnam — nama file sementara yang unik
$namaFile = tempnam(sys_get_temp_dir(), 'app_'); // /tmp/app_abc123
file_put_contents($namaFile, $data);
// proses...
unlink($namaFile); // harus hapus manual
// sys_get_temp_dir — direktori temp OS
echo sys_get_temp_dir(); // /tmp (Linux) atau C:\Windows\Temp (Windows)
// php://memory — buffer di memori
$mem = fopen('php://memory', 'r+');
fwrite($mem, "data sementara");
rewind($mem);
$isi = stream_get_contents($mem);
fclose($mem);
// php://temp — memori sampai 2MB, lalu file disk
$temp = fopen('php://temp/maxmemory:2097152', 'r+');
fwrite($temp, $dataBesar);
Fungsi Jaringan #
<?php
// gethostbyname — resolve hostname ke IP
$ip = gethostbyname('example.com'); // "93.184.216.34"
// gethostbyaddr — reverse DNS (IP ke hostname)
$host = gethostbyaddr('8.8.8.8'); // "dns.google"
// dns_get_record — ambil record DNS
$records = dns_get_record('example.com', DNS_A | DNS_MX);
foreach ($records as $record) {
echo $record['type'] . ": " . ($record['ip'] ?? $record['target'] ?? '') . "\n";
}
// checkdnsrr — cek apakah record DNS ada
var_dump(checkdnsrr('example.com', 'MX')); // bool(true)
var_dump(checkdnsrr('notexist.invalid', 'A')); // bool(false)
// Validasi email dengan DNS
function emailValid(string $email): bool
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return false;
}
$domain = substr($email, strrpos($email, '@') + 1);
return checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A');
}
// ip2long dan long2ip — konversi IP
$long = ip2long('192.168.1.1'); // 3232235777
$ip = long2ip(3232235777); // "192.168.1.1"
// Berguna untuk menyimpan IP di database sebagai integer (lebih efisien)
$pdo->prepare("INSERT INTO logs (ip_addr) VALUES (?)")->execute([ip2long($_SERVER['REMOTE_ADDR'])]);
// $_SERVER keys yang berguna untuk jaringan
echo $_SERVER['REMOTE_ADDR']; // IP client
echo $_SERVER['HTTP_USER_AGENT']; // user agent browser
echo $_SERVER['REQUEST_METHOD']; // GET/POST/PUT/DELETE/dll.
echo $_SERVER['REQUEST_URI']; // /path?query=string
echo $_SERVER['HTTP_HOST']; // example.com
echo $_SERVER['SERVER_NAME']; // nama server
echo $_SERVER['HTTPS']; // 'on' jika HTTPS
Fungsi Input/Output CLI #
<?php
// Output ke stdout dan stderr
fwrite(STDOUT, "Pesan normal\n");
fwrite(STDERR, "Pesan error\n");
// Atau langsung echo/print ke stdout
echo "Halo dari CLI\n";
print("Ini juga stdout\n");
// Membaca dari stdin
$input = fgets(STDIN); // baca satu baris
$input = trim(fgets(STDIN)); // dengan trim newline
// Baca password tanpa echo (Linux/macOS)
system('stty -echo'); // matikan echo
echo "Password: ";
$password = trim(fgets(STDIN));
system('stty echo'); // nyalakan kembali
echo "\n";
// Argumen command line
$script = $argv[0]; // nama script
$args = array_slice($argv, 1); // argumen setelah nama script
$count = $argc; // jumlah argumen
// Contoh: php script.php --env=production --debug
foreach ($argv as $arg) {
if (str_starts_with($arg, '--')) {
[$key, $val] = array_pad(explode('=', ltrim($arg, '-'), 2), 2, true);
$options[$key] = $val;
}
}
// getopt — parsing argumen yang lebih terstruktur
$options = getopt('v', ['verbose', 'env:', 'port::', 'help']);
// 'v' — flag singkat tanpa nilai
// 'env:' — wajib ada nilai (--env=production atau --env production)
// 'port::' — nilai opsional (--port atau --port=8080)
if (isset($options['help'])) {
echo "Usage: php script.php --env=production [--port=8080]\n";
exit(0);
}
// exit code — penting untuk CI/CD dan shell scripting
exit(0); // sukses
exit(1); // error umum
// PHP exit code 0 = sukses, non-zero = error
// Deteksi apakah berjalan di CLI
if (PHP_SAPI === 'cli') {
echo "Berjalan di command line\n";
} else {
echo "Berjalan di web server\n";
}
Fungsi Lain-lain yang Berguna #
<?php
// Parsing URL
$url = 'https://user:[email protected]:8080/path/to/page?key=val&foo=bar#anchor';
$parts = parse_url($url);
// [
// 'scheme' => 'https', 'host' => 'example.com', 'port' => 8080,
// 'user' => 'user', 'pass' => 'pass',
// 'path' => '/path/to/page', 'query' => 'key=val&foo=bar', 'fragment' => 'anchor'
// ]
echo parse_url($url, PHP_URL_HOST); // "example.com"
echo parse_url($url, PHP_URL_PATH); // "/path/to/page"
// parse_str — parse query string ke array
parse_str('nama=Budi&umur=28&hobi[]=baca&hobi[]=koding', $hasil);
// ['nama' => 'Budi', 'umur' => '28', 'hobi' => ['baca', 'koding']]
// http_build_query — kebalikan parse_str
$query = http_build_query(['nama' => 'Budi Santoso', 'umur' => 28]);
// "nama=Budi+Santoso&umur=28"
$url = 'https://api.example.com/search?' . http_build_query([
'q' => 'laptop gaming',
'limit' => 10,
'offset' => 0,
]);
// header — kirim HTTP header
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('X-Custom-Header: nilai');
header('Location: https://example.com/redirect', replace: true, response_code: 301);
// Cek apakah header sudah dikirim
if (headers_sent($file, $line)) {
echo "Header sudah dikirim di $file baris $line";
}
// ob_* — output buffering
ob_start();
echo "Ini ditangkap dulu";
$output = ob_get_clean(); // ambil buffer dan bersihkan
// Berguna untuk generate template ke string
ob_start();
include 'template.php';
$html = ob_get_clean();
Ringkasan #
file_get_contentsdanfile_put_contentsuntuk file kecil-sedang;fopen/fread/fwrite/fcloseuntuk file besar dengan streaming per chunk agar tidak kehabisan memori.- Mode file penting:
'r'(baca),'w'(tulis baru/truncate),'a'(append),'x'(tulis baru, gagal jika sudah ada),'c'(tulis tanpa truncate).FILE_APPEND | LOCK_EXuntuk log file yang ditulis dari banyak proses bersamaan —FILE_APPENDmenambah di akhir,LOCK_EXmencegah corruption.realpath()mengembalikan path absolut yang sudah di-resolve termasuk symlink — gunakan sebelum membandingkan path atau sebelum operasi filesystem yang sensitif.RecursiveDirectoryIterator+RecursiveIteratorIteratoruntuk traversal direktori rekursif yang lebih fleksibel dari fungsi rekursif manual.tmpfile()membuat file sementara yang otomatis dihapus saat handle ditutup;tempnam()hanya membuat nama, file harus dihapus manual denganunlink().getopt()untuk parsing argumen CLI yang terstruktur —'param:'wajib ada nilai,'param::'nilai opsional, tanpa titik dua = flag boolean.http_build_query()untuk membangun query string secara aman — otomatis URL-encode nilai dan handle array nested.