Mencoba Memakai Standard PHP Library (SPL)


Pada pelajaran di masa perkuliahan, pelajaran dasar bagi mahasiswa biasanya adalah bahasa pemograman. Tapi sebuah bahasa pemograman tidak akan pernah sempurna bila tidak ada dukungan library atau API untuknya. Sebuah library adalah kumpulan function atau class yang dapat dipakai ulang dalam setiap proyek. Setiap bahasa pemograman memiliki filosofinya masing-masing mengenai apa yang harus menjadi bagian dari standard library. Sebagai contoh, pembuat C dan C++ memiliki filosofi hanya menyertakan sesuatu yang benar-benar sering dibutuhkan oleh seluruh programmer (bukan hanya programmer di bidang tertentu). Oleh sebab itu, standard library pada bahasa mereka berukuran kecil dan ringan. Perancang bahasa pemograman PHP memiliki filosofi lain lagi, yaitu menyediakan semua yang dibutuhkan oleh programmer web dalam library mereka sehingga programmer dapat membuat aplikasi web dengan nyaman.

Sesungguhnya PHP berkembang semakin kompleks dan mungkin semakin tidak terkendali😉 Kode program yang menghasilkan apa yang disebut sebagai PHP dapat ditemukan di https://github.com/php/php-src. Interpreter PHP dibuat dengan menggunakan bahasa pemograman C bukan C++, jadi menguasai bahasa pemograman C adalah sebuah syarat mutlak untuk menjadi kontributor PHP. Situs http://www.phpinternalsbook.com yang masih belum rampung berusaha menjelaskan internal PHP sehingga mempermudah programmer yang tertarik mengembangkan PHP. Fitur pada PHP dikembangkan berdasarkan PHP RFC (Request For Comments) yang dapat ditemukan di https://wiki.php.net/rfc. Membuat RFC baru bukan hanya sekedar me-request feature baru, tetapi juga harus sanggup membuat implementasinya (setidaknya memahami dampaknya dalam internal PHP). RFC diawali dengan tahap diskusi melalui mailing list, bila lolos, akan masuk ke dalam tahap voting untuk diseleksi lebih lanjut. Sepertinya proses ini meniru Java Specification Request (JSR) di Java🙂

Dari sekian banyak library PHP (yang akan terus bertambah), saya menemukan apa yang disebut sebagai Standard PHP Library (SPL) di http://www.php.net/manual/en/intro.spl.php. Karena namanya mengandung standard library, saya berasumsi library in berisi segala sesuatu yang dibutuhkan untuk keperluan sehari-hari. Sejak versi PHP 5.3, SPL tidak dapat di-disabled seperti extension lainnya sehingga ia pasti selalu hadir di PHP manapun. Apa saja yang ada di SPL?

SPL menyediakan beberapa struktur data baru. Saya sudah pernah memakai struktur data SplObjectStorage untuk menampung object. Apa kelebihannya dibandingkan array biasa? SplObjectStorage menjaga tidak ada object ganda. Selain itu, untuk menghapus sebuah object dari struktur data, cukup dengan memanggil detach($object). Struktur data lainnya adalah SplQueue untuk mewakili queue, SplStack untuk mewakili stack, SplDoublyLinkedList untuk mewakili doubly linked list, SplHeap untuk mewakili tree dan sebagainya.

SPL juga menyediakan beberapa iterator yang dipakai dalam perulangan foreach. Sebagai contoh, ada FilesystemIterator yang dapat dipakai untuk menjelajahi sebuah direktori. Kode program berikut akan menampilkan nama dan ukuran file/direktori di root direktori drive C:

$it = new FileSystemIterator("C:");
foreach ($it as $fileinfo) {
   printf("%30s%20u\n", $fileinfo->getFilename(), 
      $fileinfo->getSize());     
}

Sebuah iterator dapat di-filter lagi dengan menggunakan CallbackFilterIterator. Sebagai contoh, saya akan menyaring hasil FilesystemIterator di atas agar hanya mengembalikan nama file dan mengabaikan direktori, dengan kode program seperti:

$it = new CallbackFilterIterator(new FilesystemIterator("C:"), 
   function($current, $key, $iterator) { 
      return $iterator->isFile();
   }
);
foreach ($it as $fileinfo) {
   printf("%30s%20u\n", $fileinfo->getFilename(), 
      $fileinfo->getSize());     
}

LimitIterator dapat dipakai untuk membatasi iterator lainnya. Sebagai contoh, pada kode program dibawah ini, ArrayIterator seharusnya melakukan perulangan sebanyak 15 kali, tetapi LimitIterator menyebabkan perulangan hanya 10 kali saja:

$array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
$it = new LimitIterator(new ArrayIterator($array), 0, 10);
foreach ($it as $i) {
   print "$i\n";
}

