Bagaimana Menggunakan Doctrine PHP ORM?

Pada tulisan sebelumnya saya sudah menceritakan penggunaan doctrine dengan Zend Framework. Dan kali ini saya akan mencoba memberikan contoh penggunaan doctrine yang meliputi:
- Instalasi
- Konfigurasi
- Models & Schema File
- Migrasi
Cara yang paling mudah untuk belajar memakai doctrine adalah dengan menggunakan Doctrine Sandbox, yang telah dilengkapi konfigurasi dan struktur direktori.

Instalasi
Doctrine menggunakan PHP 5.2.3+ dan sebelum melakukan instalasi pastikan versi PHP anda sudah mendukung. Saat tulisan ini dibuat, versi stabil installer doctrine yang terbaru adalah 1.1.4 dan dapat diunduh di sini dan untuk Doctrine Sandbox di sini. Doctrine Sandbox juga sudah menyertakan library doctrine di dalam distribusinya, sehingga tidak perlu lagi mengunduh installer Doctrine. Jika sudah mengunduh Doctrine Sandbox dan mengekstraknya maka akan menghasilkan file dan folder - folder berikut:

config.php
data/
doctrine
doctrine.php
index.php
lib/
migrations/
models/
schema/

Berikut ini penjelasan dari folder - folder dan file - file di atas:
- config.php
Berisi konfigurasi dari Doctrine, baik itu path dari pustaka doctrine, tempat penyimpanan class model dan migrasi, schema, dan path untuk export maupun import data.
- data/
Folder ini berisi folder fixtures dan sql. fixtures digunakan untuk menyimpan file yang digunakan untuk melalkukan import data dengan format yaml. Sedangkan sql digunakan untuk menyimpan file schema hasil export dalam format sql.
- doctrine
File ini berupa file eksekusi, yang digunakan untuk sebagai alat bantu doctrine yang berjalan di command line
- doctrine.php
File ini disertakan pada alat bantu doctrine
- index.php
File ini cuma file sample
- lib/
Folder ini berisi pustaka doctrine. Pustaka ini juga terdapat pada installer doctrine. Saya sarankan untuk sebaiknya memindahkan semua file dan folder yang ada di dalamnya ke include_path php. Agar setiap project yang menggunakan doctrine, cukup menggunakan pustaka dari include path, sehingga tidak menggendong pustaka ini kemana - mana.
- migrations/
Folder ini akan berisi class - class migration yang dibuat oleh doctrine jika kita melakukan migrasi.
- models/
Folder ini akan berisi class - class models yang dibuat oleh doctrine.
- schema/
Folder ini akan berisi file schema untuk struktur database dalam format yaml.

Konfigurasi
Untuk instalasi, doctrine tidak membutuhkan konfigurasi apapun. Pustaka doctrine bisa disertakan dalam file - file project anda. Tapi saya lebih suka memindahkan pustaka doctrine ke include_path php. Konfigurasi hanya diperlukan pada saat penggunaan doctrine. Pada doctrine sandbox ini, konfigurasi bisa dilihat pada file config.php

<?php 
// set path sandbox
define('SANDBOX_PATH'dirname(__FILE__));
// set path pustaka doctrine
define('DOCTRINE_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'lib');
// set path untuk untuk data fixtures
// yaitu file yang akan digunakan untuk import data dari file yaml
define('DATA_FIXTURES_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'data' DIRECTORY_SEPARATOR 'fixtures');
// set path untuk models
define('MODELS_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'models');
// set path untuk migrasi
define('MIGRATIONS_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'migrations');
// set path untuk menyimpan file sql hasil export dari doctrine
define('SQL_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'data' DIRECTORY_SEPARATOR 'sql');
// set path untuk menyimpan schema file
define('YAML_SCHEMA_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'schema');
// set database path (diasumsikan menggunakan sqlite)
define('DB_PATH'SANDBOX_PATH DIRECTORY_SEPARATOR 'sandbox.db');
// set DSN
define('DSN''sqlite:///' DB_PATH);
// jika menggunakan mysql, user password dan database (doctrine, doctrine, doctrine) 
// define('DSN', 'mysql://doctrine:doctrine@localhost/doctrine');

// jika sudah memindahkan pustaka doctrine ke include path php,
// require_once() berikut bisa diabaikan
require_once(DOCTRINE_PATH DIRECTORY_SEPARATOR 'Doctrine.php');
spl_autoload_register(array('Doctrine''autoload'));

// buat koneksi ke database berdasarkan DSN dan set atribut
$manager Doctrine_Manager::getInstance();
$manager->openConnection(DSN'doctrine');
$manager->setAttribute('model_loading''conservative');
?>

Konfigurasi di atas akan membuat koneksi ke database dan akan selalu selalu disertakan (include/require) dalam setiap file yang membutuhkan interaksi dengan database. File konfigurasi tersebut juga disertakan pada alat bantu doctrine yaitu doctrine.php

<?php
require_once('config.php');

// menyimpan konfigurasi yang sudah dibuat pada file config.php ke dalam array
$config = array('data_fixtures_path'  =>  DATA_FIXTURES_PATH,
                
'models_path'         =>  MODELS_PATH,
                
'migrations_path'     =>  MIGRATIONS_PATH,
                
'sql_path'            =>  SQL_PATH,
                
'yaml_schema_path'    =>  YAML_SCHEMA_PATH);

// gunakan array konfigurasi ke dalam Doctrine_Cli
$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
?>

Alat bantu ini dapat dijalankan pada command line, dengan cara

./doctrine

ataupun

php doctrine.php

Perintah di atas akan menampilkan daftar dari opsi - opsi yang bisa digunakan:

Doctrine Command Line Interface
 
doctrine.php build-all
doctrine.php generate-migration
doctrine.php generate-sql
doctrine.php create-db
doctrine.php generate-models-db
doctrine.php generate-migrations-diff
doctrine.php generate-migrations-db
doctrine.php dump-data
doctrine.php build-all-reload
doctrine.php dql
doctrine.php rebuild-db
doctrine.php migrate
doctrine.php generate-models-yaml
doctrine.php create-tables
doctrine.php generate-yaml-db
doctrine.php generate-yaml-models
doctrine.php build-all-load
doctrine.php load-data
doctrine.php generate-migrations-models
doctrine.php drop-db
doctrine.php compile

Models & Schema File
Dalam konsep MVC model merupakan abstraksi dari database. Jadi untuk mengakses tabel yang ada di database tidak perlu lagi melakukan query, tetapi cukup membuat object dari model tersebut dan mengakses (magic) method ataupun (magic) property dari model tersebut. Pada doctrine, model tersebut bisa dibuat manual dengan mengikuti petunjuk berikut. Saya lebih suka membuat model tersebut secara otomatis, dengan membuat schema file terlebih dahulu. Setelah schema file dibuat, dengan menjalankan perintah berikut maka model pun secara otomatis dibuat oleh doctrine.

./doctrine generate-models-db

Membuat model saja bukan berarti anda sudah berinteraksi dengan database. Karena tabel - tabel yang ada didatabase belum dibuat. Anda melakukan insert, update, maupun delete melalui model tersebut itu masih disimpan di memori. Untuk membuat table di database berdasarkan model yang ada, bisa dibuat secara otomatis dengan command

./doctrine create-tables

Saya akan memberikan contoh penggunaan doctrine yang menangani user dan group. Pada contoh ini user dan group mempunyai relasi many to many. Berikut ini adalah isi dari schema file.

---
Group:
  tableName: groups
  columns:
    groupId:
      type: string(32)
      primary: true
    name: string(255)
  relations:
    Users:
      class: User
      local: groupId
      foreign: userId
      refClass: UserIsInGroup
 
User:
  tableName: user
  columns:
    userId:
      type: string(20)
      primary: true
    name: string(255)
    password: string(255)
  relations:
    Group:
      class: Group
      local: userId
      foreign: groupId
      refClass: UserIsInGroup
 
UserIsInGroup:
  tableName: user_is_in_groups
  columns:
    userId:
      type: string(20)
    groupId:
      type: string(32)

Untuk membuat model sekaligus membuat table di database bisa dengan menjalankan perintah berikut:

./doctrine build-all

Pastikan bahwa model sudah dibuat oleh doctrine, bisa dicek apakah model sudah ada di folder models. Begitu juga untuk tabel di database, bisa dicek langsung ke database. Doctrine juga menyediakan alat bantu untuk melakukan import data. Data harus disiapkan terlebih dahulu di folder data/fixtures dan dalam format yaml. Berikut data yang akan diimport ke table yang ada di database.

---
Group:
     admin:
       groupId: admin
       name: admin
     project:
       groupId: project
       name: project
     sudo:
       groupId: sudo
       name: sudo
     user:
       groupId: user
       name: user
User:
    dolly:
       userId: dolly
       name: Dolly Aswin Harahap
       password: e10adc3949ba59abbe56e057f20f883e
    root:
       userId: root
       name: root
       password: e10adc3949ba59abbe56e057f20f883e
UserIsInGroup:
     rootadmin:
       userId: root
       groupId: admin
     dollysudo: 
       userId: dolly
       groupId: sudo
     dollyuser: 
       userId: dolly
       groupId: user

Berikut perintah untuk import data:

./doctrine load-data

Kita sudah berhasil membuat model dan table dan juga import data dengan doctrine. Sekarang kita akan berinteraksi dengan model. Saya akan memberikan contoh kode program untuk mengambil data user dan group dengan user id dolly.

<?php
// cari data user dengan userid dolly
$user Doctrine::getTable('User')->find('dolly');
echo 
$user->userId ': ';

// cari semua group dari user dolly
foreach ($user->Group as $group) {
    echo 
$group->groupId ',';
}

echo 
PHP_EOL;
?>

Untuk menambahkan data ke tabel user bisa dengan menggunakan cara di bawah ini. Kode program berikut akan menambahkan user id programmer ke tabel user.

<?php
$user 
= new User;
$user->userId 'programmer';
$user->name   'Programmer';
$user->password md5('asdf');
// tambahkan group user dan project untuk user id programmer
$user->UserIsInGroup[0]->groupId 'user';
$user->UserIsInGroup[1]->groupId 'project';
$user->save();
?>

Berikut ini contoh kode program untuk mengubah data di tabel user. Jika dijalankan maka kode program tersebut akan mengubah password dari user id dolly dan menambahkan group id project.

<?php
user 
Doctrine::getTable('User')->find('dolly');
$user->password md5('asdf');
// menambahkan group project untuk user id dolly
$user->UserIsInGroup[2]['groupId'] = 'project';
$user->save();
?>

Berikut kode program untuk menghapus user programmer dan juga relasinya.

<?php
$user 
Doctrine::getTable('User')->find('programmer');
// hapus relasi
$user->UserIsInGroup->delete();
// hapus user
$user->delete();
?>

Migrasi
Migrasi adalah fitur yang sangat saya sukai di doctrine. Migrasi adalah proses perubahan struktur database tanpa harus merusak data yang ada pada database tersebut. Doctrine melakukan migrasi berdasarkan class migrasi yang sudah dibuat. Tapi saya lebih suka membuat class migrasi secara otomatis. Doctrine membuatnya dengan cara membandingkan file schema dengan model - model yang ada.

Saya asumsikan kita sudah membuat rilis project, yang mana tabel yang kita punya itu adalah tabel user, groups, dan user_is_in_groups. Kita ingin menambahkan field emailAddress pada tabel user untuk rilis berikutnya. Untuk membuatnya, cukup dengan menambahkan field emailAddress pada struktur tabel User di schema file.

User:
  tableName: user
  columns:
    userId:
      type: string(20)
      primary: true
    name: string(255)
    password: string(255)
    # tambahan field email address
    emailAddres: string(125)
  relations:
    Group:
      class: Group
      local: userId
      foreign: groupId
      refClass: UserIsInGroup

Setelah ditambahkan, cukup jalankan perintah berikut

./doctrine generate-migrations-diff

Perintah tersebut akan menghasilkan class migrasi, yang ada di folder migrations. Berikut isi class migrasi yang dibuat doctrine secara otomatis yang disimpan dengan nama file 1256232283_version1.php (prefix angka tersebut bisa berbeda di komputer anda)


<?php
/**
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class Version1 extends Doctrine_Migration_Base
{
    public function 
up()
    {
        
$this->addColumn('user''emailaddres''string''125', array(
             ));
    }

    public function 
down()
    {
        
$this->removeColumn('user''emailaddres');
    }
}
?>

Class migrasi sudah dibuat, dan untuk mengimplementasikan perubahan terhadap model maupun struktur tabel di database cukup dengan perintah berikut.

 
./doctrine migrate

Perintah di atas akan merubah model dan struktur database. Dan doctrine juga akan membuat tabel migration_version di database untuk mencatat versi dari migrasi yang sudah dijalankan.
Sekian dulu cerita saya tentang penggunaan doctrine, dan penjelasan di atas sudah cukup sebagai bekal anda untuk memulai bekerja dengan doctrine.

Wassalam

Comments

Kirim Komentar

Tidak akan dipublikasikan
  • Alamat web dan email dirubah menjadi hyperlink secara otomatis
  • Tag HTML yang diizinkan: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Baris baru maupun paragraph dipisahkan secara otomatis

Informasi lebih lanjut tentang format pesan