Minggu, 10 Juni 2012

PDO (PHP Data Objects)

PDO Introduction

PDO (PHP Data Objects) adalah salah satu ekstensi yang disupport oleh PHP5 untuk mendefinisikan lightweight DBMS connection abstraction library atau dapat juga disebut database abstraction library. PDO digunakan untuk melakukan koneksi dengan berbagai macam database yang di support oleh PHP.
Jika anda pernah menggunakan PHP dan database MySQL anda pasti pernah menggunakan perintah-perintah sebagai berikut:
mysql_connect($host, $user, $password);
mysql_select_db($db);
Atau ketika anda menggunakan PHP dan database SQL Lite maka anda menggunakan perintah:
$dbh = sqlite_open($db, 0666);
Dengan menggunakan perintah-perintah tersebut diatas maka aplikasi yang anda buat akan terikat dengan database yang anda gunakan secara spesifik. Ketika anda akan melakukan migrasi database maka anda harus merubah seluruh script anda, dan hal ini akan sangat menyulitkan anda.
PDO menawarkan cara yang berbeda untuk bekerja dengan database secara lebih umum, dengan PDO perintah yang anda tuliskan untuk koneksi dengan database MySQL, SQLite, dan Postgree adalah sebagai berikut:
// For MySQL:
$conn = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
// For SQLite:
$conn = new PDO("sqlite:$db");
// And for PostgreSQL:
$conn = new PDO("pgsql:host=$host dbname=$db", $user, $pass);
Dengan PDO anda akan tidak perlu mengganti kode yang sudah anda buat sebelumnya ketika akan melakukan migrasi program.
Pada tutorial dibawah ini penulis akan menunjukan bagaimana cara bekerja dengan database menggunakan PDO.

Database Sample

Buat sample database yang akan digunakan pada aplikasi contoh, pertama buat database dengan nama pdokemudian buat dua table dengan nama books dan authors
mysql> create database pdo;
Query OK, 1 row affected (0.05 sec)
mysql> use pdo;
Database changed
mysql> create table books(
    -> id int primary key not null auto_increment
    -> author int not null,
    -> title varchar(70) not null,
    -> isbn varchar(20),
    -> publisher varchar(30) not null,
    -> year int(4) not null,
    -> summary text(2048));
Query OK, 0 rows affected (0.17 sec)
mysql> create table authors(
    -> id int primary key not null auto_increment
    -> firstName varchar(30) not null,
    -> lastName varchar(40) not null,
    -> bio text(2048));
Query OK, 0 rows affected (0.00 sec)
Tambahkan record kedalam table author sebagai berikut:
mysql> insert into authors(firstName, lastName, bio) values(
     -> 'Marc', 'Delisle', 'Marc Delisle is a member of the MySQL
Developers Guide');
Query OK, 1 row affected (0.14 sec)
mysql> insert into authors(firstName, lastName, bio) values(
     -> 'Sohail', 'Salehi', 'In recent years, Sohail has contributed
to over 20 books, mainly in programming and computer graphics');
Query OK, 1 row affected (0.00 sec)
mysql> insert into authors(firstName, lastName, bio) values(
     -> 'Cameron', 'Cooper', 'J. Cameron Cooper has been playing
around on the web since there was not much of a web with which to
play around');
Query OK, 1 row affected (0.00 sec)
Jika anda select semua data pada table authors maka dapt dilihat recordnya sebagai berikut:
mysql> select id, firstName, lastName from authors;
+----+-----------+----------+
| id | firstName | lastName |
+----+-----------+----------+
|  1 | Marc      | Delisle  |
|  2 | Sohail    | Salehi   |
|  3 | Cameron   | Cooper   |
+----+-----------+----------+
3 rows in set (0.03 sec)
Tambahkan record pada table books sebagai berikut:
mysql> insert into books(author, title, isbn, publisher, year, 
summary) values(
     -> 1, 'Creating your MySQL Database: Practical Design Tips and
Techniques', '1904811302', 'Packt Publishing Ltd', '2006',
     -> 'A short guide for everyone on how to structure your data and
set-up your MySQL database tables efficiently and easily.');
Query OK, 1 row affected (0.00 sec)
mysql> insert into books(author, title, isbn, publisher, year, 
summary) values(
     -> 2, 'ImageMagick Tricks', '1904811868', 'Packt Publishing
Ltd', '2006',
     -> 'Unleash the power of ImageMagick with this fast, friendly
tutorial, and tips guide');
Query OK, 1 row affected (0.02 sec)
mysql> insert into books(author, title, isbn, publisher, year,
summary) values(
     -> 3, 'Building Websites with Plone', '1904811027', 'Packt
Publishing Ltd', '2004',
     -> 'An in-depth and comprehensive guide to the Plone content
management system');
Query OK, 1 row affected (0.00 sec)

Mendesain Kode

Desain arsitektur aplikasi yang baik adalah salah satu kunci membangun aplikasi selain desain data model yang benar. Pada contoh aplikasi yang akan dibuat kali ini, pertama anda harus membuat file untuk koneksi dengan database yang akan dipanggil disetiap file yang membutuhkan koneksi dengan database.
Pertama buat file dengan nama common.inc.php yang akan berisi kode untuk koneksi dengan database. Kemudian tuliskan kodenya sebagai berikut:
<?php
/**
 *File untuk koneksi 
 */
//dbconnection string dan username/password
$connStr="mysql:host=localhost;dbname=pdo";
$user="root";
$pass="";

function showHeader($title){
?>
  <html>
  <head><title><?=htmlspecialchars($title)?></title></head>
  <body>
  <h1><?=htmlspecialchars($title)?></h1>
  <a href="books.php">Books</a>
  <a href="authors.php">Authors</a>
  <hr/>
<?php 
}

function showFooter(){
?>
  </body>
  </html>
<?php    
}

//membuat connection object
$conn = new PDO($connStr,$user,$pass);
?>
Untuk menampilkan data yang ada pada table books buat file books.php, kemudian ketikan kode berikut:
<?php
include_once 'common.inc..php';

$q = $conn->query("select * from books order by title");

showHeader('Books');
?>
<table width="100%" border="1" cellpadding="3">
<tr style="font-weight: bold">
  <td>Title</td>
  <td>ISBN</td>
  <td>Publisher</td>
  <td>Year</td>
  <td>Summary</td>
</tr>
<?php
while($r=$q->fetch(PDO::FETCH_ASSOC)){
?>
  <tr>
    <td><?=htmlspecialchars($r['title'])?></td>
    <td><?=htmlspecialchars($r['isbn'])?></td>
    <td><?=htmlspecialchars($r['publisher'])?></td>
    <td><?=htmlspecialchars($r['year'])?></td>
    <td><?=htmlspecialchars($r['summary'])?></td>
  </tr>
<?php    
}
?>
</table>
<?php
    showFooter();
?>
Jika dijalankan maka tampilannya adalah sebagai berikut :
image
Untuk menampilkan data pada table author buat halaman dengan nama authors.php, kemudian ketik kodenya sebagai berikut:
<?php
include_once 'common.inc.php';
$q=$conn->query("select * from authors order by lastname,firstname");
showHeader('Authors');
?>
<table width="100%" border="1" cellpadding="3">
<tr style="font-weight: bold">
  <td>First Name</td>
  <td>Last Name</td>
  <td>Bio</td>
</tr>
<?php
    while($r=$q->fetch(PDO::FETCH_ASSOC)){
?>
    <tr>
        <td><?=htmlspecialchars($r['firstName'])?></td>
        <td><?=htmlspecialchars($r['lastName'])?></td>
        <td><?=htmlspecialchars($r['bio'])?></td>
      </tr>
<?
    }
?>
</table>
<?php
    showFooter();
?>
image
 
Menggunakan Parameter untuk menampilkan Author
Pada contoh dibawah ini akan ditunjukan bagaimana cara untuk menggunakan parameter yang dikirimkan lewat url (query string). Buat file dengan nama authordetails.php kemudian tulis kode berikut:
<?php
include_once('common.inc.php');
 
$id = $_REQUEST['id'];
$q = $conn->query("select * from authors where id=$id");
$author = $q->fetch(PDO::FETCH_ASSOC);
$q->closeCursor();
 
if(!$author){
    showHeader('Error');
    echo "Salah memasukan id author";
    showFooter();
    exit;    
}
showHeader("Author: $author[firstName] $author[lastName]");
$q = $conn->query("select * from books where author=$id order by title");
$q->setFetchMode(PDO::FETCH_ASSOC);

?>
<h2>Author</h2>
<table width="60%" border="1" cellpadding="3">
<tr>
  <td><b>First Name</b></td>
    <td><?=htmlspecialchars($author['firstName'])?></td>
</tr>
<tr>
  <td><b>Last Name</b></td>
  <td><?=htmlspecialchars($author['lastName'])?></td>
</tr>
<tr>
  <td><b>Bio</b></td>
  <td><?=htmlspecialchars($author['bio'])?></td>
</tr>
</table>

<h2>Books</h2>
<table width="100%" border="1" cellpadding="3">
<tr style="font-weight: bold">
  <td>Title</td>
  <td>ISBN</td>
  <td>Publisher</td>
  <td>Year</td>
  <td>Summary</td>
</tr>

<?php
while($r=$q->fetch()){
?>
<tr>
      <td><?=htmlspecialchars($r['title'])?></td>
      <td><?=htmlspecialchars($r['isbn'])?></td>
      <td><?=htmlspecialchars($r['publisher'])?></td>
      <td><?=htmlspecialchars($r['year'])?></td>
      <td><?=htmlspecialchars($r['summary'])?></td>
</tr>
<?php 
}
?>
</table>
<?php
showFooter();
?>
Jalankan dengan menuliskan alamat url http://localhost/authordetails.php?id=2, anda dapat melihat hasil tampilan sebagai berikut:image
Jika id yang anda masukan tidak ada misal: http://localhost/authordetails.php?id=99 maka akan muncul halaman error-nya
image
Menggabungkan Dua Table
Pada contoh dibawah ini akan digabungkan dua table yaitu books dan authors, kemudian ketika user memilih daftar author yang ada maka detail author akan ditampilkan.

<?php
include_once('common.inc.php');

$q = $conn->query("SELECT authors.id, firstName, lastName, books.*
                   FROM authors, books WHERE author=authors.id ORDER BY title");
$q->setFetchMode(PDO::FETCH_NUM);
showHeader('Books');
?>
<table width="100%" border="1" cellpadding="3">
<tr style="font-weight: bold">
  <td>Author</td>
  <td>Title</td>
  <td>ISBN</td>
  <td>Publisher</td>
  <td>Year</td>
  <td>Summary</td>
</tr>
<?php
while($r=$q->fetch()){
?>
<tr>
    <td><a href="authordetails.php?id=<?=$r[0]?>">
    <?=htmlspecialchars("$r[1] $r[2]")?></a></td>
    <td><?=htmlspecialchars($r[5])?></td>
    <td><?=htmlspecialchars($r[6])?></td>
    <td><?=htmlspecialchars($r[7])?></td>
    <td><?=htmlspecialchars($r[8])?></td>
     <td><?=htmlspecialchars($r[9])?></td>
</tr>
<?php
}    
?>
</table>
<?php
    showFooter();
?>
image

Error Handling

PHP5 mempunyai fasilitas try..catch untuk menangani error yang terjadi, dengan PDO anda juga dapat menangkap error yang dapat terjadi, sebagai contoh tambahkan kode berikut pada file common.inc.php.
<?
function showError($message){
    echo"<h2>Error</h2>";
    echo "<p>".htmlspecialchars($message)."</p>";
    showFooter();
    exit;
}
//membuat connection object
try
{
    $conn = new PDO($connStr,$user,$pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
    showHeader('Error');
    showError("Maaf, error ditemukan.. koneksi gagal.. \n" . $e->getMessage());
}
?> 
Jika terjadi error maka akan tampil halaman sebagai berikut:
image

 

Membuat Fasilitas Edit Books

Sekarang kita akan menambahkan fasilitas untuk mengedit data pada table books, buat file dengan nama editbook.php. sebelum menambahkan kode program tambahkan dulu index pada field isbn pada table books, karena field isbn tidak boleh diisi dengan nilai yang sama.
CREATE UNIQUE INDEX idx_isbn ON books(isbn);
Kemudian ketik kode berikut pada file editbook.php
<?php
include_once('common.inc.php');

//ambil id buku
$id = (int)$_REQUEST['book'];
if($id){
    $q = $conn->query("select * from books where id=$id");
    $book = $q->fetch(PDO::FETCH_ASSOC);
    $q->closeCursor();
    $q=null;
}
else{
    //membuat buku baru
    $book=array();
}

//membuat list dari author
$author = array();
$q = $conn->query("SELECT id, lastName, firstName FROM authors ORDER BY lastName, firstName");
$q->setFetchMode(PDO::FETCH_ASSOC);
while($a=$q->fetch()){
    $authors[$a['id']]="$a[lastName], $a[firstName]";
}

if($_POST['submit']) {
      // memvalidasi setiap field
      $warnings = array();
      //title 
      if(!$_POST['title']) 
    {
        $warnings[] = 'Silahkan menginputkan book title';
    }
    // Author harus ada dalam key pada $authors array
      if(!array_key_exists($_POST['author'], $authors)) 
      {
        $warnings[] = 'Silahkan memilih author yang mengarang buku';
      }
      // ISBN harus berupa 10-digit number
      if(!preg_match('~^\d{10}$~', $_POST['isbn'])) {
        $warnings[] = 'ISBN harus 10 digits';
      }
      // Published tidak boleh kosong
      if(!$_POST['publisher']) {
        $warnings[] = 'Silahkan masukan publisher';
      }
      // Year harus 4 digits
      if(!preg_match('~^\d{4}$~', $_POST['year'])) {
        $warnings[] = 'Year harus 4 digits';
      }
      // Sumary tidak boleh kosong
      if(!$_POST['summary']) {
        $warnings[] = 'Silahkan masukan summary';
      }
      
      //jika tidak ada error
      if(count($warnings) == 0) {
        if(@$book['id']) {
              $sql = "UPDATE books SET title=" . $conn>quote($_POST['title']) . 
            ', author=' . $conn->quote($_POST['author']) . 
            ', isbn=' . $conn->quote($_POST['isbn']) . 
            ', publisher=' . $conn->quote($_POST['publisher']) . 
            ', year=' . $conn->quote($_POST['year']) . 
            ', summary=' . $conn->quote($_POST['summary']) . 
            " WHERE id=$book[id]";
    }
    else { //klo belum ada maka tambahkan data
              $sql = "INSERT INTO books(title, author, isbn, publisher,
              year,summary) VALUES(" . 
            $conn->quote($_POST['title']) . 
              ', ' . $conn->quote($_POST['author']) . 
            ', ' . $conn->quote($_POST['isbn']) . 
            ', ' . $conn->quote($_POST['publisher']) . 
            ', ' . $conn->quote($_POST['year']) . 
            ', ' . $conn->quote($_POST['summary']) . 
            ')';
    }
    try 
    {
        $conn->query($sql);
          header("Location: books.php");
          exit;
    }
    catch(PDOException $e) 
    {
        $warnings[] = 'Error: Duplikasi ISBN..';
    }
  }
}
else {
     // Form tidak tersubmit
      $_POST = $book;
}


showHeader('Edit Book');

if(count($warnings)) { 
      echo "<b>Please correct these errors:</b><br>";
      foreach($warnings as $w) 
      {
        echo "- ", htmlspecialchars($w), "<br>";
      }
}

?>

<form action="editBook.php" method="post">
<table border="1" cellpadding="3">
<tr>
    <td>Title</td>
    <td>
      <input type="text" name="title" 
           value="<?=htmlspecialchars($_POST['title'])?>">
    </td>
  </tr>
  <tr>
    <td>Author</td>
    <td>
      <select name="author">
        <option value="">Please select...</option>
        <?php foreach($authors as $id=>$author) { ?>
          <option value="<?=$id?>" 
            <?= $id == $_POST['author'] ? 'selected' : ''?>>
            <?=htmlspecialchars($author)?>
          </option>
        <?php } ?>
      </select>
    </td>
  </tr>
  <tr>
    <td>ISBN</td>
    <td>
      <input type="text" name="isbn" 
         value="<?=htmlspecialchars($_POST['isbn'])?>">
    </td>
  </tr>
  <tr>
    <td>Publisher</td>
    <td>
      <input type="text" name="publisher" 
         value="<?=htmlspecialchars($_POST['publisher'])?>">
    </td>
  </tr>
  <tr>
    <td>Year</td>
    <td>
      <input type="text" name="year" 
         value="<?=htmlspecialchars($_POST['year'])?>">
    </td>
  </tr>
  <tr>
    <td>Summary</td>
    <td>
      <textarea name="summary"><?=htmlspecialchars( 
                                    $_POST['summary'])?></textarea> 
  </td>
  </tr>
  <tr>
    <td colspan="2" align="center">
      <input type="submit" name="submit" value="Save">
    </td>
  </tr>
  </table>
  <?php if(@$book['id']) { ?>
    <input type="hidden" name="book" value="<?=$book['id']?>">
  <?php } ?>
</form>
<?php
// Display footer
showFooter();
?>
Kemudian tambahkan kode berikut pada halaman books.php
<tr>
    <td><?=htmlspecialchars($r['title'])?></td>
    <td><?=htmlspecialchars($r['isbn'])?></td>
    <td><?=htmlspecialchars($r['publisher'])?></td>
    <td><?=htmlspecialchars($r['year'])?></td>
    <td><?=htmlspecialchars($r['summary'])?></td>
    <td>
      <a href="editBook.php?book=<?=$r['id']?>">Edit</a> //tambahan
    </td>
</tr>

</table>
<a href="editBook.php">Tambah Buku...</a> //tambahan
image
Ketika link edit ditekan maka muncul tampilan dibawah ini:
image
Ketika link Tambah Buku ditekan maka tampil halaman berikut untuk menambah data:
image

Membuat Fasilitas Edit Author

Setalah membuat halaman untuk edit books maka sekarang kita akan membuat halaman untuk edit author, buat halaman dengan nama editauthor.php kemudian tambahkan kode berikut:
<?php
include('common.inc.php');

$id = (int)$_GET['author'];

if($id){
    $q = $conn->query("select * from authors where id=$id");
    $author = $q->fetch(PDO::FETCH_ASSOC);
    $q->closeCursor();
    $q=null;
}
else{
    $author=array();
}

if($_POST['submit']){
    $warnings=array();
    
    if(!$_POST['firstName']) {
        $warnings[] = 'Silahkan masukan first name';
      }

      if(!$_POST['lastName']) {
        $warnings[] = 'Silahkan masukan last name';
      }
  
      if(!$_POST['bio']) {
        $warnings[] = 'Silahkan masukan bio';
      }
  
      //jika tidak ditemukan error 
    if(count($warnings)==0){
            $sql = "update authors set firstName=".$conn->quote($_POST['firstName']).
            ",lastName=".$conn->quote($_POST['lastName']).
            ",bio=".$conn->quote($_POST['bio']).
            " where id=".$_POST['author'];
        $conn->query($sql);
        header("Location: authors.php");
    }
  
}
else { //form tidak disubmit
    $_POST=$author;
}

showHeader("Edit Author");

if(count($warnings)){
    echo "<strong>Error ditemukan :<br/></strong>";
    foreach($warnings as $w){
        echo "- ". htmlspecialchars($w), "<br/>";;
    }
}
?>

<form action="editAuthor.php" method="post">
  <table border="1" cellpadding="3">
  <tr>
    <td>First name</td>
    <td>
      <input type="text" name="firstName" 
           value="<?=htmlspecialchars($_POST['firstName'])?>">
    </td>
  </tr>
  <tr>
    <td>Last name</td>
    <td>
      <input type="text" name="lastName" 
           value="<?=htmlspecialchars($_POST['lastName'])?>">
               </td>
  </tr>
  <tr>
    <td>Bio</td>
    <td>
      <textarea name="bio"><?=htmlspecialchars($_POST['bio'])?>
      </textarea> 
    </td>
  </tr>
  <tr>
    <td colspan="2" align="center">
         <input type="submit" name="submit" value="Save" />
    </td>
  </tr>
  </table>
 
    <input type="hidden" name="author" value="<?=$_POST['id']?>" />

</form>
<?php
// Display footer
showFooter();
?>
Kemudian pada halaman author.php tambahkan kode untuk link ke halaman editauthor sebagai berikut:
<tr>
    <td><?=htmlspecialchars($r['firstName'])?></td>
    <td><?=htmlspecialchars($r['lastName'])?></td>
    <td><?=htmlspecialchars($r['bio'])?></td>
    <td>
      <a href="editAuthor.php?author=&lt;?=$r['id']?>">Edit</a>
    </td>
</tr>

untuk lebih lengkapnya lihat source

Tidak ada komentar:

Posting Komentar