Semua class yang mengimplementasikan interface Countable dapat dipakai dengan fungsi sizeof() dan count(). Selain itu, saya dapat mengimplementasikan Iterator sehingga class saya dapat dipakai pada struktur foreach. Alternatif lainnya, bila saya memiliki sudah memiliki iterator di dalam class, saya dapat men-ekposnya dengan meng-implementasi-kan interface IteratorAggregate. Sebagai contoh, pada kode program berikut ini, class Pembelian dapat dipakai pada sizeof()/count() dan juga mendukung perulangan dengan foreach:

class Pembelian implements Countable, IteratorAggregate {

    public $items;

    public function __construct() {
        $this->items = new SplObjectStorage();
    }

    public function tambahItem($kodeBrg, $jumlah) {
        $this->items->attach(new Item($kodeBrg, $jumlah));            
    }

    public function count() {
        $i=0;
        foreach ($this->items as $item) {
            $i+=$item->jumlah;
        }           
        return $i;          
    }

    public function getIterator() {
      // SplObjectStorage juga adalah sebuah Iterator
        return $this->items;     
    }

}

class Item {

    public $kodeBrg;
    public $jumlah;

    public function __construct($kodeBrg, $jumlah) {
        $this->kodeBrg = $kodeBrg;
        $this->jumlah = $jumlah;
    }

}

$invoice = new Pembelian;
$invoice->tambahItem("BRG1", 10);
$invoice->tambahItem("BRG2", 20);

$jumlah = count($invoice);
print "Jumlah barang dalam invoice adalah $jumlah\n\n";

print "Daftar item di invoice adalah:\n";
foreach ($invoice as $item) {
    print "{$item->kodeBrg} {$item->jumlah}\n";
}

Hal yang lebih menarik lagi adalah dengan mengimplementasikan interface ArrayAccess, saya dapat membuat class saya menjadi dapat dipakai seperti array. Sebagai contoh, saya akan membuat instance dari class Pembelian di atas dapat diakses seperti array, misalnya: $p[0] akan mengembalikan item pembelian pertama, $p[1] akan mengembalikan item pembelian kedua, dan seterusnya. Untuk itu, saya mengubah kode program menjadi seperti berikut ini:

class Pembelian implements Countable, IteratorAggregate, ArrayAccess {

   ...      

    public function offsetExists($offset) {
        return $offset < ($this->items->count() - 1);      
    }

    public function offsetGet($offset) {
        $this->items->rewind();
        foreach($this->items as $item) {
            if ($this->items->key() == $offset) {
                return $item;
            }
        }               
        return null;
    }

    public function offsetSet($offset, $value) {        
        // tidak diimplementasikan
    }

    public function offsetUnset($offset) {
        // tidak diimplementasikan      
    }

}

...

print "Item #1: {$invoice[0]->kodeBrg} \n";
print "Item #2: {$invoice[1]->kodeBrg}\n";   

SPL juga menyediakan interface untuk menerapkan observer design pattern yaitu SplSubject dan SplObserver. Pada design pattern ini di PHP, sebuah subject class dapat memiliki satu atau lebih class lain sebagai observer. Kemudian saat subject class memberikan notifikasi dengan memanggil notify(), maka method update pada seluruh class observer akan dikerjakan. Contoh penggunaan observer design pattern dapat dilihat di view Griffon (untuk melakukan binding) seperti saat JTextField berubah nilainya (user mengetik), maka nilai property di model akan di-update sesuatu dengan apa yang diketik.

Untuk melakukan operasi file secara OOP, SPL menyediakan class SplFileInfo, SplFileObject dan SplTempFileObject. Sebagai contoh, kode program berikut ini akan membuat file baru:

$file = new SplFileObject('C:/test.txt', 'w+');
$file->fwrite("Ini adalah isi file!");
$file->fflush(); 

SPL juga menyediakan class ArrayObject untuk memakai array di PHP secara OOP. Berikut ini adalah contoh kode program yang memakai ArrayObject:

$arr = new ArrayObject([1,7,3,1,2,6,8,3,4,5]);
$arr->asort();

foreach ($arr as $i) print "$i ";
// output: 1 1 2 3 3 4 5 6 7 8 

print "\n{$arr->count()}\n";
// output: 10

$arr->append(11);
$arr[] = 12;
foreach ($arr as $i) print "$i ";
// output: 1 1 2 3 3 4 5 6 7 8 11 12

print "\n{$arr->offsetGet(10)}\n";
print "{$arr[10]}\n";
// output:
// 11
// 11

$arr->offsetUnset(5);
$arr->offsetUnset(4);
foreach ($arr as $i) print "$i ";
// output:
// 1 1 3 3 4 5 7 8 11 12 

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: