Anda di halaman 1dari 30

8

File dan Direktori

Dalam konteks penyimpanan data, file dapat dikatakan


sebagai tempat penyimpanan alternatif (selain database).
Meskipun demikian, operasi-operasi terhadap file mutlak
diperlukan dalam pembuatan aplikasi web. Urgensi pem-
bahasan ini semakin terasa karena PHP memungkinkan URL
dan sumber daya jaringan lainnya diperlakukan layaknya file
lokal. Sebagai tambahan, bab ini juga akan membahas
operasi-operasi direktori yang sering diperlukan.

88
Informasi File
Kesuksesan operasi-operasi file sedikit banyak sangat di-
pengaruhi oleh ketersediaan informasi mengenai file terkait.
Dengan demikian, sudah sepantasnya jika kita memahami
informasi-informasi penting tersebut, khususnya di bagian
awal ini.
• Eksistensi File
Informasi mengenai eksistensi file merupakan senjata wajib
guna mencegah kegagalan operasi selanjutnya. Dalam prak-

203
tiknya, kita memanfaatkan fungsi file_exists() yang
akan mengembalikan nilai true jika file ditemukan.
if (file_exists('test.txt')) {
// Laksanakan operasi selanjutnya
// ...
}

• Nama dan Ekstensi File


Meskipun ekstensi Filesystem tidak menyediakan fungsi
khusus untuk mendapatkan nama atau ekstensi file, namun
terdapat sejumlah fungsi yang mencakup informasi tersebut,
di antaranya pathinfo() dan basename().
$fl = './test.txt';

$info = pathinfo($fl);
echo $info['basename']; // Output: test.txt
echo $info['filename']; // Output: test
echo $info['extension']; // Output: txt

echo basename($fl); // Output: test.txt


echo basename($fl, '.txt'); // Output: test

Baik pathinfo() maupun basename() juga dapat diguna-


kan pada URL.
$url = 'http://www.test.com/test.php';
print_r(pathinfo($url));
echo basename($url);

• Pemisah Path
Apabila Anda ingin menetapkan pemisah path yang portable,
gunakan slash (/) karena karakter ini dapat bekerja baik di
lingkungan Windows maupun Unix/Linux.
var_dump(file_exists('C:/tmp/test.txt'));
var_dump(file_exists('/tmp/test.txt'));

204
Meskipun ekstensi Directory juga menyediakan kons-
tanta DIRECTORY_SEPARATOR, namun lebih efisien jika
kita menggunakan karakter slash.

89
Properti File
Ketersediaan fungsi yang cukup lengkap di ekstensi
Filesystem memungkinkan kita untuk mengungkap infor-
masi detail pada suatu file. Lebih jelasnya, di sini kita akan
memanfaatkan fungsi-fungsi yang ada sesuai kebutuhan.
• Properti Standar
Layaknya explorer file, kita dapat menyajikan informasi
spesifik mengenai properti file, seperti tipe, lokasi, ukuran,
dan waktu pembuatan serta modifikasi.
$fl = './test.txt';

// Mendapatkan tipe file


echo filetype($fl), '<br />';
// Mendapatkan path absolut
echo realpath($fl), '<br />';
// Mendapatkan ukuran (dalam satuan byte)
echo filesize($fl), ' byte<br />';
// Modifikasi terakhir
$mtm = filemtime($fl);
echo date('d F Y H:i:s', $mtm), '<br />';
// Akses terakhir
$atm = fileatime($fl);
echo date('d F Y H:i:s', $atm), '<br />';

• Format Ukuran File


Informasi mengenai ukuran file yang dikembalikan dalam
satuan byte acap kali menyulitkan kita menginterpretasikan
ukuran seharusnya. Adapun langkah bijak untuk mengatasi

205
persoalan ini dengan mengonversi ukuran ke satuan terdekat,
misalnya KB, MB, atau GB.
public static function getSize($fl) {
// Array satuan
$arr = array('B','KB','MB','GB','TB','PB');
$size = filesize($fl);
$cnt = 0;
while ($size >= 1024) {
$cnt++;
$size /= 1024;
}
return number_format($size,
($cnt ? 2 : 0), ',', '.') . ' '.$arr[$cnt];
}

• Atribut File
Untuk mendapatkan informasi mengenai atribut file, guna-
kan fungsi-fungsi berawalan is_, seperti is_executable(),
is_readable(), dan is_writable().
$fl = './test.txt';

