Selasa, 29 Januari 2013

Tutorial Membangun Sistem Database

 Operasi database adalah salah satu fasilitas yang mutlak harus ada dalam sebuah framework MVC. Pada tulisan kali saya akan mengulas bagaimana membuat class Model dan fungsi-fungsi untuk operasi database.

Dalam pemrograman PHP terdapat beberapa cara untuk mengoperasikan database khususnya mysql, antara lain menggunakan metode klasik yaitu dengan memanfaatkan fungsi bawaan (mysql_connect, mysql_select_db, mysql_query). Codeigniter merupakan salah satu contoh framework MVC yang memanfaatkan operasi klasik ini(http://www.codeigniter.com).

Selain operasi database klasik diatas, saat ini sudah tersedia modul PHP Data Object (PDO). PDO didesain mampu men-support banyak engine database misalnya MySql, Oracle, PostgresSQL, Ms Sql server dsb. PDO mendukung pemrograman berorientasi object (OOP), sehingga syntax pemrogramannya lebih sistematis dan mudah digunakan. Sayangnya tidak semua web hosting telah mengaktifkan modul PDO, bahkan ada juga web hosting yang tidak menyediakan modul PDO ini. Salah satu framework yang memanfaatkan operasi database PDO adalah Obullo (http://www.obullo.com).

Memang operasi database klasik maupun PDO mempunyai kelebihan dan kelemahan. Oleh karena itu pada framework ini sengaja saya sediakan dua-duanya. Jadi nantinya programmer bisa memilih, bisa menggunakan operasi database klasik atau PDO.

Tole : "Pakdhe..pakdhe, kalau framework sampean ini mendukung  dua operasi database apa tidak semakin berat kerja server-nya Pakdhe?"
Pakdhe : "Ya tidaklah Tole, kan nantinya programmer milih salah satu, dan ketika salah satu operasi tadi dipilih operasi yang lain tidak di-load, jadi tidak berat kerja server-nya"
Tole :"O..gitu to Pakdhe,ya sudah Pakdhe, tak simaknya dulu ntar nanti kita buktikan ya Pakdhe...kerja servernya berat apa tidak"
Pada implementasinya, sengaja saya gunakan design pattern factory, adapter dan driver. Hal ini bertujuan agar framework ini fleksibel dan mudah untuk digunakan oleh programmer yang lain. Untuk lebih memudahkan dalam pembuatan program, sengaja operasi database ini saya letakkan pada folder system/database. Adapun susunan direktori operasi database ini, terlihat seperti gambar disamping ini.

Driver database yang saya sediakan hanya mysql. Dilain waktu saya akan menambahkan driver untuk database lain misalnya Oracle, MS SQL Server, Postgres SQL dan sebagainya. Tentunya masing-masing driver tersebut mendukung operasi klasik dan PDO.

1. Factory
Jika kita baca di bukunya Gang of Four "Design Patterns: Elements of Reusable Object-Oriented Software", factory ini tergolong dalam kreasional desain. Factory tersebut perlu kita buat ketika kita perlu mendefinisikan sebuah tipe data/class (kita sebut kreator)  yang berfungsi untuk membuat objek dari tipe data/class yang berbeda (kita sebut produk).  Tujuannya adalah agar pengguna tidak perlu capek-capek mempelajari class produk tadi. Pada framework ini yang disebut factory adalah class db_factory sedangkan yang disebut class produk adalah db_adapter. Dalam literatur lain, saya menemukan ada sistem dependency injection. Sistem dependency injection ini lebih sederhana dibandingkan dengan factory. Oleh karena itu dalam pembuatan program kali ini saya memanfaatkan dependency injection dalam membangun class database factory. Dibawah ini contoh source code class db_factory

  1. <?php defined('SYS'or exit('Access Denied!');  
  2. /*  
  3. * Becak MVC Framework version 1.0  
  4. * 
  5. * File      : db_factory.php 
  6. * Directory : system/database 
  7. * Author    : Eko Heri Susanto 
  8. * Description   : penyedia koneksi ke bermacam-macam database 
  9. */  
  10. class db_factory {  
  11.     public static function callDB($db_name){  
  12.         include APP.'config'.DS.'database'.PHP_EXT;  
  13.         if(!is_array($config[$db_name]))   
  14.             throw new Exception("Please set a valid database driver from config database file");  
  15.         $driver_class = strtolower($config[$db_name]['type']);  
  16.         include SYS.'database'.DS.'driver'.DS.$driver_class.PHP_EXT;  
  17.         include SYS.'database'.DS.'db_adapter'.PHP_EXT;  
  18.             $driver = new $driver_class($config[$db_name]);   
  19.         $adapter = new db_adapter($driver);  
  20.         return $adapter;  
  21.     }//end callDB  
  22. }//end class  
  23. ?>  
2. Adapter
Telah saya sebutkan diatas, operasi database dalam framework ini mendukung banyak driver database. (mysql, oracle ms-sql server dsb). Sebenarnya masing-masing driver tersebut cara penggunaannya tentu berbeda antara satu dengan yang lain. Oleh karena itu kita perlu design pattern adapter agar pengguna tidak perlu memikirkan bagaimana cara mengoperasikan masing-masing driver tersebut.
Gambar disamping menunjukkan desain sistem db_factory dan db_adapter yang sudah saya jelaskan sebelumnya.

Fungsi/method callDB pada class db_factory ini nantinya akan dipanggil pada fungsi database yang ada di class loader. Untuk lebih jelasnya silakan anda lihat contoh source code yang saya sertakan. Ingat class loader ini terdapat pada folder core.

Coba anda perhatikan method yang terdapat pada db_adapter, disitu terdapat metode-metode untuk mengoparesikan database seperti pencarian (select), penambahan (insert), perubahan (update) dan penghapusan (delete) data. Saya temukan dibeberapa contoh framework, method-method ini ada yang menyebutnya dengan istilah active record. Dibeberapa buku design pattern active record ini sudah diakui sebagai salah satu pola dalam design pattern. Dibawah ini contoh source code class db_adapter

  1. <?php defined('SYS'or exit('Access Denied!');  
  2. /*  
  3. * Becak MVC Framework version 1.0  
  4. * 
  5. * File      : db_adapter.php 
  6. * Directory : system/database 
  7. * Author    : Eko Heri Susanto 
  8. * Description   : fungsi common (CRUD) untuk database 
  9. */  
  10. class db_adapter {  
  11.     private $driver = null;  
  12.     private $sql = '';  
  13.     public function __construct($driver){  
  14.         $this->driver = $driver;  
  15.         $this->driver->connect();  
  16.     }  
  17.     public function __destruct(){  
  18.         $this->driver->disconnect();  
  19.     }  
  20.     public function select($sql){  
  21.         $this->sql = $sql;  
  22.     }  
  23.     public function fetch_array(){  
  24.         return $this->driver->results($this->sql, 'array');  
  25.     }  
  26.     public function fetch_object(){  
  27.         return $this->driver->results($this->sql, 'object');  
  28.     }  
  29.     public function query($sql){  
  30.         return $this->driver->query($sql);  
  31.     }  
  32.     public function insert($table$data){  
  33.         $sql = "INSERT INTO ".$table;  
  34.         $multi_rows = FALSE;  
  35.         foreach($data as $key => $val){  
  36.             if(!is_array($val) ) {  
  37.                 $fields[$key] = $key;  
  38.                 $rows[$key] = $this->escape($val);  
  39.             }else {  
  40.                 $multi_rows = TRUE;  
  41.                 foreach($val as $skey => $sval){  
  42.                     $fields[$skey] = $skey;  
  43.                     $row[$skey] = $this->escape($sval);  
  44.                 }  
  45.                 $rows[$key] = "(".implode(', '$row).")";  
  46.             }  
  47.         }  
  48.         $sql .= " (". implode(', '$fields).") VALUES ";  
  49.         if(!$multi_rows$sql .= "(". implode(', '$rows).");";  
  50.         else $sql .= implode(', '$rows).";";  
  51.         return $this->driver->query($sql);  
  52.         }  
  53.     public function update($table$data$where=NULL){  
  54.         $sql = "UPDATE ".$table." SET ";  
  55.         $values = array();  
  56.         foreach($data as $key => $val){  
  57.             $values[$key] = $key." = ".$this->escape($val);  
  58.         }  
  59.         $sql .= implode(", "$values);  
  60.         if(is_array($where)){  
  61.             $filter = array();  
  62.             foreach($where as $key => $val){  
  63.                 $filter[$key] = "(".$key." = ".$this->escape($val).")";  
  64.             }  
  65.             $sql .= " WHERE ".implode(" AND "$filter);  
  66.         }  
  67.         return $this->driver->query($sql);  
  68.     }  
  69.     public function delete($table$where=NULL){  
  70.         $sql = "DELETE FROM ".$table;  
  71.         if(is_array($where)){  
  72.             $filter = array();  
  73.             foreach($where as $key => $val){  
  74.                 $filter[$key] = "(".$key." = ".$this->escape($val).")";  
  75.             }  
  76.             $sql .= " WHERE ".implode(" AND "$filter);  
  77.         }  
  78.         return $this->driver->query($sql);  
  79.     }  
  80.       
  81.     private function escape($str)  
  82.         {  
  83.         if(is_string($str)){  
  84.             return "'".str_replace("'""''",$str)."'";  
  85.         }  
  86.   
  87.         if(is_integer($str))  
  88.         return (int)$str;  
  89.   
  90.         if(is_double($str))  
  91.         return (double)$str;  
  92.   
  93.         if(is_float($str))  
  94.         return (float)$str;  
  95.   
  96.         if(is_bool($str))  
  97.         return ($str === FALSE) ? 0 : 1;  
  98.   
  99.         if(is_null($str))  
  100.         return 'NULL';  
  101.         }  
  102. }//end class  
  103. ?>  
3. Driver
OK, selanjutnya mari kita lanjutkan untuk membahas class driver. Ingat class driver ini merupakan tata cara pengoperasian database yang sesungguhnya. Gambar dibawah ini menjelaskan struktur desain sistem driver database.

Berikut ini contoh source code class mysql (operasi database klasik)

  1. <?php defined('SYS'or exit('Access Denied!');  
  2. /*  
  3. * Becak MVC Framework version 1.0  
  4. * 
  5. * File      : mysql.php 
  6. * Directory : system/database/driver 
  7. * Author    : Eko Heri Susanto 
  8. * Description   : driver mysql 
  9. */  
  10. class mysql {  
  11.     private $conn;  
  12.     private $config;  
  13.     public function __construct($config){  
  14.         $this->config    = $config;  
  15.     }  
  16.     public function connect() {  
  17.         extract($this->config);  
  18.         if(isset($this->conn)) return $this->conn;  
  19.         $this->conn = @mysql_connect($server,$user,$password, true) or show_error("Unable connect to mysql server.Please make sure the server, username or password specified in your Database.php file is valid.");   
  20.         @mysql_select_db($database$this->conn) or show_error("Unable to select your default database name.Please make sure the database name specified in your Database.php file is valid.");  
  21.     }  
  22.     public function disconnect(){  
  23.         if(isset($this->conn)) {  
  24.             @mysql_close($this->conn);  
  25.         }  
  26.     }  
  27.     public function query($sql){  
  28.         $result = @mysql_query($sql$this->conn);  
  29.         if (!$result) {  
  30.                 show_error(mysql_error());  
  31.         }  
  32.         return $result;  
  33.     }  
  34.     public function results($query$type = 'object'){  
  35.         $result = $this->query($query);  
  36.         $return = array();  
  37.         while ($row = @mysql_fetch_object($result)) {  
  38.             if($type == 'array')  
  39.                 $return[] = (array$row;  
  40.             else  
  41.                 $return[] = $row;  
  42.         }  
  43.         @mysql_free_result($result);  
  44.         return @$return;  
  45.     }  
  46. }//end class  
  47. ?>  
Berikut ini contoh source code class mysql_pdo (operasi database PDO)

  1. <?php defined('SYS'or exit('Access Denied!');  
  2. /*  
  3. * Becak MVC Framework version 1.0  
  4. * 
  5. * File      : pdo_mysql.php 
  6. * Directory : system/database/driver 
  7. * Author    : Eko Heri Susanto 
  8. * Description   : driver PDO mysql 
  9. */  
  10. class mysql_pdo {  
  11.     private $conn;  
  12.     private $config;  
  13.     public function __construct($config){  
  14.         $this->config    = $config;  
  15.     }  
  16.     public function connect() {  
  17.         extract($this->config);  
  18.         if(isset($this->conn)) return $this->conn;  
  19.         try{  
  20.             $this->conn = new PDO ("mysql:host=$server;dbname=$database",$user,$password);  
  21.         }catch(PDOException $e){  
  22.             echo __LINE__.$e->getMessage();  
  23.         }  
  24.     }  
  25.     public function disconnect(){  
  26.         if(isset($this->conn)) {  
  27.             $this->conn = null;  
  28.         }  
  29.     }  
  30.     public function query($sql){  
  31.         $result = null;       
  32.         try{  
  33.             $result = $this->conn->exec($sqlor print_r($this->conn->errorInfo());  
  34.         }catch(PDOException $e){  
  35.             echo __LINE__.$e->getMessage();  
  36.         }  
  37.         return $result;  
  38.     }  
  39.     public function results($query$type = 'object'){  
  40.         $result = $this->conn->query($queryor print_r($this->conn->errorInfo());  
  41.         $result->setFetchMode(PDO::FETCH_ASSOC);  
  42.         return $result;  
  43.     }  
  44. }//end class  
  45. ?>  
Sampai disini pembahasan mengenai operasi database sudah selesai. Selanjutnya coba saya jelaskan bagaimana cara menjalankan contoh program yang saya sertakan.
Pertama-tama anda siapkan dulu database-nya. Caranya buka phpmyadmin, kemudian buat database baru dengan nama blogkomputer. Setelah itu silakan anda buat table content seperti contoh dibawah ini.

  1. CREATE TABLE `blogkomputer`.`content` (  
  2. `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,  
  3. `judul` VARCHAR( 100 ) NOT NULL ,  
  4. `kategori` VARCHAR( 100 ) NOT NULL ,  
  5. `isi` TEXT NOT NULL  
  6. ) ENGINE = MYISAM ;  
Setelah table-nya selesai anda buat, jangan lupa isikan contoh datanya. Ini saya sertakan query untuk mengisi data table content tersebut

  1. INSERT INTO `blogkomputer`.`content` (`id`, `judul`, `kategori`, `isi`) VALUES (NULL'Ini adalah judul 1''pemrograman''isi sembarang data disini'), (NULL'ini adalah judul 2''becak framework''becak framework adalah framework MVC yang mendukung PHP 5');  
Langkah kedua coba anda buka file database.php, yang terdapat pada folder application/config, kemudian lakukan pengaturan (setting) konfigurasi database. Lihat contoh dibawah ini

  1. $config = array();  
  2.   
  3. // jika ingin menggunakan PDO ubah mejadi 'mysql_pdo'  
  4. $config['db']['type']       = 'mysql';   
  5.   
  6. // jika anda menggunakan PDO, ubah menjadi '127.0.0.01'  
  7. $config['db']['server']     = 'localhost';   
  8.   
  9. //sesuaikan dengan user yang ada di database mysql anda  
  10. $config['db']['user']       = 'root';  
  11.   
  12. //sesuaikan dengan password mysql anda  
  13. $config['db']['password']   = '';  
  14.   
  15. //sesuaikan dengan nama database yang anda buat  
  16. $config['db']['database']   = 'blogkomputer';  
Cukup sampai disini, kedepan akan saya bahas bagaimana membuat library, helper serta menambah error handling.
Selamat mencoba, semoga ada guna dan manfaatnya...

Tidak ada komentar:

Posting Komentar