PEAR::DB_DataObject

Posted by PunNeng, Sun Dec 04 22:55:00 UTC 2005

มาเริ่ม Topic ใหม่กันที่ PEAR กันเลย

PEAR (PHP Extension and Application Repository) คืออะไร

PEAR เป็น Framework ที่รวบรวม library ต่างๆ ใหม่ๆ ที่สร้างขึ้นมาใหม่ ไว้ใช้กับ PHP โดยเฉพาะ ซึ่งมันจะช่วยอำนวยความสะดวกในการเขียนโปรแกรมขึ้นได้อีกมาก PEAR ถูกสร้างขึ้นเพื่อเตรียม
  • library ของชุด open-source สำหรับผู้ใช้ PHP
  • ระบบสำหรับ code ต่างๆ และ ระบบดูแลปรับปรุงที่เป็นส่วนๆ (Package maintenance)
  • ชุด code ที่ style ที่เป็นมาตรฐาน ซึ่งถูกกำหนดตาม linkนี้
  • PHP Extension Community Library (PECL)
ซึ่งในส่วนของ library ที่มีให้เราใช้กัน มีเยอะ เพราะมันเป็น open-source และมี community ค่อนข้างกว้าง เลยมีคนคอยพัฒนา library พวกนี้ ขึ้นมามาก ลองเข้าไปดูที่นี่ จะเห็น Package มากมาย บานเบอะ ครอบคลุมทุกการใช้งาน

แต่ที่คราวนี้คือ DB_DataObject ซึ่งจะเป็นตัวอธิบาย ORM ให้เห็นเป็นรูปเป็นร่างมากขึ้น

DB_DataObject

เป็นตัวช่วยสร้าง SQL และ Data Modeling Layer บนฝั่ง PEAR::DB มีจุดประสงค์เพื่อ

  • ช่วยสร้าง SQL และ Database เสมือน ในรูปแบบ Object Oriented
  • จับกลุ่ม source code ที่เกี่ยวข้องกับข้อมูลในข้อข้างบน
  • เตรียมชุด API ในการ access ไปยัง Database โดยต่อกับข้อมูลในข้อข้างบน

มาดูถ้าจะเขียนเป็น class แบบ ทั่วๆ ไป ไม่ได้อาศัย Framework อันอื่นมาช่วย จะได้ประมาณนี้

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
<?php
class MyPerson {

      // gets an array of data about the seleted person
      function getPerson($id) {
          global $db;
          $result = $db->query("SELECT * FROM person WHERE id=$id");
          return $result->fetchRow();
      }

      // example of checking a password.
      function checkPassword($username,$password) {
          global $db;
          $result = $db->query("SELECT username FROM person WHERE username='$username' AND password = '$password'");
          return $result->fetchRow();
      }

  }

  // get the persons details..
  $array = MyPerson::getPerson(12);
?>

จุดเจ๋งๆ ของมันเลยคือ ลักษณะของ class ที่เป็นการรวบรวมจับกลุ่ม Method1 ต่างๆ ในการเข้าถึง 1 table

(1)อันนี้เชิง OO จะใช้คำว่า Method แทน Function และ variable(ตัวแปร) จะใช้คำว่า Property(ตัวแปรในความหมายเดียวกัน) แทน

ต่อไป มาดูแบบที่พอเป็นในลักษณะ DataObject หรือ Container บ้าง ในส่วนของกลไกการเก็บข้อมูล

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
<?php
class MyPerson {

      var $id;  
      var $name;
      var $birthDate;


      // gets an array of data about the seleted person
      function get($id) {
          global $db;
          $result = $db->query("SELECT * FROM person WHERE id=$id");
          $array = $result->fetchRow();
          foreach($array as $key=>$value) {
              $this->$key = $value;
          }
      }

      function getAge() {
          return date('Y') - date('Y',$this->birthDate);
      }

  }
  // now get the person and display the age.
  $person = new MyPerson;
  $person->get(12);
  echo "{$person->name} is ". $person->getAge() . " years old";
?>

ในส่วนของ property id, name, birthDate จะเป็นชื่อของ column ใน DB เมื่อมัน loop ไปแล้ว จะวนตาม Property 3 ตัวนี้ อย่างที่เห็น หลังจากที่มันทำการเก็บ data ต่างๆ ลงใน Ojbect ตัวนี้แล้ว method ที่ถูกเพิ่มเข้ามา คือ getAge(และอันอื่นๆ ที่ถูกเพิ่มมาในอนาคต) ก็จะเข้าถึง Data เหล่านี้ได้

แต่ถ้าเราจะใช้ประโยชน์จาก property ต่างๆ ในการค้นหาใน Database ละ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
<?php
class MyPerson {

      var $id;
      var $name;
      var $birthDate;


      // does the query based on the value of $this->name
      function find() {
          global $db;
          $this->result = $db->query("SELECT * FROM person WHERE name={$this->name}");
      }

      // fetches a row of data and sets the object 
      // variables to match it.

      function fetch() {
          $array = $this->result->fetchRow();
          if (empty($array)) {
              return false;
          }
          foreach($array as $key=>$value) {
              $this->$key = $value;
          }
      }

  }
  // now get the person and display the age.
  $person = new MyPerson;
  $person->name = "John";
  $person->find();
  while ($person->fetch()) {
    echo "a {$person->name} has a birthday on {$person->birthDate}<br />";
  }
?>