var_dump(is_readable($fl));
var_dump(is_writable($fl));
var_dump(is_executable($fl));

• Mengubah Atribut File


Melalui fungsi chmod(), ekstensi Filesystem mengizinkan
Anda untuk mengubah atribut-atribut (mode) file. Dalam
pengubahan ini, sebaiknya gunakan format bilangan berbasis
8 (oktal) pada argumen mode untuk menghindari kegagalan
operasi.
// Read write untuk owner, read untuk user lain
var_dump(chmod($fl, 0644));

var_dump(is_writable($fl));
// Output: true

var_dump(is_executable($fl));
// Output: false

206
90
Operasi File
Sehubungan dengan fungsionalitas utamanya, ada beberapa
operasi file yang disediakan oleh ekstensi Filesystem. Operasi-
operasi yang lazim dilakukan meliputi pembuatan, pengha-
pusan, penulisan, dan pembacaan.
• Penulisan File
Untuk melakukan penulisan string ke file secara praktis,
Anda dapat memanfaatkan fungsi file_put_contents().
Fungsi yang diperkenalkan sejak PHP 5 ini akan melakukan
tiga pekerjaan sekaligus, yakni membuka, menulis, dan me-
nutup file.
$str = 'Dirgahayu RI Ke-63';
$fl = './test.txt';

$write = file_put_contents($fl, $str);

if ($write) {
echo 'Berhasil, ', $write, ' byte tersimpan';
}

Bagi Anda yang masih menggunakan PHP versi 5 ke bawah,


pilihan Anda adalah fungsi fwrite() atau aliasnya,
fputs(). Adapun jika diperlukan, sebenarnya tidak sulit
untuk mendefinisikan method yang memiliki perilaku seperti
file_put_contents().
/* Replikasi file_put_contents */
function file_put_contents($fl, $data,
$append = false) {
$mode = $append ? 'a' : 'w';
$fp = fopen($fl, $mode);

if ($fp === false) {


return 0;

207
} else {
if (is_array($data)) {
$data = implode($data);
}
$byte = fwrite($fp, $data);
fclose($fp);
return $byte;
}

// Contoh penggunaan
$str = 'Dirgahayu RI ke-63';

// Replace
var_dump(file_put_contents('test.txt', $str));

// Append
var_dump(file_put_contents('test2.txt', $str,
true));

• Membaca Isi File


Tersedianya beragam fungsi pembacaan file menuntut kita
untuk memahami strategi penggunaannya. Dengan kata lain,
seyogyanya kita memilih fungsi yang tepat sesuai kebutuhan.
Apabila Anda ingin membaca seluruh isi file secara praktis
gunakan fungsi file_get_contents(). Tidak seperti
file_put_contents() fungsi ini sudah tersedia sejak PHP
4.
$fl = './test.txt';
echo file_get_contents($fl);

Pembacaan praktis seluruh file juga dapat dilakukan dengan


memanfaatkan fungsi file(). Fungsi ini identik dengan
file_get_contents(), kecuali nilai kembaliannya adalah
suatu array. Untuk alasan performansi, sebaiknya hindari
penggunaan fungsi file() ini apabila data yang akan diam-
bil cukup besar.
print_r(file($fl));

208
Sebagai alternatif, jika Anda ingin membaca file per baris,
gunakan fungsi fgets(). Sementara itu, apabila Anda hanya
ingin membaca karakter tunggal, tersedia fungsi fgetc().
Berbeda dengan pendekatan-pendekatan sebelumnya, kedua
fungsi ini memerlukan pointer file.
$fp = fopen($fl, 'r') or
die('Gagal membuka file');

if ($fp) {
while (!feof($fp)) {
$buffer = fgets($fp, 4096);
echo $buffer;
}
fclose($fp);
}

Sebagai tambahan, jika Anda ingin melakukan pembacaan


sekaligus pemformatan, gunakan fungsi fscanf().

Usahakan untuk sesegera mungkin menutup file apabila


sudah tidak diperlukan. Langkah ini sangat penting
untuk menghemat penggunaan sumber daya.

91
Highlight Sintaks
Untuk menghasilkan visualisasi kode dengan dukungan
syntax highlighting, Anda cukup menyimpan file program
dengan ekstensi .phps. Langkah ini mengambil asumsi bahwa
server Anda mendukung fitur highlighting dan mengaktifkan
baris berikut:
AddType application/x-httpd-php-source .phps

209
Apabila Anda ingin mengimplementasikan syntax
highlighting secara independen (tanpa bergantung pada
dukungan server), Anda bisa memanfaatkan fungsi
highlight_string() atau highlight_file(). Kedua
fungsi ini berbeda dalam hal penerimaan jenis argumen,
yaitu string dan file.
$kode = <<<EOQ
<?php
/**
* Tes Komentar
*
*/
function test() {
// Tes Komentar
echo 'Mari Bersatu Menuju Kejayaan';
}
?>
EOQ;

highlight_string($kode);

Untuk lebih memudahkan pembacaan kode program, kita


bisa memberikan penomoran baris kode. Sebagai contoh, di
sini kita menggunakan fungsi highlight_file().
public static function printSource($fl) {
?>
<table>
<tr>
<td align="right">
<pre>
<?php
$len = count(file($fl));
$i = 0;
while ($i < $len) {
$i++;
echo $i, ' <br/>';
}
?>
</pre>
</td>
<td valign="top">
<?php highlight_file($fl); ?>

210
</td>
</tr>
</table>
<?php
}

Baik highlight_string() maupun highlight_file()


secara otomatis akan bekerja begitu menemukan tag pem-
buka PHP, meskipun tanpa dilengkapi tag penutup.

Gambar 8.1 Syntax highlighting

Alternatif lain syntax highlighting adalah dengan meman-


faatkan paket PEAR, tepatnya TextHighlighter.
require_once 'Text/Highlighter.php';

$opsi = array(
'numbers' => HL_NUMBERS_TABLE,
'tabsize' => 4,
);

// Higlight kode PHP


$hl =& Text_Highlighter::factory('PHP', $opsi);
$str = file_get_contents('./test.php');
echo $hl->highlight($str);

211
92
Include/Require File
Mengacu pada struktur aplikasi web, yang lazimnya terdiri
atas beberapa file, tidak mungkin kita dapat menghasilkan
aplikasi tanpa meng-include file lain. Sehubungan dengan hal
ini, akan dijelaskan mengenai tip dan trik seputar include/
require file.
• Menspesifikasikan File
File-file yang dimaksudkan untuk di-include, atau tidak
dijalankan secara langsung, sebaiknya disimpan dengan
ekstensi khusus, misalnya inc atau inc.php. Umumnya jenis
ekstensi kedua lebih disukai, meskipun Anda sudah mem-
proteksi file-file inc.
Untuk mencegah kegagalan include yang diakibatkan tidak
ditemukannya file, kita bisa memeriksa eksistensi file terlebih
dahulu.
function include_eksis($fl) {
if (file_exists($fl)) {
include $fl;
} else {
// Misal keluar dari program
exit('File ' . $fl . ' tidak ditemukan');
}
}

include_eksis('nothing.php');

Sebagai catatan, apabila opsi allow_url_fopen diaktifkan,


kita diperbolehkan untuk meng-include URL.
include 'http://www.test.com/test.inc';

212
• Mencegah Include/Require Ulang
Untuk mencegah include/require ulang, gunakan fungsi
include_once() atau require_once(). Kedua fungsi ini
memastikan bahwa file yang sama hanya akan di-include
sekali.
require 'test2.php';

// Ini tidak dievaluasi lagi


require_once 'test2.php';

Apabila Anda ingin mendapatkan nama-nama file yang


sudah di-include atau di-require, gunakan fungsi
get_included_files() atau get_required_files(),
yang merupakan aliasnya. Fungsi ini akan mengembalikan
array nama file, yang direpresentasikan sebagai path absolut.
include 'test.php';
require 'test2.php';
require_once 'test2.php';

echo '<pre>';
print_r(get_included_files());

• Include vs Require
Perbedaan mendasar antara include dan require terletak pada
reaksi yang ditimbulkan manakala file tidak ditemukan. Pada
pendekatan include, parser akan menampilkan pesan
warning dan mencoba melanjutkan eksekusi. Sementara itu,
pada require akan menimbulkan pesan fatal error dan
eksekusi program segera dihentikan.
include 'nothing1.php';
echo 'Ini masih dieksekusi';

require 'nothing2.php';
echo 'Ini sudah tidak dieksekusi';

Mengacu pada perilaku masing-masing, kita bisa memilih


pendekatan yang tepat sesuai kebutuhan. Singkatnya, guna-

213
kan require jika ingin agar eksekusi tidak dilanjutkan, dan
sebaliknya manfaatkan include.

93
File Konfigurasi
Menyimpan konfigurasi-konfigurasi aplikasi di sebuah file
merupakan suatu langkah praktis, khususnya jika kita tidak
memiliki DBMS. File yang digunakan untuk penyimpanan
ini juga variatif, namun umumnya adalah file-file berekstensi
ini atau php.
Apabila Anda menggunakan file ini, Anda bisa meman-
faatkan fungsi parse_ini_file() untuk mengelola file.
Fungsi ini memungkinkan kita untuk menguraikan file .ini
dengan mudah. Sebagai contoh, kita memiliki file test.ini
seperti berikut:
; Contoh file .ini

[Seksi_1]
satu = 1
; Ini komentar, tidak diproses
dua = 5

[Seksi_2]
tiga = "tiga"
empat = "empat"

Pada saat ingin menguraikan file .ini, Anda bisa mengikutkan


bagian seksi atau mengabaikannya. Langkah ini dilakukan
dengan cara menambahkan argumen opsional boolean true
atau mengosongkannya.
$fl = 'test.ini';

// Mengabaikan seksi (membentuk array asosiatif)


$ini1 = parse_ini_file($fl);

214
// Mengakses elemen tiga
echo $ini1['tiga']; // Output: tiga
print_r($ini1);
/* Output
Array
(
[satu] => 1
[dua] => 5
[tiga] => tiga
[empat] => empat
)
*/

// Ikutkan seksi (membentuk array multidimensi)


$ini2 = parse_ini_file($fl, true);
print_r($ini2);
/* Output:
Array
(
[Seksi_1] => Array
(
[satu] => 1
[dua] => 5
)

[Seksi_2] => Array


(
[tiga] => tiga
[empat] => empat
)
)
*/

Perlu diperhatkan, penulisan nilai (value) string dilakukan


menggunakan tanda kutip ganda. Adapun penggunaan tanda
kutip tunggal mengakibatkan hasil pengaksesan (keluaran)
juga mengandung tanda kutip tunggal.
Khusus untuk file konfigurasi php, kita cukup memerlukan
operasi penulisan saja karena pembacaan dapat dilakukan
layaknya mengakses variabel. Penyimpanan konfigurasi di file
php cenderung lebih aman dibanding file ini. Hal ini karena
file diperlakukan sebagai kode program. Artinya, selama file
tidak men-generate output, browser tidak akan mencetak

215
informasi apa pun ketika mencoba mengakses file konfi-
gurasi.

94
Informasi Direktori
Untuk mendapatkan informasi-informasi direktori, kita bisa
memanfaatkan fungsi-fungsi Filesystem. Selain itu, PHP juga
menyediakan ekstensi Directory yang khusus didesain untuk
menangani direktori.
• Eksistensi Direktori
Fungsi file_exists() tak hanya dimaksudkan untuk me-
meriksa eksistensi file, namun juga mencakup direktori.
Sementara itu, untuk memastikan bahwa objek benar-benar
merupakan direktori, gunakan fungsi is_dir().
var_dump(file_exists('./dir'));
// Memeriksa eksistensi subdirektori
var_dump(file_exists('./dir/subdir'));

// Memastikan bahwa benar-benar direktori


var_dump(is_dir('./dir'));
var_dump(is_dir('./dir/subdir'));

• Nama dan Path


Untuk mendukung operasi-operasi direktori, terkadang kita
memerlukan informasi mengenai nama dan path direktori
terkait. Langkah ini bisa kita wujudkan dengan meman-
faatkan fungsionalitas dirname() dan realpath().
$dir = 'dir/subdir';

// Mengembalikan nama direktori


echo dirname($dir);

216
// Mengembalikan path absolut
echo realpath($dir);

Sementara itu, jika Anda ingin mendapatkan nama path


current direktori, Anda bisa memanfaatkan fungsi
getcwd().
echo getcwd();

• Properti Direktori
Layaknya bekerja dengan file, kita bisa memanfaatkan fungsi-
fungsi berawalan is_ untuk mendapatkan informasi
mengenai properti direktori.
$dir = 'dir/subdir';

var_dump(is_readable($dir));
var_dump(is_writeable($dir));

95
Traversal File
Berbekal fungsi-fungsi yang telah tersedia, Anda tidak akan
kesulitan melakukan operasi ini. Namun bagaimana imple-
mentasinya secara nyata? Bagaimana pula mengimplemen-
tasikan traversal pada direktori dan subdirektori?
Bagi pengguna PHP 5 ke atas, Anda dapat memanfaatkan
fungsi scandir() untuk memindai file-file di suatu direk-
tori. Di samping mendapatkan nama-nama file dan direktori,
fungsi ini juga mengembalikan metaentry “.” (current
direktori) dan ‘..” (direktori induk). Oleh karena itu, jika
Anda hanya ingin mengambil nama-nama file, gunakan
fungsi is_file() untuk menyaring entry.
class Traversal {

217
public static function scanFile($dir) {
$arr = array();
if (is_dir($dir)) {
$fls = scandir($dir);
foreach ($fls as $fl) {
$path = $dir . '/' . $fl;
// Hanya mengambil file
if (is_file($path)) {
$arr[] = $fl;
}
}
return $arr;
} else {
return false;
}
}

Adapun bagi pengguna PHP 4, Anda bisa mengombinasikan


fungsionalitas opendir() dan readdir() untuk men-
definisikan method yang berperilaku seperti scandir().
public static function listFile($dir) {
$arr = array();
if ($d = opendir($dir)) {
while (false !== ($fl = readdir($d))) {
$path = $dir . '/' . $fl;
// Hanya mengambil file
if (is_file($path)) {
$arr[] = $fl;
}
}
closedir($d);
}
return $arr;
}

Dalam konteks paradigma berorientasi objek, traversal file di


atas dapat kita tuliskan sebagai berikut:
public static function listFileOO($dir) {
$arr = array();
$d = dir($dir);

218
while (false !== ($fl = $d->read())) {
$path = $dir . '/' . $fl;
// Hanya mengambil file
if (is_file($path)) {
$arr[] = $fl;
}
}
$d->close();
return $arr;
}

Khusus untuk traversal yang mencakup seluruh subdirektori,


kita bisa menggunakan pendekatan rekursif.
public static function listFileRec($dir) {
$arr = array();
if (is_dir($dir)) {
$fls = scandir($dir);
foreach ($fls as $fl) {
// Abaikan metaentry
if ($fl != '.' && $fl != '..') {
$path = $dir . '/' . $fl;
// Jika direktori, panggil method ini
// secara rekursif guna mencari
// di subdirektori
if (is_dir($path)) {
$arr = array_merge($arr,
Traversal::listFileRec($path));
} else {
$arr[] = $path;
}
}
}
return $arr;
} else {
return false;
}
}

Penggunaan array_merge() di atas mengakibatkan hasil


yang dikembalikan berupa array indexed. Jika Anda meng-
abaikan array_merge(), Anda akan mendapatkan hasil
berupa array multidimensi.

219
96
Pencarian dan Penyaringan File
Untuk melakukan pencarian dan penyaringan file, PHP
menyediakan pendekatan yang variatif. Bagian ini akan
mengulas beberapa pendekatan yang nantinya mungkin bisa
Anda adopsi atau kembangkan lebih lanjut.
Salah satu pendekatan yang praktis adalah dengan meman-
faatkan fungsi glob(). Fungsi ini menerima argumen
berupa pola, dan akan mengembalikan array berisi file/
direktori yang sesuai.
// Mencari file berekstensi .php
$list = glob('*.php');

foreach ($list as $fl) {


echo $fl, '<br />';
}

Fungsi glob() normalnya hanya melakukan pencarian di


current direktori sehingga kita perlu mengubah lokasi
direktori ketika ingin bekerja dengan direktori lain.
// Mencari file .txt di direktori /tmp
$d = '/tmp/*.txt';
// Mengubah direktori aktif
chdir(dirname($d));

$list = glob(basename($d));
foreach ($list as $fl) {
echo $fl, '<br />';
}

Pendekatan lain yang dapat kita gunakan adalah dengan


memanfaatkan method pengambilan file sebelumnya. Untuk
tujuan pencarian ini, kita tinggal menambahkan fungsiona-
litas pencarian, misalnya menggunakan fungsi stripos().

220
class Pencarian {

public static function find($key, $dir) {


$arr = array();

if (is_dir($dir)) {
$fls = scandir($dir);
foreach ($fls as $fl) {
// Abaikan metaentry
if ($fl != '.' && $fl != '..') {
$path = $dir . '/' . $fl;
// Jika direktori, cari secara rekursif
if (is_dir($path)) {
$arr = array_merge($arr,
Pencarian::find($key, $path));
} else {
// Jika sesuai, simpan ke array
if ((stripos($fl, $key)) !== false) {
$arr[] = $path;
}
}
}
}

return $arr;
} else {
return false;
}
}

echo '<pre>';
// Mencari file test
print_r(Pencarian::find('test', '/tmp'));

// Menyaring file berekstensi .txt


print_r(Pencarian::find('.txt', '/tmp'));

221
Gambar 8.2 Pencarian dan penyaringan file

97
Operasi Direktori
Sebagaimana diketahui, operasi-operasi direktori yang utama
meliputi pembuatan dan penghapusan. Secara umum,
operasi-operasi ini dapat kita lakukan dengan mudah melalui
fungsi-fungsi yang tersedia.
Untuk menciptakan direktori baru, PHP menyediakan fungsi
built-in mkdir().
$dir = './test';
if (!is_dir($dir)) {
// Buat direktori baru
mkdir($dir);
}

Sekadar catatan, mkdir() hanya dapat menciptakan direk-


tori baru apabila induk direktorinya eksis. Jika Anda ingin
menciptakan subdirektori sekaligus induk direktorinya, Anda

222
bisa memanfaatkan program mkdir sistem. Dalam imple-
mentasinya, gunakan fungsi exec() atau system() untuk
menjalankan program tersebut.
// Untuk lingkungan Unix/Linux
public static function mkdirNix($dir) {
if (!is_dir($dir)) {
$dir = escapeshellarg($dir);
exec('/bin/mkdir -p ' . $dir);
return true;
} else {
return false;
}
}

// Untuk lingkungan Windows


public static function mkdirWin($dir) {
if (!is_dir($dir)) {
$dir = escapeshellarg($dir);
exec('mkdir ' . $dir);
return true;
} else {
return false;
}
}

Selain operasi-operasi umum, mungkin kita juga akan me-


nemui operasi khusus, seperti penghapusan direktori yang
tidak kosong. Bagaimanapun juga, fungsi rmdir() tidak
dapat digunakan untuk menghapus direktori dan isinya.
Adapun sebagai solusi, kita mengadopsi pendekatan del tree.
Tekniknya, hapus dari akar kemudian baru menghapus
induk direktori.
public static function deltree($dir) {
if (is_dir($dir)) {
$dirs = scandir($dir);
foreach ($dirs as $fl) {
if ($fl != '.' && $fl != '..') {
$path = $dir . '/' . $fl;
// Panggil secara rekursif
if (is_dir($path)) {
Direktori::deltree($path);
} elseif (is_file($path)) {

223
// Hapus file
unlink ($path);
}
}
}
return rmdir($dir);
} else {
return false;
}
}

Sebagai alternatif, penghapusan direktori tak kosong dapat


dilakukan dengan memanfaatkan program sistem. Seperti
kasus sebelumnya, di sini kita menggunakan fungsi exec()
untuk menjalankan program eksternal.
// Untuk lingkungan Unix/Linux
public static function delNix($dir) {
if (is_dir($dir)) {
$dir = escapeshellarg($dir);
exec('rm -rf ' . $dir);
return true;
} else {
return false;
}
}

// Untuk lingkungan Windows


public static function delWin($dir) {
if (is_dir($dir)) {
$dir = escapeshellarg($dir);
exec('rmdir /s /q ' . $dir);
return true;
} else {
return false;
}
}

224
98
Iterator Direktori
Jika di bab awal kita telah mengulas SPL, kali ini akan di-
jelaskan implementasinya terkait dengan operasi direktori.
Setidaknya ada dua kelas khusus yang dapat kita manfaatkan
untuk bekerja dengan direktori, yakni DirectoryIterator
dan RecursiveDirectoryIterator.
Melalui objek DirectoryIterator, kita dapat memindai
entry di dalam direktori secara praktis. Dalam pengguna-
annya, isikan path direktori sebagai argumen konstruktor
kelas ini.
$dir = '/tmp';
try {
// Menciptakan objek iterator direktori
$di = new DirectoryIterator($dir);

foreach ($di as $fl) {


if (is_file($dir . '/' . $fl)) {
echo $fl, '<br />';
}
}

} catch(Exception $e) {
echo 'File tidak ditemukan..';
}

Seperti halnya pendekatan rekursif yang kita gunakan, SPL


juga menyediakan kelas untuk pemindaian seluruh file di
direktori dan sub-sub direktori.
$dir = '/tmp';

try {
// Menciptakan objek iterator rekursif
$rdi = new RecursiveDirectoryIterator($dir);
$rii = new RecursiveIteratorIterator($rdi);

225
// Cetak semua file beserta path-nya
foreach ($rii as $fl) {
echo $fl, '<br />';
}

} catch(Exception $e) {
echo 'File tidak ditemukan..';
}

99
Operasi File dengan PEAR
Bagian ini secara khusus akan menjelaskan operasi-operasi
file dengan memanfaatkan paket PEAR. Sebenarnya ada
beberapa paket yang terkait dengan operasi file, namun di
sini kita memfokuskan pada fungsionalitas paket File dan
File_Find.
• Paket File
Paket ini memungkinkan kita melakukan operasi-operasi
standar pada file dan direktori dengan mudah. Secara umum,
fungsionalitas ekstensi Filesystem terangkum di dalam paket
File.
require_once 'File.php';

$fl = './test.txt';

$e = File::write($fl, 'Halo Indonesia',


FILE_MODE_WRITE);
if (PEAR::isError($e)) {
echo 'Error: ' . $e->getMessage();
} else {

// Membaca isi file


echo File::readAll($fl);
}

226
• Paket File_Find
Paket ini memungkinkan kita melakukan pencarian file
dengan pola yang variatif. Bagi Anda yang terbiasa meng-
gunakan explorer file, Anda bisa memanfaatkan jenis pola
shell.
require_once 'File/Find.php';

$dir = '/tmp';

// Pola untuk semua file, kecuali


// yang berekstensi .html
$pola = '*.*|*.html';

// Pencarian dengan jenis pola shell


$fl = &File_Find::search($pola, $dir, 'shell');

echo '<pre>';
print_r($fl);

Jenis pola lainnya yang tersedia adalah php (mengacu standar


POSIX) dan perl (mengacu standar PCRE).
// Pola untuk semua file berekstensi .txt
$pola = '/\.txt$/i';

// Pencarian dengan jenis pola perl


$fl = &File_Find::search($pola, $dir, 'perl');

echo '<pre>';
print_r($fl);

• Paket File_SearchReplace
Paket ini sangat berguna ketika Anda ingin me-replace teks di
satu atau lebih file. Kelebihan lain dari paket ini adalah
mampu menangani semua file di direktori dan mengabaikan
baris teks tertentu.
Require_once 'File/SearchReplace.php' ;

// File target
$files = array( 'test1.txt',

227
'test2.txt',
'test3.txt'
);

$dir = './';

// Teks yang dicari


$find = 'Jaya';
// Teks pengganti
$repl = 'Merdeka';
// Mencakup subdirektori
$sub = true;
// Abaikan baris dengan karakter awal sbb
$ignoreline = array("#", ":");

// Menciptakan objek
$sr = new File_SearchReplace($find, $repl,
$files, $dir, $sub, $ignoreline) ;

// Start search dan replace


$sr -> doSearch() ;

100
Upload File
Di PEAR, kita bisa memanfaatkan paket HTTP_Upload
untuk mengirim file dengan mudah dan aman. Fitur yang
disediakan paket ini tergolong cukup lengkap, meliputi me-
kanisme validasi, informasi upload, dan penanganan bebe-
rapa file sekaligus. Berikut contoh sederhana penggunaan
HTTP_Upload.
<form action="<?php $_SERVER['PHP_SELF'];?>"
method="post" enctype="multipart/form-data">
<input type="file" name="fl" />
<input type="submit" name="submit" />
</form>

<?php

228
if (isset($_POST['submit'])) {
require_once 'HTTP/Upload.php';
// Lokasi upload
$dir = 'upload';

$hu = new HTTP_Upload("en");


// Mendapatkan file
$fl = $hu->getFiles('fl');

if ($fl->isValid()) {
// Upload file
$moved = $fl->moveTo($dir);
if (!PEAR::isError($moved)) {
echo 'Upload berhasil';
echo '<pre>';
// Debug (print info)
print_r($fl->getProp());
} else {
echo $moved->getMessage();
}
} elseif ($fl->isMissing()) {
echo 'File Kosong';
} elseif ($fl->isError()) {
echo $file->errorMsg();
}

Untuk kasus upload beberapa file, kita tidak perlu mene-


tapkan argumen pada method getFiles(). Akibatnya,
method ini akan mengembalikan hasil berupa array file.
<form action="<?php $_SERVER['PHP_SELF'];?>"
method="post" enctype="multipart/form-data">
<input type="file" name="fl1" />
<input type="file" name="fl2" />
<input type="file" name="fl3" />
<input type="submit" name="submit" />
</form>

<?php
if (isset($_POST['submit'])) {
require_once 'HTTP/Upload.php';
// Lokasi upload
$dir = 'upload';

229
$hu = new HTTP_Upload('en');
// Mendapatkan array file
$fls = $hu->getFiles();

foreach($fls as $fl){
if (PEAR::isError($fl)) {
echo $fl->getMessage();
}

if ($fl->isValid()) {
$moved = $fl->moveTo($dir);
if (PEAR::isError($moved)) {
echo $moved->getMessage();
}
$real = $fl->getProp('real');
echo 'File ' . $real .
' berhasil diupload', '<br />';
} elseif ($fl->isMissing()) {
echo 'File Kosong', '<br />';
} elseif ($fl->isError()) {
echo $fl->errorMsg();
}
}

101
Kompres/Dekompres File
PHP tidak hanya mampu digunakan untuk mendukung
operasi-operasi file standar, tetapi juga memungkinkan
melakukan operasi spesifik, seperti kompres/dekompres file.
Untuk melakukan operasi ini, Anda bisa memilih pendekatan
ekstensi built-in, PEAR, atau menulis program sendiri.
Di bagian ini, kita memilih langkah yang paling praktis, yakni
memanfaatkan ekstensi Zip File. Sebelumnya, pastikan
bahwa Anda sudah mengaktifkan ekstensi karena normalnya

230
belum aktif. Berikut contoh penggunaan ekstensi Zip File
yang direpresentasikan melalui objek ZipArchive.
$zip = new ZipArchive();
$fl = './test.zip';

// Menciptakan file zip


if ($zip->open($fl, ZIPARCHIVE::CREATE) === true)
{
$dir = './dir';
// Menambahkan file ke file zip
$zip->addFile($dir . '/elex.gif');
$zip->addFile($dir . '/test.doc');
$zip->addFile($dir . '/test.txt');

echo 'Jumlah File: ', $zip->numFiles, '<br />';


echo 'Status: ', $zip->status, '<br />';
$zip->close();
echo 'OK';
} else {
echo 'Gagal';
}

Selanjutnya, untuk tahap dekompresi, kita memanfaatkan


extractTo(). Method ini menerima argumen berupa
direktori lokasi dekompresi, yang sekaligus akan diciptakan
jika direktori belum ada.
$zip = new ZipArchive;
$fl = './test.zip';

if ($zip->open($fl) === TRUE) {


// Ekstrak ke direktori unzip
$zip->extractTo('./unzip');
$zip->close();
echo 'OK';
} else {
echo 'Gagal';
}

Di PEAR, kita bisa memanfaatkan paket Archive_Tar


untuk mengompres file. Langkah penggunaan objek
Archive_Tar juga cukup sederhana.

231
require_once 'Archive/Tar.php';

$tar = new Archive_Tar('test.tar');

// Isi arsip
$fl[0] = './dir/elex.gif';
$fl[1] = './dir/test.doc';
$fl[2] = './dir/test.txt';

// Menciptakan file tar


if ($tar->create($fl)) {
echo 'OK';
} else {
echo 'Gagal';
}

Untuk mendekompres atau meng-untar file .tar di atas,


gunakan method extract().
require_once 'Archive/Tar.php';

$tar = new Archive_Tar('test3.tar');

// Menciptakan file zip


if ($tar->extract('./untar')) {
echo 'OK';
} else {
echo 'Gagal';
}

232

Anda mungkin juga menyukai