ตามนี้ เราจะระบุค่าใน property ก่อนที่จะใช้ find method ในการ query ตัว DataObject ก็จะมีลักษณะพฤติกรรมเหมือนๆ กันแบบนี้ เรายังสามารถเพิ่มค่าต่างๆ ในการค้นหาได้ด้วย whereAdd() method หรือจะใช้การเลือกโดยใช้ selectAdd() method ก็ยังได้

สังเกตุดู ว่าเราสามารถที่จะแต่งเติม code ที่เป็นของเราเองเพิ่มได้ ในแต่ละ table ไม่ยากๆ มันจะมี step ของมันอยู่ ก็สร้าง methods ตามนี้เลย

  • ขั้นตอนการ fetch : get, find, fetch
  • ขั้นตอนการปรับปรุง data : update, insert และ delete
  • แล้วก็ทำการผูก data ต่างๆ ใน object นั้นๆ

หลังจากที่ทำมันเสร็จแล้ว DB_DataObject ก็ถือกำเนิดขึ้นมา แต่ก็ยังไม่ดี เลยเอามาขัดเกลาด้วย

  • เพิ่ม Common simple configuration method ทำหน้าที่ config การติดต่อกับ Database
  • ถ้าจะใช้งาน Database ให้เร็ว ควรจะใช้ primary key ให้เป็นประโยชน์เยอะๆ
  • อย่าลืมตั้งค่า ตัว Debugger ด้วย มันจะช่วยให้เห็นว่าเรากำลังทำอะไรอยู่บ้าง
  • ในการตรวจความถูกต้องของข้อมูล ใช้ Strings กับ Integers ในการตรวจสอบจะดีมาก
  • สามารถที่จะสร้างความสัมพันธ์ระหว่างตารางอย่างซับซ้อนๆ ได้ ด้วยการใช้ secondary calls(ตอนหลังๆ ถ้าไม่ลืม จะมาแสดงให้ดู ว่าทำยังไง)
  • ทำการสร้างและปรับปรุงตารางของเราด้วย Database เสมือนของเรา(อันนี้ก็เหมือนกัน จะมาทำให้ดู)
  • ต่อเติมจาก package อันอื่นด้วย setForm() และ toArray() methods(จะทำให้ดูอีกเช่นกัน)

นะ มาดู class นี้กันต่อ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
<?php
// this is the common configuration code - 
//place in a general site wide include file.

    // this  the code used to load and store 
    // DataObjects Configuration. 
    $options = &PEAR::getStaticProperty('DB_DataObject', 'options');

    // the simple examples use parse_ini_file, 
    // which is fast and efficient.
    // however you could as easily use wddx, 
    // xml or your own configuration array.
    $config = parse_ini_file('example.ini',TRUE);

    // because PEAR::getstaticProperty was 
    // called with and & (get by reference)
    // this will actually set the variable inside 
    // that method (a quasi static variable)
    $options = $config['DB_DataObject'];

     // this is normally contained in your DataObjects file 
     // (autogenerated by the generator)

    require_once 'DB/DataObject.php';


    // by extending the base class DB_DataObject 
    // you inherit all the common methods defined in it.
    class DataObjects_Person extends  DB_DataObject {

        var $id; // this is a primary id (it's specified in 
        // a config file - explained later)
        var $name;
        var $friend;

        // this is a simple function to get the persons 
        // friends..?

        function getFriends(){

            $personObject = $this->factory('person');

            // look for all people with their friend number 
            // matching this persons id.
            $personObject->friend = $this->id;

            // do the select query.
            $personObject->find();
            $array = array();

            // fetch the results into the object.
            while ($personObject->fetch()) {
                // use the clone to copy - not really needed 
                // but get used to it for PHP5

                $array[] = clone($personObject);
            }
            // return the results.
            return $array;

        }
    }


    // and this goes on your display code 

    // create a new person class..
    $person = DB_DataObject::Factory('person');

    // get the person using the primary key.
    $person->get(12);
    // get the friends.
    $friends = $person->getFriends();

    //  DB_DataObjects is designed to make print_r useable to 
    //  debug your applications.
    print_r($friends);
?>

class อันนี้แสดงให้เห็นถึงส่วนประกอบของ DB_DataObject ตั้งแต่การติดตั้ง options, objects พื้นฐานต่างๆ ก็จะโหลดจากไฟล์ .ini อย่างอัตโนมัติ แล้วก็กระบวณการ access ถึง

Database ส่วนครึงหลัง จะแสดงให้เห็นการ query และก็ดึงค่าออกมาโดยที่ $preson->get() จะต่อไปยัง Database โดยทำการ query แล้วก็ fetch ข้อมูลออกมาให้ object ตัวนึงที่รองรับอยู่ โดย query นี้คือ

SELECT * FROM person WHERE id=12;
SELECT * FROM person WHERE friend=12;

อีกตัวอย่าง ถ้าจะเปลี่ยนแปลงค่าใน Database เราจะใช้ update method

  1
  2
  3
  4
  5
  6
<?php
    $person = DB_DataObject::factory('person');
    $person->get(12);
    $person->name = 'Fred';
    $person->update();
?>

ส่วน methods อื่นๆ ชื่อมันก็คล้ายๆ กับ SQL statement แหละ ดูได้ที่นี่

แก้ไขล่าสุด วันที่ 20 มิถุนายน 2550 เวลา 3.22 น.

ข้อมูลจาก
PEAR :: Manual :: Introduction

Filed Under: General | Tags: database orm pear php

Comments

Have your say

A name is required. You may use HTML in your comments.




codegent: we're hiring