<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6231031171309673290</atom:id><lastBuildDate>Wed, 04 Sep 2024 14:06:23 +0000</lastBuildDate><category>Journal</category><category>Publication</category><category>Tutorial</category><category>Portfolio</category><category>Info</category><title>digitalXPerience</title><description></description><link>http://arthur.purnama.de/</link><managingEditor>noreply@blogger.com (Anonymous)</managingEditor><generator>Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-1745076118336181487</guid><pubDate>Wed, 20 Jan 2016 10:58:00 +0000</pubDate><atom:updated>2016-05-31T15:58:34.777+02:00</atom:updated><title>Bicara tentang Reverse Engineering</title><description>Gue rasa proyek reverse engineering termasuk proyek-proyek umum yang terjadi di industri, gak cuma software sebenernya. Dalam hubungannya dengan reverse engineering software, harus mulai dari mana? Dokumentasi bisnis prosesnya? gambar diagram-diagram dari setiap use case, modul, aktivitas, fungsi, fitur, database? Kalo kita sudah punya itu semua, apakah artinya kita pasti bisa implementasi ulang produk tersebut dan bisa jadi, setidaknya secara fungsional, sama persis?&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Ngebahas diagram dan bisnis proses. apabila kita ngejalanin bisnis proses analysis salah satu diagram yang umum dihasilkan itu ya bisnis proses diagram. Bentuknya lebih mirip activity atau flow diagram di uml daripada use case. bisnis proses gak terus langsung bisa dipakai buat bikin aplikasi. Dalam hasil analisa bisnis proses kita bisa pertimbangkan mana yang bisa di support menggunakan aplikasi (bentuknya bisa macem2 gak cuma software, mungkin alat berat, perkakas atau bangunan). Disitu kita juga bisa mempertimbangkan optimalisasi. ngelihat mana proses yang perlu dibuang atau ditambahkan. bahkan kadang disitu kita bisa melihat, menemukan atau mempertimbangkan potensi bisnis baru.&lt;br /&gt;
&lt;br /&gt;
Apakah untuk reverse engineer aplikasi tersebut perlu dibuat dokumentasi bisnis proses nya terlebih dahulu? buat gue ya belon tentu perlu. Mungkin kalo alasannya supaya ke depannya semua stakeholder (bisnis, tehnik, provider, dll) bisa berpegang sama satu informasi dasar yang sama, bisa jadi dibutuhkan. Kalo memang dibutuhkan ya time &amp; budgetnya tentu harus disesuaikan. Itupun harus diperhatikan mo seberapa yang di analisa, banyak bisnis, terutama yang baru start, punya bisnis proses yang cepat berubah karena harus menyesuaikan sama kondisi. Perusahaan2 besar banyak yang punya departemen yang bisnis prosesnya jelas bahkan kadang tersertifikasi. Kantor pemerintahan punya banyak proses yang sudah jelas. Tapi begini pun kadang bisa berubah juga. misalnya regulasi baru di reformasi birokrasi. Dan jangan lupa analisa bisnis proses itu bukan analisa untuk bikin aplikasi software loh. Dari point ini niat awal reverse engineering sebenernya masih jauh.&lt;br /&gt;
&lt;br /&gt;
So sekarang katakan lah lo dah punya informasi dasar dari bisnis proses. kira2 udah tahu aplikasi yang mo di reverse engineer itu meng cover bisnis proses bagian mana. Selanjutnya ngapain? Pada dasarnya (pada dasarnya loh ya). Bisa mulai requirement engineering. mulai lihat aplikasinya bisa apa aja, tanya sama yang pake ini fitur buat apa, kenapa bisa kok fitur ini dibikin begini? apa alasannya? itupun belon tentu semua yang pake atau yang berhubungan sama aplikasi itu tahu kenapa aplikasi itu dulu dibuat seperti itu.&lt;br /&gt;
&lt;br /&gt;
Terus gimana? hajar requirement engineering. kumpulin semua fitur, modul, dlsb, dari situ design sistim dan software arsitekturnya, kalo uda jadi kita punya dokumen beratus2/beribu2 halaman&lt;br /&gt;
penuh dengan diagram2 UML cantik. kita kasih ke developer dan mereka pasti dengan bahagianya implementasi-in buat kita karena semuanya sudah &quot;jelas&quot; terdokumentasi dengan baik di tahap awal.&lt;br /&gt;
&lt;br /&gt;
Hal seperti ini bisa saja dilakukan, tapi gue sih prediksi projekt seperti ini lebih dekat ke ambang kegagalan dari pada on time &amp; on budget. Lo gak akan pernah tahu apakah requirement yang lo kumpulin itu sudah pasti cover semua yang ada di dalam aplikasi itu. lo ga akan pernah tahu juga apakah arsitektur yang di desain itu sudah pasti sesuai dan meng cover semua requirement. Dan lo yakin developer bakal bahagia kalo kerjaannya &quot;tinggal&quot; implementasi?  Yakin pada baca ga? uda ditulis &amp; digambar panjang lebar :D buat gue ini mimpi indah :) Bisa jadi ada developer kaya gini, dan mungkin juga banyak. Tapi buat gue sih ini developer males mikir, gak punya niat belajar, dan gak suka menghadapi tantangan.&lt;br /&gt;
&lt;br /&gt;
Definisi flexible itu harus jelas. Fleksibilitas itu selalu trade off dengan kompleksitas. Buat gue, gak ada end product yang flexible. Setiap produk pasti punya tujuan, tujuan ini jadi value produkt tersebut. kalau sebuah produk dibuat untuk digunakan menciptakan produk, bisa saja kita anggap produk itu &quot;fleksibel&quot;. Tapi pada dasarnya ya enggak. produk itu memang dibuat untuk menciptakan produk. itu tujuannya dan value yang ada di dalamnya.&lt;br /&gt;
&lt;br /&gt;
Kalo lo buat aplikasi &quot;fleksibel&quot;, liat lagi, ini dibuat fleksibel karena lo bingung client/user &quot;maunya apa&quot; atau ada value yang jelas dari fleksibilitas tersebut. Kalopun &quot;maunya&quot; jelas dan terang benderang, liat lagi value nya. apa perlu buang uang, tenaga, pikiran untuk hal yang dipakai setaon belon tentu sekali misalnya. kalo itu bisnis critical ya silahkan.&lt;br /&gt;
&lt;br /&gt;
Saran gue? kerjakan bertahap secara iterativ. kumpulkan requirement berupa user stories, mo gambar UML silahkan, sesuai kebutuhan aja. libatkan arsitek dan developer dalam estimasi waktu implementasi dan delivery. tentukan most viable product / feature. tentukan release time box yang pendek (dibawah 1 bulan). Release often, get feedback often. user harus menggunakan aplikasi yang lama &amp; yang baru secara bersamaan dalam menjalankan proses bisnis. time box nya ditentukan saja bersama. tujuannya kan dengan aplikasi baru proses bisnis / output bisa berjalan seperti menggunakan aplikasi lama. Dokumentasi bisnis proses, requirement engineering, arsitektur atau dokumen teknikal lainnya bukan untuk mendukung user manual. kalo user manual dirasa belum cukup ya diperbaiki atau aktualisasi user manualnya. informasi yang dirasa perlu diketahui di masukkan. belum tentu semua orang yang mo tahu cara pake aplikasi itu perlu baca UML diagram kok.&lt;br /&gt;
</description><link>http://arthur.purnama.de/2016/01/bicara-tentang-reverse-engineering.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-4147247529959425108</guid><pubDate>Fri, 14 Dec 2012 07:20:00 +0000</pubDate><atom:updated>2014-01-03T23:25:41.448+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Info</category><title>Make it in Germany</title><description>Follow up pertemuan / gathering PHP Indonesia oktober lalu. ini gue forward email dari ppi jerman. buat kalian para IT Professional yang pengen merantau kesini :D kali aja ada yang mau... disitu juga ada link2 prosedur pendaftaran visa, cari sponsor (perusahaan) dll..&lt;br /&gt;
&lt;br /&gt;
o iya btw.. si pak mentri rösler ini sebenernya orang vietnam loh.. diangkat anak ma bule jadilah namanya &quot;rösler&quot; hehehehe... kalo gak pasti dah trang tring trong treng atau sejenisnya....&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Mungkin ada rekan, kenalan atau saudara yang berminat kerja di Jerman. Pemerintah Jerman lagi bikin kampanye nyari tenaga ahli dari luar.&lt;br /&gt;
&lt;br /&gt;
Salah satu program nya, bikin portal &lt;a href=&quot;http://www.make-it-in-germany.com/en/making-it/i-made-it/&quot; target=&quot;_blank&quot;&gt;&quot;Make It In Germany&quot;&lt;/a&gt; yg memuat info ttg Jerman dan di kasih bumbu dg video clips ttg pekerja asing di Jerman.&lt;br /&gt;
&lt;br /&gt;
Saya manfaatin kesempatan ini sekalian utk promosi SDM Indonesia, bahwa di Indonesia banyak tenaga ahli juga, bukan cuman ahli korupsi, yg selama ini di kenal di luar.&lt;br /&gt;
&lt;br /&gt;
Ternyata Pak Menteri Rösler setelah lihat film tsb, menetapkan pilot project utk &lt;a href=&quot;http://www.bmwi.de/English/Navigation/Press/press-releases,did=523250.html&quot; target=&quot;_blank&quot;&gt;nyari tenaga ahli&lt;/a&gt; dari Indonesia, Vietnam dan India.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ada juga berita pendamping di majalah Deutschland. &lt;a href=&quot;https://www.deutschland.de/en/node/1629&quot; target=&quot;_blank&quot;&gt;Majalahnya kemenlu Jerman&lt;/a&gt; yang di sebar di kedutaan besar Jerman di seluruh dunia.&lt;br /&gt;
&lt;br /&gt;
Semoga bermanfaat.</description><link>http://arthur.purnama.de/2012/12/make-it-in-germany.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7208511110804066536</guid><pubDate>Sat, 20 Oct 2012 21:32:00 +0000</pubDate><atom:updated>2014-01-03T23:32:34.746+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Presentasi Gathering / Meetup PHP Indonesia</title><description>Presentasi dari Gathering / Meetup PHP Indonesia bisa dibaca di Slidshare.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src=&quot;http://www.slideshare.net/purnama/slideshelf&quot; width=&quot;490px&quot; height=&quot;470px&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:none;&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt;&lt;/iframe&gt;</description><link>http://arthur.purnama.de/2012/10/presentasi-gathering-meetup-php.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-613949076022740457</guid><pubDate>Fri, 12 Oct 2012 00:03:00 +0000</pubDate><atom:updated>2014-01-03T23:24:35.820+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Info</category><title>Undangan Gathering / Meetup PHP Indonesia</title><description>Forward undangan dari Milis PHP Indonesia waktu gue lagi pulang jerman.&lt;br /&gt;
&lt;br /&gt;
Komunitas pegiat PHP di Indonesia yang berlokasi di Jakarta mengadakan gathering di kantor PT. Rynet.&lt;br /&gt;
&lt;br /&gt;
Tanggal : Hari Kamis, Tgl 18 Oktober 2012&lt;br /&gt;
Waktu : Pokoknya setelah office hours selesai, langsung aja capcus ke TKP. Gak pake Lama!&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
TKP :&lt;br /&gt;
PT Rynet Cipta Teknologi Kompleks Ruko Golden Plaza(D&#39;Best) Blok D-18&lt;br /&gt;
Jl. RS Fatmawati No.15&lt;br /&gt;
Jakarta 12420, INDONESIA&lt;br /&gt;
&lt;br /&gt;
Materi Diskusi :&lt;br /&gt;
--- Study Banding dengan Pegiat PHP di Germany&lt;br /&gt;
--- Application Design based on PHP&lt;br /&gt;
--- Success Story&lt;br /&gt;
--- Cara mendapatkan beasiswa ke Germany&lt;br /&gt;
--- Cara jitu mendapatkan wanita idaman (Pagi para Jomblowers)&lt;br /&gt;
&lt;br /&gt;
Pakaian : Bebas, Rapi, boleh wangi boleh tidak wangi, dan nyaman dipakai.&lt;br /&gt;
&lt;br /&gt;
Itulah yang bisa saya sampaikan pada hari ini di pagi ini di hari jumat ini. Ini serius lhooo dan diharapkan kehadiran kawan-kawan milis nanti pada event ini.</description><link>http://arthur.purnama.de/2012/10/undangan-gathering-meetup-php-indonesia.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-3986604970948911114</guid><pubDate>Thu, 03 May 2012 06:45:00 +0000</pubDate><atom:updated>2014-01-03T20:35:33.788+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Dependency Injection &amp; Inversion Of Control</title><description>Dalam kesempatan ini gue pengen ngebahas tentang dependency injection dan inversion of control karena gue sempet melihat di milis ada yang masih belum mengerti bedanya. Bahkan ada yang mengira bahwa DI atau IOC itu berbeda dengan Object Oriented Programming.&lt;br /&gt;
&lt;br /&gt;
Di milis bahkan ada yang sudah menjawab dan jawaban tersebut, meskipun menurut gue belum lengkap, sudah menuju ke arah yang benar.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot;&gt;&lt;/script&gt;&lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;&lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all()&lt;/script&gt;&lt;br /&gt;
Thread lengkapnya bisa dibaca &lt;a href=&quot;http://groups.yahoo.com/neo/groups/id-php/conversations/topics/50203&quot; target=&quot;_blank&quot;&gt;di milis&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Gue kutip jawaban dari mas Herloc disini:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Intinya sih semua dependency dari kelas tersebut dilakukan diluar, trus dimasukkan (inject) ke kelas tersebut melalui constructor atau setter (setModel misalnya)... Lebih ribet? Yup, namun kalo mau ganti2 implementasi dari dependency jauh lebih enak (database vs dummy)...&lt;/blockquote&gt;&lt;br /&gt;
Contoh yang diberikan:&lt;br /&gt;
Cara biasa tanpa Dependency Injection&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class Person_Model_Database
{
  function findAll()
  {
    $sql = &#39;SELECT * FROM t_people&#39;;
    
    return $db-&gt;queryAll($sql);
  }
}

class Person_Service
{
  private $model;
  
  function __construct()
  {
    $this-&gt;model = new Person_Model_Database;
  }
  
  function findAll()
  {
    // hak akses, dst
    
    return $this-&gt;model-&gt;findAll();
  }
}

$service = new Person_Service;
$people = $service-&gt;findAll();
&lt;/pre&gt;&lt;br /&gt;
Cara Dependency Injection&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;interface Person_Model_Interface
{
  function findAll();
}

class Person_Model_Database
  implements Person_Model_Interface
{
  function findAll()
  {
    $sql = &#39;SELECT * FROM t_people&#39;;
    
    return $db-&gt;queryAll($sql);
  }
}

class Person_Model_Dummy
  implements Person_Model_Interface
{
  function findAll()
  {
    return array(&#39;Gw&#39;, &#39;Lo&#39;, &#39;End&#39;);
  }
}

class Person_Service
{
  private $model;
  
  function __construct(Person_Model_Interface $model)
  {
    $this-&gt;model = $model;
  }
  
  function findAll()
  {
    // hak akses, dst
    
    return $this-&gt;model-&gt;findAll();
  }
}

// ambil data dari database
$dbModel = new Person_Model_Database;
$service = new Person_Service($dbModel);
$people = $service-&gt;findAll();

// ambil data bohongan dari array, gara2 yg bikin DB belom kelar2
$dummyModel = new Person_Model_Dummy;
$service = new Person_Service($dummyModel);
$people = $service-&gt;findAll();
&lt;/pre&gt;&lt;br /&gt;
menurut gue contoh mas herloc itu adalah jawaban yang tepat untuk Inversion of Control. tapi belum dependency injection.&lt;br /&gt;
&lt;br /&gt;
gue ambil contoh kita punya 2 Service ya..&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace app\service
  
  class Applicants{
    
    private $person;
    function __construct(model\interfaces\Person $person)
      
    {
      $this-&gt;person = $person;
    }
  }

namespace app\service
  
  class ClassRoom{
    
    private $person;
    
    private $room;
    
    function __construct(model\interfaces\Person $person,
                         model\interfaces\Room $room)
      
    {
      $this-&gt;person = $person;
      $this-&gt;room = $room;
    }
  }
&lt;/pre&gt;&lt;br /&gt;
maka untuk menciptakan 2 kelas tersebut kita harus menciptakan 2 kelas konkrit person dan room dimana nantinya kita masukkan ke konstruktornya Applicants dan ClassRoom&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$personModel= new model\Person;
$roomModel = new model\Room;
$applicantsService= new app\service\Applicants($personModel);
$classRoomService = new app\service\ClassRoom($personModel. $roomModel)
&lt;/pre&gt;&lt;br /&gt;
fine.. ini baru dua.. gimana kalo dalam satu bisnis logik lo butuh 5 service sekaligus, dimana masing2 service bisa memiliki 3 model atau lebih yg berbeda? bakal pegel nyiptain modelnya satu2 dan masukin ke service class.&lt;br /&gt;
&lt;br /&gt;
disini kita bisa menggunakan Factory Pattern atau sebangsanya&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace util;

class Factory{
  
  public static function createApplicants(){
    $personModel= new model\Person;
    return new app\service\Applicants($personModel);
  }
  
  public static function createClassRoom(){
    $personModel= new model\Person;
    $roomModel = new model\Room;
    return new app\service\Applicants($personModel, $roomModel);
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
jadi kita tinggal:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$applicantsService = util\Factory::createApplicants();
$classRoomService = util\Factory::createClassRoom();
&lt;/pre&gt;&lt;br /&gt;
Okay.. fine.. ini sudah mulai &quot;dependecy injection&quot;.. kan kita punya class dimana kita bisa meng &quot;inject&quot; semua object yang kita mau.&lt;br /&gt;
&lt;br /&gt;
Problem berikutnya adalah.. apabila kita punya 10 service yang butuh misalnya Person model, maka di factory class kita bisa kemungkinan memiliki 10 method dimana kita harus &quot;inject&quot; konkrit class Person 10 kali ke masing2 service tersebut. ini gak terlihat bakal mudah di maintain..&lt;br /&gt;
&lt;br /&gt;
coba bayangkan, kalo kita punya satu line of code yang isinya kira2...&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&quot;untuk semua kelas yang memiliki dependency model\interfaces\Person, inject konkrit class model\Person&quot;&lt;/blockquote&gt;&lt;br /&gt;
dalam bentuk code mungkin bisa ditulis:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$container-&gt;bind(&#39;model\interfaces\Person&#39;)-&gt;to(&#39;model\Person&#39;);
&lt;/pre&gt;&lt;br /&gt;
kita gak butuh lagi inject satu2, kita gak butuh lagi Factory method seperti diatas. kita hanya punya satu Factory class dengan satu method &quot;getInstance&quot; (atau sejenisnya)&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$applicantsService = util\Factory::getInstance(&quot;app\service\Applicants&quot;);
$classRoomService = util\Factory::getInstance(&quot;app\service\ClassRoom&quot;);
&lt;/pre&gt;&lt;br /&gt;
Problem berikutnya adalah.. (problem melulu... kapan beresnya...) gimana kalo model Person di Applicants gak sama dengan di ClassRoom? bukannya maka dari itu kita punya interface? :D misalnya Applicants akan menggunakan model\Person, dan ClassRoom menggunakan model\Student dimana Person dan Student sama2 implements model\interface\Person.&lt;br /&gt;
&lt;br /&gt;
Statement binder diatas kan cuma berlaku &quot;untuk semua kelas&quot; yang memiliki dependency model\interfaces\Person.&lt;br /&gt;
&lt;br /&gt;
untuk kasus khusus seperti ini solusinya bisa bermacam2. seperti misalnya menggunakan xml/yaml seperti symfony atau spring (java)&lt;br /&gt;
symfony yaml:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;service.applicants:
  class: app\service\Applicants
    calls:
      - [ setPerson, [ @... ] ]
service.classRoom:
  class: app\service\ClassRoom
    calls:
      - [ setPerson, [ @... ] ]
      - [ setRoom, [ @... ] ]
&lt;/pre&gt;&lt;br /&gt;
spring xml:&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;bean id=&quot;person&quot; class=&quot;model.Person&quot; /&amp;gt;
&amp;lt;bean id=&quot;student&quot; class=&quot;model.Student&quot; /&amp;gt;
&amp;lt;bean id=&quot;room&quot; class=&quot;model.Room&quot; /&amp;gt;

&amp;lt;bean id=&quot;applicants&quot; class=&quot;app.service.Applicants&quot;&amp;gt;
    &amp;lt;property name=&quot;person&quot; ref=&quot;person&quot; /&amp;gt;
&amp;lt;/bean&gt;

&amp;lt;bean id=&quot;classRoom&quot; class=&quot;app.service.ClassRoom&quot;&amp;gt;
    &amp;lt;property name=&quot;person&quot; ref=&quot;student&quot; /&amp;gt;
    &amp;lt;property name=&quot;room&quot; ref=&quot;room&quot; /&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Apakah kita cuma bisa inject object? DI/IOC framework yang yahud gue rasa bisa inject semuanya.. dari primitive (int, string, bool, array) sampe object .. pokoknya apa yang dibutuhkan property sebuah kelas.. bisa kita inject. Ribet itu sebenernya hanya di awal waktu mempersiapkan semuanya.. kalo sudah masuk maintainance.. ini semua lebih terbaca dan lebih mudah refactoring nya.. belum lagi kalo kita mo Test Driven Development.. dengan membuat applikasi kita IOC.. kita sudah memotong2 setiap kelas dan method menjadi unit2 yang bisa kita test tanpa &quot;dependency&quot; dari kelas atau method lain.&lt;br /&gt;
&lt;br /&gt;
Apa lagi yang framework ini bisa? framework yang yahud juga punya &quot;scope&quot; :D .. kalo di PHP gue bakal butuh &quot;Request&quot;, &quot;Singleton&quot;, dan &quot;Session&quot;. di java ada lebih dari ini (misalnya Application scope). Dimana standard scope adalah &quot;Request&quot;.&lt;br /&gt;
&lt;br /&gt;
apa enaknya scope? bayangin coba, kalo kita harus maintain semua array atau isi $_SESSION.. makin gede aplikasi, makin bingung kita.. &quot;username&quot; udah kepake belum ya.. apa yang kepake itu &quot;user&quot; atau &quot;userid&quot;.. eh tapi gue liat di debug tadi ada &quot;id&quot; apaan tuh ya? siapa yang pake?...&lt;br /&gt;
&lt;br /&gt;
kita bisa saja membuat kelas model\Login yang kita deklarasikan scopenya sebagai session. jadi waktu di inject ke kelas lain, informasi yang ada dalam object model\Login tersebut akan ada/sama selama session belum expired. Dan apabila ada model lain yang juga dalam scope session misalnya model\Person. meskipun punya property yang kebetulan sama (name misalnya) kita gak perlu pusing kalo informasi tersebut tumpang tindih.. karena kita terimanya kan sudah berupa object.. dan meniympan dan membaca dari session sudah diatur sama frameworknya.&lt;br /&gt;
&lt;br /&gt;
Singleton pun begitu.. kalo kita punya object DataAccess misalnya.. kita tentunya pengen sepanjang http request object ini cuma pegang satu koneksi ke database, tidak setiap kali kita panggil untuk diinject dia menciptakan object dan connection yang baru.&lt;br /&gt;
&lt;br /&gt;
semoga memberikan pencerahan. :D</description><link>http://arthur.purnama.de/2012/05/dependency-injection-inversion-of.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7866471280676754569</guid><pubDate>Fri, 08 Apr 2011 04:17:00 +0000</pubDate><atom:updated>2014-01-03T18:18:18.214+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Rekaman EPHPC Webinar Unit Testing</title><description>Video Webinar kemarin udah bisa diakses.&lt;br /&gt;
&lt;br /&gt;
silahkan dilihat. jangan lupa feedbacknya ya... link feedback formulir juga terlampir :D&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;blockquote&gt;Dear All,&lt;br /&gt;
&lt;br /&gt;
Thank you for attending our webinar session on PHPUnit presented by Arthur Purnama, ZCE a couple of days ago. And we just want to inform you that you can now view the recorded version of our webinar on:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.enterprisephpcenter.com/&quot;&gt;http://www.enterprisephpcenter.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Recorded Webinar: &lt;a href=&quot;http://goo.gl/FJrfT&quot;&gt;Unit Testing – Merangkak Menuju Pengembangan Aplikasi PHP yang Berkualitas dan Tahan Banting&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Don&#39;t forget fill in the &lt;a href=&quot;http://goo.gl/K9SV8&quot; target=&quot;_blank&quot;&gt;survey form&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And support us by blogging/tweeting/write/discuss on the mailing list&lt;br /&gt;
or do anything about our webinar, and use the hashtag #ephpc-phpunit.&lt;br /&gt;
&lt;br /&gt;
Warm Regards&#39;&lt;br /&gt;
Happy PHP&#39;ing&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
Enterprise PHP Center Team&lt;/blockquote&gt;&lt;br /&gt;
Presentasi dapat dilihat di &lt;a href=&quot;https://www.slideshare.net/purnama/unit-testing-7557247&quot; title=&quot;Unit testing&quot; target=&quot;_blank&quot;&gt;Slideshare&lt;/a&gt;.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe src=&quot;http://www.slideshare.net/slideshow/embed_code/7557247&quot; width=&quot;427&quot; height=&quot;356&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px&quot; allowfullscreen&gt; &lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
Youtube Version:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe width=&quot;480&quot; height=&quot;360&quot; src=&quot;//www.youtube.com/embed/GyGyobbY3b8&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;
Vimeo Version: &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;375&quot; mozallowfullscreen=&quot;&quot; src=&quot;//player.vimeo.com/video/22086815&quot; webkitallowfullscreen=&quot;&quot; width=&quot;500&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;/div&gt;</description><link>http://arthur.purnama.de/2011/04/rekaman-ephpc-webinar-unit-testing.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-3281677636732446633</guid><pubDate>Thu, 10 Mar 2011 20:32:00 +0000</pubDate><atom:updated>2014-01-03T23:24:55.086+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Info</category><title>Undangan Webinar bertema Unit Testing</title><description>Minggu lalu om Rama dari Rynet follow up kesediaan gue untuk jadi pembicara di webinar. Acara webinar ini difasilitasi oleh om Rama secara gratis buat komunitas PHP.&lt;br /&gt;
Gue bilang dengan senang hati gue bersedia. Gue akan berusaha mempersiapkan sebaik-baiknya. om Rama juga sudah janji untuk membantu dari segi teknisnya :) Semoga tidak ada hambatan.&lt;br /&gt;
&lt;br /&gt;
Dengan ini gue mo mengundang teman-teman untuk menghadiri acara ini... cuma modal internet dan browser loh... jadi adil buat teman-teman yang di daerah juga :D siapa saja bisa ikut. gak peduli tempat.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Jangan takut ngeliat judul thema nya. thema nya gak berat kok, dan sebenarnya cukup basi... dan gue akan berusaha membuatnya berupa introduction jadi bisa diikuti semua.&lt;br /&gt;
&lt;br /&gt;
So hadir ya.. gue bakal senang sekali kalo banyak yang hadir.. semoga tanggal dan waktunya gak jelek :)&lt;br /&gt;
&lt;br /&gt;
Informasi acaranya gue copy paste, atau bisa dilihat &lt;a href=&quot;http://goo.gl/AwCV0&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Terima kasih sekali lagi om Rama buat fasilitasnya :P&lt;br /&gt;
&lt;br /&gt;
Unit Testing - Merangkak Menuju Pengembangan Aplikasi PHP yang&lt;br /&gt;
Berkualitas dan Tahan Banting&lt;br /&gt;
Start Date: Apr 06, 2011&lt;br /&gt;
Start Time: 13.00 WIB&lt;br /&gt;
End Time: 14.30 WIB&lt;br /&gt;
&lt;br /&gt;
Speaker : Arthur Purnama, ZCE (Zend Certified Engineer in PHP5)&lt;br /&gt;
Current Job: Technology Consultant at Cirquent GmbH&lt;br /&gt;
&lt;br /&gt;
Synopsis :&lt;br /&gt;
Dalam mengembangkan aplikasi, setiap orang pasti akan menguji/mengetest apakah aplikasi yang ditulis itu jalan atau tidak. Entah apapun itu atau bagaimanapun cara mengujinya. Dengan semakin kompleks atau semakin pentingnya satu aplikasi (apalagi buat di jual atau dipakai banyak orang), maka menguji kualitas atau mendeteksi kesalahan dalam aplikasi menjadi semakin rumit. Berbagai macam metode, langkah maupun tehnik diperkenalkan untuk dapat menguji aplikasi dengan mudah, efektif dan transparan. Dalam kesempatan ini akan dibahas satu bagian dari Software Testing, yaitu Unit Testing. Dimulai dari apa itu Unit Testing, apa bedanya dengan test yang lain (apa yang termasuk unit testing apa yang tidak). Keuntungan apa yang bisa didapat, apabila Unit Testing diterapkan dalam pengembangan aplikasi. Kerugian apa yang akan dihadapi jika tidak diterapkan. Strategi apa yang harus diperhatikan dalam menerapkannya. Hingga, tentunya, bagaimana cara menerapkan Unit Testing dalam proyek aplikasi kita.&lt;br /&gt;
&lt;br /&gt;
Pembahasan tema ini akan menggunakan (atau memperkenalkan buat yang belon kenal) PHPUnit sebagai salah satu Unit Testing Framework dalam bahasa pemrograman PHP. Meskipun begitu Unit Testing memiliki pemahaman fundamental yang sama, sehingga Tema ini pada dasarnya juga bisa diikuti oleh mereka yang menulis aplikasi tidak dalam bahasa tersebut.&lt;br /&gt;
&lt;br /&gt;
Duration : 60 minutes presentation + 15 minutes Q&amp;A&lt;br /&gt;
Language : Bahasa Indonesia&lt;br /&gt;
&lt;br /&gt;
Arthur Purnama, ZCE :&lt;br /&gt;
Bekerja sebagai Konsultan IT, Divisi Portal Solutions, Cirquent GmbH, München - Jerman&lt;br /&gt;
Tinggal di Frankfurt am Main, Jerman. Menikmati pengembangan aplikasi web menggunakan PHP dan Java, dan senang berbagi pengalaman nya di .... blog? hmmm... di mailing list user group indonesia :D. Kalo lagi bosen, suka belajar masak makanan indo di dapur, atau keluar foto - foto gak jelas :)&lt;br /&gt;
&lt;br /&gt;
Address: http://rynetgroup.webex.com&lt;br /&gt;
</description><link>http://arthur.purnama.de/2011/03/undangan-webinar-bertema-unit-testing.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-6950899985905793592</guid><pubDate>Wed, 02 Mar 2011 08:01:00 +0000</pubDate><atom:updated>2014-01-03T14:19:33.995+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><title>Enterprise PHP ???</title><description>Pada dasarnya aplikasi sudah bisa dibilang enterprise apabila dia bisa dipakai sebagai sebuah solusi dalam suatu perusahaan. gak peduli besar kecilnya. Dengan ini aplikasi blog paling murahan sekalipun apabila dianggap layak dan cukup untuk memenuhi kebutuhan sebuah perusahaan mempresentasikan existensinya di internet. bisa dibilang &quot;enterprise software&quot;.&lt;br /&gt;
&lt;br /&gt;
Hanya saja kebutuhan perusahaan umumnya tidak berhenti disitu saja. Jaman sekarang begitu banyak proses-proses bisnis dalam perusahaan (gak peduli apa usahanya) bisa dibuat lebih efisien menggunakan IT. Kemampuan software untuk bisa mengimplementasikan dan mengintegrasikan proses-proses bisnis ini yang membuat mereka di cap &quot;enterprise&quot;.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Definisi panjang lebar tentang aplikasi enterprise bisa dilihat di &lt;a href=&quot;http://en.wikipedia.org/wiki/Enterprise_software&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Tapi itu aja belon cukup. Ambil contoh lah bikin Aplikasi buat POS. bisnis proses POS perusahaan A belum tentu sama dengan perusahaan B. kalo lo mo jual software elo harus bisa di &quot;costumize&quot; kalo perlu tanpa perjuangan besar (koding, compile, deploy dsb). membuat sebuah aplikasi yang meng cover segala macam bentuk bisnis proses membawa satu tantangan kompleksitas tersendiri dalam mengembangkan aplikasinya. kalo bisa sampe sini nampaknya layak kita cap &quot;enterprise&quot;&lt;br /&gt;
&lt;br /&gt;
Oh tapi gue rasa masih belum cukup sampe disitu.&lt;br /&gt;
&lt;br /&gt;
Ambil contoh. Bang Jupri buka Toko Roti. Bang Jupri yang pergi belanja pagi - pagi, Bang Jupri yang panggang kuenya, dan Bang Jupri juga yang jual depan rumah. Bang Jupri gak muluk-muluk. butuh aplikasi buat akuntansi kecil kecilan aja, buat sekedar kontrol duit keluar masuk sama ngitung penghasilan.&lt;br /&gt;
&lt;br /&gt;
Roti bang Jupri ternyata enak banget. belon sampe siang sudah abis mulu. akhirnya bang jupri manggil pegawai 2 orang buat bantuin dia. sekarang bang jupi mulai bayar gaji :)&lt;br /&gt;
&lt;br /&gt;
Pegawai 2 orang ternyata gak cukup. sekarang bang jupri mulai beli mobil untuk angkut belanjaan, beli mesin panggang yang gedean supaya produksi bisa meningkat, dan beli kulkas buat nyimpen sisa bahan. sekarang bang jupi harus belajar ngontrol resource nya. :)&lt;br /&gt;
&lt;br /&gt;
Saking lakunya, banyak pelanggan minta dibukain toko roti dekat kompleknya. dan bang jupri liat banyak pelanggannya juga yang dari komplek itu. akhirnya bang jupri expand usahanya. buka toko roti satu lagi pegawai bang jupri jadi banyak. Belanja ke pasar udah bukan solusi. bang jupri bikin kontrak sama supplier bahan dasar. sekarang bang jupri harus kontrol suppliernya supply sesuai jumlah yang dibutuhkan dan puffer di gudang cukup.. akhirnya bang jupri belajar logistik :D&lt;br /&gt;
&lt;br /&gt;
Roti bang jupri beken kemana mana... tapi buka cabang gak selalu solusi utama. akhirnya bang jupri menyadari existensi internet. bang jupri expand ke web :D. bang jupri buka toko roti online. bang jupri kerja sama, dengan financial institute untuk memastikan kenyamanan berbelanja buat pelanggannya, bang jupri kerja sama dengan Jasa kiriman untuk memastikan barang yang dibeli pelanggan tiba dengan selamat.&lt;br /&gt;
&lt;br /&gt;
Begitu bekennya roti bang jupri, sampe pelanggannya minta dibikinin roti yang lain, selain roti yang selama ini bang jupri jual. akhirnya bang jupri buka satu departemen yang khusus untuk menciptakan resep resep roti baru. bahkan departemen ini juga bekerja untuk mengoptimalkan proses pembuatan roti. departemen ini bahkan tidak hanya menciptakan roti roti unik, tapi juga menjadi inovator mesin mesin pemanggang roti...&lt;br /&gt;
&lt;br /&gt;
STOOOOP....&lt;br /&gt;
&lt;br /&gt;
wah ngalor ngidul...&lt;br /&gt;
&lt;br /&gt;
ok. bisa gak sebuah aplikasi berkembang seperti layaknya bisnis berkembang? ataukah setiap kali bisnis berkembang bang jupri harus nge drop aplikasinya dan beli atau pakai aplikasi lain? kenapa gak pakai satu aplikasi, yang bisa ikut berkembang.. seiring berkembangnya perusahaan? kalau kecil.. ya kecil. sampai tiba saatnya saya butuh POS, tinggal tambahin POS, tiba saatnya saya butuh ERP. tambahin ERP, saya butuh Logistik, tambahin logistik. butuh crm? tambahin crm. Online shop?.. tambahin online shop... dst....&lt;br /&gt;
&lt;br /&gt;
Kalo perlu master datanya sama. gak perlu migrasi-migrasi...&lt;br /&gt;
&lt;br /&gt;
Kalo bisa.. ini baru gue cap &quot;enterprise&quot;&lt;br /&gt;
&lt;br /&gt;
Apakah PHP bisa?&lt;br /&gt;
&lt;br /&gt;
YA.. bisa-bisa saja kenapa nggak... tapi effortnya sejauh mana dulu. dibandingin sama aplikasi lain yang &quot;tinggal costumize&quot; dari raksasa seperti ibm, oracle, sap, to name a few... ingat biaya developing from scratch sama biaya costumize plus license gak sebanding. kompleksitas bisnis proses meningkat. kompleksitas pengembangan bisa meningkat exponensial. ini kadang hasil akhirnya gak menguntungkan.&lt;br /&gt;
&lt;br /&gt;
Pake framework apa?&lt;br /&gt;
&lt;br /&gt;
framework bakal bukan jadi pertanyaan disini. tapi seperti ditulis diatas bagaimana aplikasi kita bisa scale.. sama-sama dengan perusahaannya. bisa jadi kalo mo konsisten di PHP. framework hanya menjadi salah satu pertimbangan saja. pertimbangan lainnya bisa di databasenya apa, hardwarenya apa, perlu cache gak.. data centernya dimana.. dlsb...&lt;br /&gt;
&lt;br /&gt;
bicara tentang framework dan kerja yang efisien. buat gue belum ada satu framework php yang merupakan &quot;the&quot; framework. Zend Framework bisa jadi punya banyak tools yang tinggal dipakai. tapi masih banyak hal yang Zend tidak punya. Ini bisa saja dipecahkan dengan mengkombinasikan Framework yang ada.. belum lagi IDE nya? bagaimana dengan Continous Integration? Testing? Work Methodology? dlsb...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So... Buat kalian yang bertanya tentang Enterprise... mungkin tanya balik.. diri kalian, atau bos kalian.. atau siapa saja dimana pertanyaan itu muncul... &quot;enterprise&quot; itu maksudnya apa? Sebenernya &quot;masalah&quot; nya itu dimana? apakah bener2 butuh yang seperti itu?&lt;br /&gt;
&lt;br /&gt;
kadang lo gak selalu menghadapi Owner.. CEO atau boss.. bisa jadi cuma manager yang pengen ngabisin budget taon ini. bisa jadi pegawai yang 5 taon kedepan juga belon tentu di perusahaan itu. maka buat dia juga selama aplikasi tersebut bisa jadi solusi untuk x tahun kedepan. it will be enterprise enough :D</description><link>http://arthur.purnama.de/2011/03/enterprise-php.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7453755907769632957</guid><pubDate>Wed, 01 Dec 2010 17:33:00 +0000</pubDate><atom:updated>2014-01-03T17:41:14.902+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Struktur File, Modul dan Komponen dalam Aplikasi</title><description>Di milis id-php ada yang sering kali kesulitan dalam membuat aplikasi yg benar2 loose coupled, walau sudah bikin pake framework pun kayaknya masih belum puas terhadap aplikasi yg di buat. Seringkali ketika membuat modul atau komponen baru, dan dipasangkan ke aplikasi saya tadi, ada saja bagian yang harus disentuh didalam coding.&lt;br /&gt;
&lt;br /&gt;
Pertanyaannya bagaimana kita bisa membuat antar modul atau komponen bisa saling berkomunikasi tanpa memiliki ketergantungan antar modul tersebut.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot;&gt;&lt;/script&gt;&lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;&lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all()&lt;/script&gt;&lt;br /&gt;
Thread lengkapnya bisa dibaca langsung di &lt;a href=&quot;http://groups.yahoo.com/neo/groups/id-php/conversations/topics/39384&quot; target=&quot;_blank&quot;&gt;milis&lt;/a&gt;. Disini gue ingin menuliskan pandangan gue yang juga gue post disana.&lt;br /&gt;
&lt;br /&gt;
Karena yang bertanya sedang bekerja menggunakan yii framework, banyak pertanyaan yang menuju solusi spesifik di yii framework. Sebelum gue coba jawab, gue disclaimer dulu ya... gue bukan pengguna yii... untuk mencoba mengerti kasus lo, gue coba baca-baca dokumentasi yii.. dan dari situ gue coba mengerti gimana arsitektur aplikasinya. gue bakal berusaha menjawab pertanyaan lo dengan tidak mengesampingkan yii sebagai framework yang udah lo pakai. kalau elo atau teman2 lain ada melihat kesalahan pengertian gue terhadap arsitektur yii.. silahkan dikoreksi..&lt;br /&gt;
&lt;br /&gt;
gue gak akan membahas yii dari sisi technical seperti.. gimana caranya make x atau cara ngejalanin y atau sejenisnya.. tapi lebih ke sisi arsitektur.. tenang... bukan berarti gue gak bahas sama sekali technicalnya.. hanya saja gue akan berusaha kasih contoh atau link.. alasannya gue gak bahas technicalnya dalam2.. ya karena itu... gue gak perna pake yii.. mungkin elo yang biasa pake bisa lebih tahu dari gue.&lt;br /&gt;
&lt;br /&gt;
so gue mulai ya...&lt;br /&gt;
&lt;br /&gt;
ada 2 hal berbeda sebenarnya dari pertanyaan elo. ini mau gue jelaskan terlebih dahulu. supaya gak bingung. yang pertama adalah Arsitektur yang baik dimana kita dapat memiliki komponen/kelas/property yang reuseable antar modul. yang kedua adalah Arsitektur untuk bikin modul yang pluginable.&lt;br /&gt;
&lt;br /&gt;
Ini 2 hal berbeda. dan membuat pembangunan aplikasi memiliki tujuan dan arsitektur yang berbeda. kalo aplikasinya &quot;pluginable&quot; itu artinya aplikasi elo sebenernya bisa ditambahkan third-party komponen (komponen yang ditulis orang lain diluar project aplikasi elo sendiri). Lo jadi harus publikasiin spesifikasi interface elo, supaya orang bisa bikin plugin buat aplikasi elo. dan aplikasi elo sendiri harus dibuat sedemikian rupa supaya siap untuk menerima plugin tersebut entah apa itu pluginnya. karena pada dasarnya bisa apa saja, suka2 orang yang nulis plugin nya.&lt;br /&gt;
&lt;br /&gt;
Kalo gue bole ambil contoh yang dikasih bro Indra, menurut disitu ada beberapa hal yang menyimpang dari konsep plugin itu sendiri. biasanya arsitektur plugin itu gak akan masukin komponen nya langsung kedalam aplikasi utama (copy paste ke directory yang dipakai untuk ngembangin aplikasi utama), umumnya aplikasi utama punya satu directory atau satu pool buat naro plugin, jadi terpisah baik secara fisik maupun konteks dari aplikasi utama. hal yang lain terjadi pada relasi antar object yang &quot;pseudo&quot; dinamis. memang objectnya dinamis. tapi foreign key nya nggak (&#39;user_id&#39;). artinya kalo kebetulan di database atau di object model foreign_key nya bukan &#39;user_id&#39;, tapi misalnya &#39;person_id&#39; plugin nya gak jalan. ya ini memang bisa diperbaiki hingga semuanya dinamis.. terus tulis spesifikasinya dan lain sebagainya.. tapi Gue pribadi gak gitu yakin kalo ini tujuan dari aplikasi elo.&lt;br /&gt;
&lt;br /&gt;
Kalo baca dari tulisan elo. sepertinya lo cuma butuh untuk tahu gimana Arsitektur yang baik supaya kelas-kelas atau module elo bisa berkomunikasi atau digunakan satu sama lain tanpa memiliki ketergantungan yang erat (loose coupled). semoga asumsi gue benar. dan gue akan menjelaskan tentang ini saja. karena kalo musti ngebahas bikin aplikasi pluginable.. bisa gak selesai-selesai :D&lt;br /&gt;
&lt;br /&gt;
kalo lihat dari arsitekturnya yii framework. yii sudah memberikan kesempatan buat para penggunanya membuat aplikasi yang loose coupled dan high cohesive. gue jelaskan sekali lagi prinsipnya. sebuah kelas/komponen yang baik itu seharusnya loose coupled.. artinya memiliki ketergantungan yang minim antara satu dengan yang lainnya. ketergantungan itu pasti ada, tapi dibuat seminimal mungkin. sebuah kelas/komponen yang baik itu seharusnya high cohesiv.. artinya memiliki satu tujuan atau maksud eksistensi yang jelas.&lt;br /&gt;
&lt;br /&gt;
kalau melihat contoh code yang lo kasih, code elo yang pasti gak kohesiv, karena ada fungsi untuk generate html code di dalam sebuah kelas yang tujuannya adalah sebuah object model.&lt;br /&gt;
&lt;br /&gt;
Dalam hal ini gue pribadi tetep gak ngerti alasan dibalik itu. apa alasannya lo naro fungsi buat generate html di dalam kelas model? gue baca di dokunya, yii punya &lt;a href=&quot;http://www.yiiframework.com/doc/guide/1.1/en/basics.component&quot; target=&quot;_blank&quot;&gt;&quot;component&quot;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
kalo liat contohnya kayak gini &lt;a href=&quot;http://code.google.com/p/yii/source/browse/trunk/demos/blog/protected/components/TagCloud.php&quot; target=&quot;_blank&quot;&gt;[TagCloud]&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
bukankah itu satu code snippet yang generate html untuk digunakan dimana saja? menurut gue konsep ini cukup bagus dan tentunya reuseable. kenapa gak pake ini? ini sudah out of the box dari yii.&lt;br /&gt;
&lt;br /&gt;
lo membuat module dalam yii framework. dengan contoh module siswa dan module kota&lt;br /&gt;
&lt;br /&gt;
kalo baca dari dokumentasinya yii tentang &lt;a href=&quot;http://www.yiiframework.com/doc/guide/1.1/en/basics.module&quot; target=&quot;_blank&quot;&gt;module&lt;/a&gt; maka masing-masing module itu seperti aplikasi yang berdiri sendiri (punya view nya sendiri, punya controllernya sendiri, modelnya sendiri, dan lain-lain sendiri)&lt;br /&gt;
&lt;br /&gt;
berarti.. dalam bayangan gue struktur file elo kayak gini&lt;br /&gt;
&lt;pre class=&quot;brush: bash, highlight: [10,23]&quot;&gt;modules/
  siswa/
    SiswaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
      Siswa.php
    views/
    layouts/
    default/
      index.php
  kota/
    KotaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
      Kota.php
    views/
    layouts/
    default/
      index.php
&lt;/pre&gt;&lt;br /&gt;
so sekarang lo harus ngerti bahwa secara prinsip arsitekturnya lo gak bisa bikin relasi model antar module. jadi untuk menyatakan bahwa seorang siswa datang dari satu kota, dan dari satu kota datang banyak siswa. masing-masing module harus memiliki modelnya sendiri2. jadi kira2 seperti ini&lt;br /&gt;
&lt;pre class=&quot;brush: bash, highlight: [10,11,24,25]&quot;&gt;modules/
  siswa/
    SiswaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
      Siswa.php
      Kota.php
    views/
    layouts/
    default/
      index.php
  kota/
    KotaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
      Siswa.php
      Kota.php
    views/
    layouts/
    default/
      index.php
&lt;/pre&gt;&lt;br /&gt;
ini secara prinsip arsitektur loh ya... technically keliatannya bisa saja langsung membuat relasi antar model meskipun model tersebut ada di module&lt;br /&gt;
lain. silahkan liat &lt;a href=&quot;http://code.google.com/p/yii-user/issues/detail?id=30&quot; target=&quot;_blank&quot;&gt;ini&lt;/a&gt; atau &lt;a href=&quot;http://groups.yahoo.com/neo/groups/id-php/conversations/messages/39392&quot; target=&quot;_blank&quot;&gt;contohnya mas indra setiawan&lt;/a&gt;. dengan menganggap bahwa secara teknis hal ini &quot;mungkin&quot;. maka &quot;ketergantungan antar modul&quot; ya jelas tidak dapat dihindari.. udah jelas-jelas disitu lo sengaja bikin relasi model dimana modelnya ada di 2 module yang berbeda.&lt;br /&gt;
&lt;br /&gt;
sekarang anggap saja kita mau mengikuti jalan arsitektur yang benar. kita sadar bahwa 2 model yang sama ada di masing-masing modul. apabila kita punya banyak modul dan di setiap modul kita butuh model siswa, maka model siswa akan ada di setiap modul. ini jelas tidak baik, karena code yang ada ditulis berulang-ulang. dan nantinya sulit untuk di maintain. maka ada baiknya komponen/kelas/model/apa saja yang akan dibutuhkan di semua module, ya ditulis satu kali, dan secara struktur terletak di luar module. gue ngebayangin nya ya kira-kira kayak gini&lt;br /&gt;
&lt;pre class=&quot;brush: bash, highlight:[2,3,12,24]&quot;&gt;models/
  Siswa.php
  Kota.php
modules/
  siswa/
    SiswaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
    views/
    layouts/
    default/
      index.php
  kota/
    KotaModule.php
    components/
    views/
    controllers/
      DefaultController.php
    extensions/
    models/
    views/
    layouts/
    default/
      index.php
&lt;/pre&gt;&lt;br /&gt;
Sekarang jangan tanya ke gue gimana itu model/komponen/class/apa saja, bisa dikenali oleh masing-masing module kalo ditaro seperti itu :D... pertanyaan technical ini gue balikin ke elo sebagai orang yang lebih sering pake yii.. Tapi sehubungan dengan ini gue juga ingin menjawab pertanyaan elo yaitu:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&quot;Seringkali ketika membuat modul baru, dan dipasangkan ke aplikasi saya tadi, ada saja bagian yang harus disentuh didalam coding.&quot;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
bagian apa yang harus disentuh dalam coding? bagian terlarang? :D apabila pada awalnya lo cuma punya module siswa.. beserta modelnya.. terus datang kota/kabupaten.. lalu antara siswa dan kabupaten memiliki relasi. ya jelas lo harus aktualisasi model siswa, minimal di bagian relasinya.. untuk menyatakan bahwa siswa ini datang dari kota x. kecuali lo mo bikin unidirectional relation.. yaitu hanya memberikan informasi siswa mana saja yang datang dari kota x. tanpa informasi siswa x datang dari kota mana. maka lo tidak perlu &quot;menyentuh&quot; model siswa.&lt;br /&gt;
&lt;br /&gt;
inipun buat gue sudah minimal.. lo gak akan perlu &quot;menyentuh&quot; controller atau view masing2 module. penyajian viewnya kan beda. kecuali lo misalnya punya view kota yang mau lo attached di view siswa. inipun menurut gue lo sudah punya yii &quot;component&quot; sebagai solusinya.&lt;br /&gt;
&lt;br /&gt;
terlepas dari itu semua.. database design dan domain model design (siswa model, kota model, mungkin sekolah model, beserta relasinya) umumnya sudah di pikirkan atau dipertimbangkan di awal sebelum coding aplikasi. ya gak semua tentunya.. bisa saja tiba2 ada model baru atau konsep baru nongol di tengah jalan.. itu lumrah.. tapi arsitektur yii gak mempersulit hal ini sebenarnya (penambahan model baru, definisi ulang relasi dsbnya). justru mempermudah.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&quot;apakah ngedit script config untuk koneksi modul hal yang wajar?&quot;&lt;/blockquote&gt;&lt;br /&gt;
ya dan tidak... sekarang kalo lo koneksi databasenya ganti.. harus edit konfigurasi gak?... hayo... :P&lt;br /&gt;
&lt;br /&gt;
yang namanya konfigurasi .. pasti ada saatnya dimana harus di &quot;edit&quot; statement &quot;ya dan tidak&quot; karena kalau dalam hubungan antar code php sendiri, sejak php5, php punya autoloader. dan seperti yang lo liat yii framework juga punya sejenis &quot;autoloader&quot;. sejak php5 &quot;autoloader&quot; ini cukup intensif digunakan di setiap jenis framework. tergantung bagaimana frameworknya, atau elo sebagai pengguna framework men setup autoloader ini. bisa saja lo gak harus mengedit configurasi ini lagi sama sekali. umumnya sih autoloader ini bekerja dengan menggunakan naming convention tertentu. kalo di yii kayaknya namanya &quot;namespaces&quot;.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;// autoloading model and component classes
&#39;import&#39;=&gt;array(
&#39;application.models.*&#39;,
&#39;application.components.*&#39;,
),
&lt;/pre&gt;&lt;br /&gt;
mungkin kalo lo bilang application.* lo gak perlu lagi edit2 confignya.. selama lo gak bikin kelas yang namanya sama :D. kalau di zend framework, ya mereka autoloadernya pake class naming convention. jadi kalo nama kelasnya Barang_Pecah_Belah, maka bisa ditemukan di frameworkpath/Barang/Pecah/Belah.php sekedar contoh.&lt;br /&gt;
&lt;br /&gt;
Pertanyaan dari mas Didin&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;saya pernah pake cara ini, hal ini kalo menurut saya hampir sama dengan konsep yang di awal dikatakan mas indra untuk membuat core module yang di load setiap saat. cuman, apakah cara ini termasuk ke dalam loose coupled.&lt;br /&gt;
&lt;br /&gt;
atau mungkin dari contoh kasus diatas misal saya mau design aplikasi yang secara simple terdiri dari siswa dan kota. hubungan siswa dan kota seperti biasanya.&lt;br /&gt;
&lt;br /&gt;
kira-kira lebih efisiennya seperti apa? apa dibikin module kota sendiri dan siswa sendiri. atau hanya bikin module siswa dan untuk kota hanya dibuatkan model yang diletakan di model utama (core module).&lt;br /&gt;
&lt;br /&gt;
untuk masalah high cohesive tadi, tujuan saya membuat method di class sebelumnya. untuk membuat element select yang nantinya bisa dimasukan ke dalam variable javascript. kenapa saya gak pake helpernya Yii (CHtml)?? karena helpernya yii menggenereate select dengan menyertakan format enter &quot;\n&quot; (mohon koreksi kalo seandainya pemahaman saya salah). yang kalo seandainya dimasukan ke dalam variabel di javascript akan error. makannya sya bikin method sendiri.&lt;/blockquote&gt;&lt;br /&gt;
pada dasarnya kalo lo ngikutin arsitekturnya yii.. semua model, view, controller, component dan lain2 nya yii itu sudah cukup loose coupled. kalo lo mo lebih loose coupled lagi, lo musti kerja pake interface, punya class factories atau pake inversion of control container dll.. dimana yii sendiri gak mensupport itu out of the box, dan gue gak yakin lo butuh saat ini.. yang penting kan make yii dulu yang bener toh bukan begitu?&lt;br /&gt;
&lt;br /&gt;
Dan ingat prinsip autoloader itu gak nge &quot;load semua&quot;.. autoloader itu cuma ngeload waktu lo butuh.. jadi pas lo new Siswa() atau Siswa:: atau sejenisnya baru di load. kalo gak dibutuhkan gak di load.&lt;br /&gt;
&lt;br /&gt;
gue lihat.. bekerja pake yii itu gak harus pake module. kalo lo liat contoh2 &lt;a href=&quot;http://code.google.com/p/yii/source/browse/#svn/trunk/demos&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
itu contohnya semua gak kerja pake module. kalo dalam definisi yii itu istilahnya &quot;default&quot; module. kalo mo beneran pake module kan di dalam protected itu ada directory module, dimana di dalam directory module itu ada directory nama module nya (dalam doku contohnya forum) dan di dalam directory tersebut ada model, view controller component dll. sedangkan dalam contoh di link tersebut gak seperti itu.&lt;br /&gt;
&lt;br /&gt;
antara gue gak ngerti bener tujuan aplikasi lo.. atau lo belum begitu ngerti kenapa orang bikin &quot;module&quot;.. bikin aplikasi yang modular kadang gak selalu langsung bikin &quot;module&quot; :D dan apakah pengertian &quot;core module&quot; elo dengan prinsip &quot;default module&quot; nya yii itu sama.. gue juga gak tahu.. hehehe tapi mungkin mengenai module ini gue coba luruskan dulu...&lt;br /&gt;
&lt;br /&gt;
seperti yang gue bilang sebelumnya atau sesuai dokunya yii.. module itu konsepnya satu aplikasi utuh. di dokunya mereka ambil contoh forum. biasanya kalo lo punya aplikasi yang besar. katakanlah lo punya webportal namanya &quot;didin&quot;.. lo punya cms untuk portal beritanya, terus lo punya forum buat orang2 nongkrong.. terus lo punya online shopping.. dll...&lt;br /&gt;
&lt;br /&gt;
masing2 punya kompleksitasnya sendiri2... kompleksitas spesifik ini yang menjadi tujuan module. banyak logik2 yang gak dibutuhkan atau gak berhubungan satu sama lain. apabila ini dijadiin satu, hanya merepotkan maintenance nya saja. ya.. ada satu point dimana ada hal-hal yang dipakai bareng.. katakanlah login information. hal hal seperti ini ya seperti yang gue bilang sebelumnya.. sebaiknya di taruh atau exist di luar module ini.&lt;br /&gt;
&lt;br /&gt;
sekarang lo harus coba bertanya pada diri lo sendiri.. seberapa kompleks aplikasi saya? atau seberapa kompleks &quot;siswa&quot; atau &quot;kota&quot; sampe2 harus dibikin masing2 sebagai module? kalo tujuannya cuma pengen bikin satu data grid dimana cuma kasih liat siswa mana saja yang datang dari kota x? kayak gini mah gak perlu module.&lt;br /&gt;
&lt;br /&gt;
lo cuma butuh 2 activerecord model. 1 controller dan 1 view... sekompleks2nya tambah satu form model.. sudah cukup...&lt;br /&gt;
&lt;br /&gt;
1 active record model buat siswa, 1 buat kota.. masing2 kasih relasinya 1 controller kasih satu action. dan bikin gridnya di view.&lt;br /&gt;
&lt;br /&gt;
kalo perlu tambahin form supaya bisa masukin nama kotanya.. biar grid siswanya dinamis.. sudah toh? gak perlu module.&lt;br /&gt;
&lt;br /&gt;
mungkin lain ceritanya ya kalo mo bikin .... *mikir*... entahlah... aplikasi untuk pemerintah propinsi kali ya.. dimana lo punya satu bagian tentang &quot;sekolah&quot; dari urusan management nya, keuangannya, mungkin siswa dan pegawainya.. inventarisasi dlsbnya.. dan lo punya bagian lagi tentang &quot;daerah&quot; dari informasi pemerintahnya (kepala daerah, pegawai pemerintah) tata kota, akta-akta dan lain sebagainya. ini mungkin layak lo bikin satu modul sekolah dan satu modul daerah. dan kalo lo mo bikin hubungan &quot;siswa&quot; dan &quot;kota&quot; ya model dari kedua module tersebut harus selayaknya ada di luar module.&lt;br /&gt;
&lt;br /&gt;
mengenai Chtml, gue gak bisa komentar karena gue gak tahu gimana cara kerjanya.. bahwa chtml ga bisa lo pake, menurut gue bukan alasan bahwa itu html select lo generate di satu method dalam sebuah active record class :D gue yakin itu method buat generate select pasti bisa lo taro di tempat lain.. yang pasti bukan di active record tempatnya. menurut gue itu yii component konsepnya sesuai. contohcomponent gue sempat kasih linknya.</description><link>http://arthur.purnama.de/2010/12/struktur-file-modul-dan-komponen-dalam.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7182284769746808233</guid><pubDate>Thu, 10 Jun 2010 08:12:00 +0000</pubDate><atom:updated>2014-01-03T14:08:19.705+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Unit Testing di PHP</title><description>Unit testing itu merupakan test paling dasar dalam pengembangan aplikasi. Terlepas dari apakah aplikasi elo itu ditulis menggunakan paradigma OO atau tidak. Dengan unit testing. lo melakukan sejenis &quot;pembuktian&quot; bahwa fungsi (unit) elo itu melakukan apa yang sebenarnya harus dilakukan. apabila sebuah fungsi (unit) bisa memiliki beberapa kemungkinan. maka sebisa mungkin semua kemungkinan ini di test/buktikan kebenarannya.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;&lt;br /&gt;
misal:&lt;br /&gt;
pada fungsi&lt;br /&gt;
&lt;br /&gt;
f(x) = x^2&lt;br /&gt;
&lt;br /&gt;
kita berasumsi bahwa apabila fungsi tersebut diberikan nilai minus pada parameter x, maka hasilnya pasti nilai kuadratnya dalam positif. kalau kita kasih nilai 0 maka hasilnya 0, dan kalo dikasi nilai positif maka hasilnya kuadratnya dalam positif.&lt;br /&gt;
&lt;br /&gt;
maka dari itu, dalam men-test fungsi (unit) ini, kita butuh katakanlah 3 &quot;test case&quot; (kasus kali ya istilahnya), misalnya&lt;br /&gt;
&lt;br /&gt;
jika x = 2 maka f(x) = 4&lt;br /&gt;
jika x= 0 maka f(x) = 0&lt;br /&gt;
jika x= -2 maka f(x) = 4&lt;br /&gt;
&lt;br /&gt;
apabila waktu lo test, ternyata keluarnya gak sama, berarti ni fungsi &quot;buggy&quot;.. harus dibenerin...&lt;br /&gt;
&lt;br /&gt;
so karena ini milis php, dan bukan milis matematika, gue tulis contoh codenya. gue tulis contohnya menggunakan unit testing framework bawaan phpunit. yang penting disini konsepnya dulu, bukan gimana cara pake phpunit. &lt;br /&gt;
&lt;br /&gt;
kelas yang mo di test :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace project\iseng;

class MyClass{
  
  public static function myMethod($x){
    return $x * $x;
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
contoh unit test nya :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace project\tests;

use project\iseng\MyClass;

class MyClassTest extends PHPUnit_Framework_TestCase
{
  
  /**
   * @test
   */
  public function myMethodTestXEquals2()
  {
    $result = MyClass::myMethod(2);
    $this-&gt;assertEquals(4, $result);
  }
  
  /**
   * @test
   */
  public function myMethodTestXEquals0()
  {
    $result = MyClass::myMethod(2);
    $this-&gt;assertEquals(4, $result);
  }
  
  /**
   * @test
   */
  public function myMethodTestXEqualsMinus2()
  {
    $result = MyClass::myMethod(-2);
    $this-&gt;assertEquals(4, $result);
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
apabila test ini di jalankan maka phpunit akan lapor OK. semua gak ada masalah. Akan tetapi dalam prakteknya menulis aplikasi. gak jarang kita menghadapi kesalahan dalam implementasi. Kesalahan itu bisa didasari berbagai macam alasan.... misalnya karena tidak paham benar konsep dasar proses bisnisnya. dan lain2.&lt;br /&gt;
&lt;br /&gt;
sekarang gue ambil contoh lah. Anggap programmernya gak ngerti bahwa fungsi f(x) adalah x^2 ... dia cuma tahu hasil dari f(x) adalah 0 untuk 0, 4 untuk 2 dan minus 2. mungkin dia ga tanya lagi ke product ownernya.. atau tidur, waktu pelajaran kalkulus, diferential dan polynomial pas kuliah :D&lt;br /&gt;
&lt;br /&gt;
jadi dia tulis begini :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class MyClass{
  
  public static function myMethod(x){
    return x * 2;
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
waktu unit test nya dijalanin.. phpunit bilang OK.. no problem.. tapi waktu di deploy di produktiv server.. hitungannya salah semua.. karena waktu masukin angka 1.. sebenernya hasilnya harus satu, ini malah 2... waktu masukin 3 mestinya 9, ini malah 6... akhirnya softwarenya &quot;buggy&quot;.&lt;br /&gt;
&lt;br /&gt;
Sekarang mungkin muncul pertanyaan, gue uda nulis unit test, kok masih buggy? well, yang ngetest kan kita, yang semestinya paham bagaimana bisnis prosesnya harus diimplementasikan kan kita. maka dari itu, kita yang sebenarnya harus tahu lebih dahulu.. fungsi ini sebenernya maunya apa.. dan menulis test case dari segala macam bentuk kemungkinan yang ada. unit test sendiri hanyalah &quot;perangkat&quot; yang ngebantu kita untuk menulis aplikasi yang lebih berkualitas dan stabil.&lt;br /&gt;
&lt;br /&gt;
Dengan sadarnya kita bahwa software kita buggy, dan unit test kita belum meng-cover semua kemungkinan yang ada. solusi yang harus dijalanin adalah tidak hanya mereparasi codenya, tapi juga menambahkan test-case pada unit kita. contoh :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace project\tests;

use project\iseng\MyClass;

class MyClassTest extends PHPUnit_Framework_TestCase
{
  
  //test case sebelumnya....
  
  /**
   * @test
   */
  public function myMethodTestXEquals1()
  {
    $result = MyClass::myMethod(1);
    $this-&gt;assertEquals(1, $result);
  }
  
  /**
   * @test
   */
  public function myMethodTestXEquals3()
  {
    $result = MyClass::myMethod(3);
    $this-&gt;assertEquals(9, $result);
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
Unit Testing juga digunakan sebagai &quot;perangkat&quot; dalam bekerja menggunakan metodologi &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot; target=&quot;_blank&quot;&gt;Test Driven Development&lt;/a&gt; dimana esensinya adalah &quot;test first, then write the code&quot;. Dengan ini kita didorong untuk memahami dulu bisnis prosesnya atau tugas yang harus kita kerjakan. dan mempertimbangkan semua kemungkinan kasus2 yang ada yang akan terjadi ketika fungsi tersebut digunakan. Tulis test case nya dulu. baru menulis codenya.&lt;br /&gt;
&lt;br /&gt;
Dalam hubungannya dengan bahasa berparadigma OO. Tantangan dalam menulis unit test salah satunya adalah interaksi fungsi dengan object. Maksudnya disini. kalo kita nulis satu fungsi/method, biasanya gak selalu parameternya itu angka atau primitiv data type, seperti contoh gue diatas. bisa jadi parameter x itu adalah object Pegawai.. dengan segala member attribute dan methodenya.&lt;br /&gt;
&lt;br /&gt;
Dalam hal ini, ketika menulis unit test. kita harus pastikan bahwa unit test tersebut berdiri secara independen, dan tidak dipengaruhi efek2 samping dari luar.&lt;br /&gt;
&lt;br /&gt;
misalnya f(x,y) adalah menghitung kenaikan gaji pegawai dimana x adalah object pegawai dan y adalah kenaikan dalam persen.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;namespace project\iseng;

use project\models;

class MyClass{
  
  public static function hitungKenaikanGajiDalamPersen(models\Pegawai
                                                       $pegawai, $persen){
    $kenaikan = $pegawai-&gt;getGaji() * ($persen/100);
    $gajiBaru = $pegawai-&gt;getGaji() + $kenaikan;
    $pegawai-&gt;setGaji($gajiBaru);
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
Apabila kita menulis unit test untuk fungsi ini, dan Object pegawai di initialisasi menggunakan informasi dari database. Maka unit test kita gak akan konstan kebenarannya. apabila di test berulang-ulang. misal :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class MyClassTest extends PHPUnit_Framework_TestCase
{
  
  //test case sebelumnya....
  
  /**
   * @test
   */
  public function myMethodTestNaikGaji10Persen()
  {
    $pegawai = projects\dao\Pegawai::getById(5);
    MyClass::hitungKenaikanGajiDalamPersen($pegawai, 10);
    $this-&gt;assertEquals(3300, $pegawai-&gt;getGaji());
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
Dalam contoh ini, unit test menginitialisasi object pegawai dari database. menganggap si pegawai dg nomer 5 itu gajinya 3000 eur. setelah naik 10 persen jadi 3300. Mungkin pada test pertama benar. karena memang begitu keadaannya dalam database. tapi setelah test pertama. informasi dalam database sudah berubah. yaitu naik gajinya 3300. waktu menjalankan test untuk kedua kalinya maka yang dinaikkan 10% sudah bukan 3000 lagi, melainkan 3300. dan perbandingan yang ada dalam unit test sudah tidak benar lagi. phpunit bakal protes kalo test nya gagal.&lt;br /&gt;
&lt;br /&gt;
Dalam hal ini, unit test mengenal istilah &quot;mock objects&quot;.. dimana dalam test. object2 yang berinteraksi dibuatkan object &quot;boong2an&quot; untuk menunjang test tersebut.&lt;br /&gt;
&lt;br /&gt;
contoh standard misalnya :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class MyClassTest extends PHPUnit_Framework_TestCase
{
  
  //test case sebelumnya....
  
  /**
   * @test
   */
  public function myMethodTestNaikGaji10Persen()
  {
    $pegawai = new projects\models\Pegawai();
    $pegawai-&gt;setGaji(3000);
    MyClass::hitungKenaikanGajiDalamPersen($pegawai, 10);
    $this-&gt;assertEquals(3300, $pegawai-&gt;getGaji());
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
Dalam hal ini pegawai mungkin attributnya ga cuma gaji saja, tapi ada alamat dan lain sebagainya.. hanya saja karena dalam test ini hanya berurusan masalah gaji. kita membuat instance kosong dari kelas pegawai dan mengisi nilai gajinya sebelum diberikan ke method untuk menghitung kenaikan gaji.&lt;br /&gt;
&lt;br /&gt;
Untuk hal2 yang kompleks umumnya unit testing framework memberikan tools2 extra dimana kita bisa membuat mock objects untuk test yang cukup rumit dan berinteraksi dengan berbagai macam object.&lt;br /&gt;
&lt;br /&gt;
So sekian dulu.. sebagai penutup.. seperti teman2 yang lain bilang.. menulis unit test itu butuh latihan dan disiplin tinggi. gue sendiri saja masih sering gagal menjalankannya secara konsekuen. semua tahu bahwa hal ini menunjang stabilitas dan kualitas produkt. tapi dalam pelaksanaannya gak jarang penuh hambatan...&lt;br /&gt;
&lt;br /&gt;
Selamat belajar.</description><link>http://arthur.purnama.de/2010/06/unit-testing-di-php.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-3910622322200213085</guid><pubDate>Fri, 26 Mar 2010 14:53:00 +0000</pubDate><atom:updated>2014-01-03T13:44:16.936+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>Earth Hour</title><description>waktu gue baca tentang aksi earth hour di indonesia yang mengundang rakyat indonesia untuk mematikan lampu selama satu jam. gue mikir. apa gak kurang tuh yang namanya mati lampu di indonesia? gue rasa kita semua orang indonesia pasti pernah ngerasain yang namanya mati lampu.. dan gak sebentar, bisa ber jam2.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
gue dulu waktu kecil tinggal di denpasar bahkan perna ngerasain mati lampu ampe 2 mingguan... gue nguping bokap gue ngoceh ma orang pln.. katanya &quot;apa-apaan ini.. ini mah bukan perusahaan listrik negara.. tapi perusahaan lilin negara kalo kayak gini&quot;. apakah keadaan di indonesia makin membaik atau tidak, gue pribadi gak tahu.. semoga saja makin membaik.&lt;br /&gt;
&lt;br /&gt;
waktu kuliah di jerman bbrp tahun, gue perna ditanya ma anak indo.. &quot;eh lo perna ngerasain mati lampu ga di jerman&quot;.. setelah gue pikir2 betul juga.. gue ga perna ngerasain... gue perna ngerasain mati lampu tapi cuma di gedung gue doang karena korsleting ato sejenisnya.. itupun cuma beberapa menit..&lt;br /&gt;
&lt;br /&gt;
akhirnya gue penasaran, gue pengen tahu.. emang seberapa lama sih rata2 mati lampu di jerman dan di indonesia? cari2 di google, gue ketemu &lt;a href=&quot;http://de.wikipedia.org/wiki/Stromausfall&quot; target=&quot;_blank&quot;&gt;statistiknya jerman di wikipedia&lt;/a&gt; dan yang indonesia di &lt;a href=&quot;http://www.pln.co.id/laporantahunan2008/pg_0012.htm&quot; target=&quot;_blank&quot;&gt;website pln&lt;/a&gt; .&lt;br /&gt;
&lt;br /&gt;
menurut statistik &lt;a href=&quot;http://de.wikipedia.org/w/index.php?title=System_Average_Interruption_Duration_Index&amp;amp;action=edit&amp;amp;redlink=1&quot; target=&quot;_blank&quot;&gt;SAIDI&lt;/a&gt;(System Average Interruption Duration Index) jerman tahun 2008 adalah 16,89 menit per orang(atau pelanggan?) yang paling seru di indonesia satuan nya jam :D dan taon 2008 SAIDI nya adalah 80,90 jam per pelanggan :( pake satuan hari aja biar kecil :D 3,37 hari.&lt;br /&gt;
&lt;br /&gt;
kalo gue mo balik lagi ke aksi Earth Hour... berarti dalam setaun bangsa indonesia mau atau tidak mau sudah menjalankan Earth Hour sebanyak hampir 81 kali... apa perlu ditambah sejam lagi?&lt;br /&gt;
&lt;br /&gt;
buat para idealis.. tentu saja perlu... :D alasannya sudah disebutkan di forwardnya mas titus..&lt;br /&gt;
&lt;br /&gt;
&quot;bla bla 300 Megawatt, bla...bla.. 267 ton karbondioksida, bla... bla.. 267 pohon bla...bla.. 535 orang, bla...bla.. Rp200 juta.&quot; bla..blub... foo... bar.. echo &quot;Hello Earth&quot;;&lt;br /&gt;
&lt;br /&gt;
ya ya.. gue tahu.. infrastruktur kita tidak bagus... dsb.. dsb.. gak bisa dibandingin sama negara maju.. tapi hey.. negara kita tuh sumber energi..mereka dapat dari mana energinya kalo bukan dari kita? kincir angin mereka memang dimana-mana tapi itu hanya meng cover dibawah 10% kebutuhan energi mereka... mereka jauh lebih wajib ngelaksanain aksi earth hour dibandingin kita :D&lt;br /&gt;
&lt;br /&gt;
apakah gue bakal ikutan aksi earth hour? hmmm... besok jam 20.30 gue uda pasti ga di rumah :D.. lampu pasti mati.. tapi listrik enggak :D soalnya kalo listrik gue matiin.. makanan gue buat seminggu di kulkas dan di freezer jadi rusak... akhirnya gue gak cuma ikutan earth hour.. tapi juga buang makanan.. gak ideal juga dong? buang makanan gitu loh... sementara orang&lt;br /&gt;
lain gak bisa makan.. bla bla.. blub.. foo... bar... echo... udah deeee :D &lt;br /&gt;
&lt;br /&gt;
kok ga di ruma?&lt;br /&gt;
&lt;br /&gt;
soalnya mao ikutan &lt;a href=&quot;http://www.hr-online.de/website/specials/hr3@night/index.jsp&quot; target=&quot;_blank&quot;&gt;hr3@night&lt;/a&gt; club party...&lt;br /&gt;
&lt;br /&gt;
yah sama aja dong?&lt;br /&gt;
&lt;br /&gt;
gak juga.. kan gak pake lampu juga.. gelap gelap... justru kalo terang ga seru.. hehehehe..&lt;br /&gt;
&lt;br /&gt;
maksa abis.. garing.. uda aaahh&lt;br /&gt;
&lt;br /&gt;
Have a nice weekend yaaa buat semua... jangan lupa matiin lampu :D</description><link>http://arthur.purnama.de/2010/03/earth-hour.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-8543674396755134512</guid><pubDate>Sun, 21 Feb 2010 23:39:00 +0000</pubDate><atom:updated>2014-01-03T15:58:49.345+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Asosiasi antar obyek di PHP</title><description>Apa itu agregasi apa itu komposisi? aggregasi itu salah satu bentuk asosiasi antar objekt... asosiasi object ada 2 macam. yang pertama dibilangnya &quot;komposisi&quot; yang kedua &quot;agregasi&quot;... UML notasinya bisa dilihat di &lt;a href=&quot;http://en.wikipedia.org/wiki/Object_composition&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt; itu kalo komposisi node diamond nya itu diisi, kalau aggregasi itu kosong.&lt;br /&gt;
&lt;br /&gt;
sekarang &quot;asosiasi object&quot; itu menjelaskan apa? &lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;&lt;br /&gt;
asosiasi object itu menjelaskan object X itu butuh atau menggunakan atau dibentuk dari object apa saja.&lt;br /&gt;
&lt;br /&gt;
apakah asosiasi tersebut jenisnya &quot;komposisi&quot; atau &quot;agregasi&quot; ini dilihat dari ketergantungan object x tersebut sama object lainnya.&lt;br /&gt;
&lt;br /&gt;
komposisi:&lt;br /&gt;
Object x &quot;terdiri dari / dibentuk oleh / dibangun dengan / membutuhkan&quot; object y, object z, dst... tanpa object y, object z, dst.. tersebut.. object x tidak bisa exist. atau dengan kata lain existensinya tidak berarti.. (oh apalah artinya hidup ini)&lt;br /&gt;
&lt;br /&gt;
contoh ngasal dari wiki... object mobil terdiri dari object mesin, object ban, object gearbox, dst....&lt;br /&gt;
&lt;br /&gt;
agregasi:&lt;br /&gt;
Object x &quot;bisa memiliki / menggunakan&quot; object y, object z, dst... tanpa object y, object z, dst.. tersebut object x tetap bisa exist.&lt;br /&gt;
&lt;br /&gt;
contoh ngasal dari wiki... object danau bisa memiliki object bebek, object perahu dst...&lt;br /&gt;
&lt;br /&gt;
ok sekarang kita masuk ke contoh aja deh ya...&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class ProductModel {
  
  private $f1;
  
  public function setF1(F1 $f1) {
    $this-&gt;f1 = $f1;
  }
  
  
  public function getF1() {
    return $this-&gt;f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this-&gt;f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}
&lt;/pre&gt;&lt;br /&gt;
object ProduktModel bergantung gak sama object F1? nggak, soalnya gue bisa menciptakan object ProduktModel tanpa object F1,&lt;br /&gt;
&lt;br /&gt;
misalnya&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProduktModel();
&lt;/pre&gt;&lt;br /&gt;
gue juga bisa menciptakan object F1 tanpa object ProduktModel misalnya&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$f1 = new F1();
&lt;/pre&gt;&lt;br /&gt;
gue bisa bikin object ProductModel berasosiasi sama object F1 misalnya&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel-&gt;setF1($f1);
&lt;/pre&gt;&lt;br /&gt;
so.. jenis asosiasi apakah ini? maka jawabannya &quot;agregasi&quot;;&lt;br /&gt;
&lt;br /&gt;
contoh berikut:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1){
    $this-&gt;f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this-&gt;f1 = $f1;
  }
  
  
  public function getF1() {
    return $this-&gt;f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this-&gt;f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}
&lt;/pre&gt;&lt;br /&gt;
object ProductModel bergantung gak sama object F1? iya.. coba sekarang bikin object ProductModel tanpa object F1,&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProductModel();
&lt;/pre&gt;&lt;br /&gt;
gak bisa.. karena dalam penciptaannya (konstruksi nya) butuh object F1. maka:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProductModel(new F1());
&lt;/pre&gt;&lt;br /&gt;
so.. jenis asosiasi apakah ini? maka jawabannya komposisi.&lt;br /&gt;
&lt;br /&gt;
contoh lagi&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;abstract class ProductDAO {
  
  public static function create(ProductModel $product) {
    if ($dsn-&gt;query(&quot;INSERT INTO product (f1,f2,f3) 
                     VALUES (&#39;{$product-&gt;getF1()}&#39;,&#39;{$product-&gt;getF2()}&#39;,&#39;{$product-&gt;getF3()}&#39;)&quot;)) {
      return true;
    } else {
      return false;
    }
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
so.. kelas ProductDAO dalam hal ini abstract... entah dimana mestinya ada implementasi konkritnya.. tapi gak usah dibahas dulu. dalam hal ini tidak akan ada yang namanya object ProductDAO, karena sifatnya yang abstrak, kita gak bisa instantiate (baca koreksi gue di atas).&lt;br /&gt;
&lt;br /&gt;
tapi kelas ProductDAO punya static method namanya create. methode ini butuh object ProductModel. kalo lo mo pake methode ini loe harus sertakan object ProductModel. misal:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProductModel();
ProductDAO::create($productModel);
&lt;/pre&gt;&lt;br /&gt;
so.. jenis asosiasi apakah ini?.. ini sebenarnya asosiasi &quot;komposisi&quot; akan tetapi yang berasosiasi bukan antara object dengan object tapi static method dengan object...&lt;br /&gt;
&lt;br /&gt;
kalo baca di wiki lebih lanjut... pada object yang memiliki asosiasi &quot;komposisi&quot;... apabila Object x dihancurkan, maka object y, object z, dst.. juga ikut hancur. sedangkan pada agregasi, apabila object x dihancurkan, maka object y, object z, dst... &quot;bisa&quot; tetap exist, karena tidak tergantung satu sama lain.&lt;br /&gt;
&lt;br /&gt;
statement ini dalam OOP buat gue (kalo ada yang punya pendapat lain silahkan komentar) gak absolut. mungkin bisa gue jelaskan dalam contoh..&lt;br /&gt;
&lt;br /&gt;
gue ambil contoh asosiasi komposisi seeperti diatas:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1){
    $this-&gt;f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this-&gt;f1 = $f1;
  }
  
  
  public function getF1() {
    return $this-&gt;f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this-&gt;f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}
&lt;/pre&gt;&lt;br /&gt;
so.. kalau kita menciptakan object ProductModel seperti contoh gue diatas,&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProductModel(new F1());
&lt;/pre&gt;&lt;br /&gt;
maka statement wiki tersebut benar. apabila object $productModel gue hancurkan, maka object F1 juga ikut hancur. misal&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;unset($productModel);
&lt;/pre&gt;&lt;br /&gt;
akan tetapi bagaimana kalau begini : ?&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$f1 = new F1();
$productModel = new ProductModel($f1);
&lt;/pre&gt;&lt;br /&gt;
pada dasarnya object ProductModel tetap memiliki asosiasi komposisi terhadap object F1 (tidak bisa eksis tanpa F1) akan tetapi apabila objectProductModel kita hancurkan, object F1 tetap eksis, karena variabel $f1 masih punya reference ke object F1:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;unset($productModel);
//object F1 masih exist... ga percaya?
var_dump($f1);
&lt;/pre&gt;&lt;br /&gt;
dengan ini statement tersebut tidak benar... statement tersebut kayaknya berlaku untuk bahasa2 seperti C, karena definisi asosiasi sendiri sudah ada lama jauh sebelum object oriented paradigma (betulkah begitu?... gue butuh dukungan atau komentar atas hal ini :D )&lt;br /&gt;
&lt;br /&gt;
2 contoh lagi buat direnungkan atau di diskusikan:&lt;br /&gt;
&lt;br /&gt;
contoh 1:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1 = null){
    $this-&gt;f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this-&gt;f1 = $f1;
  }
  
  
  public function getF1() {
    return $this-&gt;f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this-&gt;f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}
&lt;/pre&gt;&lt;br /&gt;
pada snipets diatas.. constructor parameternya gue kasih default value (dalam hal ini default value null) berarti sekarang object ProductModel sudah tidak bergantung lagi sama object F1. Karena gue sekarang bisa menciptakan object ProductModel tanpa F1:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$productModel = new ProductModel();
&lt;/pre&gt;&lt;br /&gt;
berarti sekarang asosiasinya agregasi dong :D&lt;br /&gt;
&lt;br /&gt;
contoh 2:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;abstract class ProductDAO {
  
  public static function create(ProductModel $product = null) {
    if ($dsn-&gt;query(&quot;INSERT INTO product (f1,f2,f3) 
                     VALUES (&#39;{$product-&gt;getF1()}&#39;,&#39;{$product-&gt;getF2()}&#39;,&#39;{$product-&gt;getF3()}&#39;)&quot;)) {
      return true;
    } else {
      return false;
    }
  }
  
}
&lt;/pre&gt;&lt;br /&gt;
sama seperti contoh 1, hanya saja kali ini bukan object tapi static method.&lt;br /&gt;
&lt;br /&gt;
pada dasarnya gue &quot;bisa&quot; memanggil static method create tanpa menyertakan object ProductModel karena parameternya kita kasih default value (lagi2 null).. :&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;ProductDAO::create();
&lt;/pre&gt;&lt;br /&gt;
akan tetapi kalo lo liat pada implementasi create, disitu object $product gue pake.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;.... VALUES (&#39;{$product-&gt;getF1()}&#39;,&#39;{$product-&gt;getF2()}&#39;,&#39; .....
&lt;/pre&gt;&lt;br /&gt;
meskipun &quot;tidak harus&quot; menyertakan object ProductModel, methode tersebut tidak bisa dipakai (existensi nya tidak berarti :D ) karena tetap butuh object ProductModel.&lt;br /&gt;
&lt;br /&gt;
maka dari itu asosiasinya tetap komposisi dong? :D&lt;br /&gt;
&lt;br /&gt;
Pertanyaan dari polutan:&lt;br /&gt;
&lt;blockquote&gt;gimana gambar UML nya untuk menyimbolkan bahwa yang berasosiasi bukan antara object dengan object tapi static method dengan object? Semua contoh2 dan yg di Wiki contohnya pasti melewatkan object B melalui konstruktor class A. Apalagi in abstract class dan static method, jd nggak yakin membuat gambarnya spt yg di tutorial2 itu..&lt;/blockquote&gt;&lt;br /&gt;
UML itu modeling language... sifatnya informatif.. tergantung apa yang mau disampaikan...&lt;br /&gt;
&lt;br /&gt;
lo bisa aja gambar seperti contoh di wiki, misalnya begini:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNLs1R5OeW-1H0TjKzV_1xjH4ygqssbjtXoG7-rFreku4afugFIiNlR5HOriiPwYx_2mDii3LKChE4w_4C-1ken2bDmFCXeed9X99xuTpUicIu5Xzkisy7joX5PQdJGyBxZnLUY7sLJ0k/s1600/komposisi2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNLs1R5OeW-1H0TjKzV_1xjH4ygqssbjtXoG7-rFreku4afugFIiNlR5HOriiPwYx_2mDii3LKChE4w_4C-1ken2bDmFCXeed9X99xuTpUicIu5Xzkisy7joX5PQdJGyBxZnLUY7sLJ0k/s1600/komposisi2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
dengan gambar ini lo udah kasih tahu bahwa &quot;abstract class ProductDAO punya relasi komposisi sama kelas ProductModel.&quot; implementasinya gimana itu gak relevan. sifatnya informatif saja.&lt;br /&gt;
&lt;br /&gt;
kalo mo diperjelas dari sisi ProductDAO nya (sesuai pertanyaan elo) ya bisa aja lo bikin begini:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0-exIud4vLME340ob9mwbB1Dub30BFL9TyKGdfE0IoXuPkHkwAFo80jDWYZKOoE466cDwqRP1dFl7TDW0V32R4_h0xCTMnw9eaiAq0Ij5JhAWFoksBblL2ZlhD8iFUqmZYcSylW37qFA/s1600/komposisi.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0-exIud4vLME340ob9mwbB1Dub30BFL9TyKGdfE0IoXuPkHkwAFo80jDWYZKOoE466cDwqRP1dFl7TDW0V32R4_h0xCTMnw9eaiAq0Ij5JhAWFoksBblL2ZlhD8iFUqmZYcSylW37qFA/s1600/komposisi.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
dengan gambar ini lo uda menginformasikan, bahwa &quot;abstract class ProductDAO yang berelasi komposisi dengan kelas ProductModel di implementasikan di public static methode yang namanya create yang memiliki parameter dengan nama product yang type nya ProductModel dan returnnya Boolean.&quot;&lt;br /&gt;
&lt;br /&gt;
ini pun sifatnya informatif saja, alias yang ga relevan ga dikasih liat. buktinya ProductModel gak gue isi member variabelnya apa, dan methodnya apa aja.&lt;br /&gt;
&lt;br /&gt;
semuanya tergantung apa yang mo lo sampaikan atau informasikan.&lt;br /&gt;
&lt;br /&gt;
kalo bingung kenapa dengan gambar seperti itu bisa tahu kalau kelasnya abstract atau methodnya public static.</description><link>http://arthur.purnama.de/2010/02/asosiasi-antar-obyek-di-php.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNLs1R5OeW-1H0TjKzV_1xjH4ygqssbjtXoG7-rFreku4afugFIiNlR5HOriiPwYx_2mDii3LKChE4w_4C-1ken2bDmFCXeed9X99xuTpUicIu5Xzkisy7joX5PQdJGyBxZnLUY7sLJ0k/s72-c/komposisi2.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-8046277263176811734</guid><pubDate>Thu, 13 Aug 2009 06:47:00 +0000</pubDate><atom:updated>2014-01-03T13:28:20.085+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Lazy initialization</title><description>Kelas yang &quot;ramping atau tidak bergantung&quot; dan &quot;performa aplikasi&quot; itu gak selalu berhubungan. belum tentu dengan ramping dan tidak bergantungnya kelas terus aplikasi pasti berjalan lebih cepat. Disini gue melihat adanya kekurang pahaman tentang prinsip loose coupled dan high cohesion. dimana prinsip kolonial VOC jaman dulu divide et impera (devide and conquer) ditelan mentah-mentah. pokoknya belah apa yang bisa dibelah, pisah apa yang bisa dipisah. akhirnya setelah semuanya dipisah, bingung make-nya gimana.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;Thema ini sempat diangkat di milis id-php ketika satu teman mengalami dilema dalam memilih strategi pengembangan aplikasinya. Thread lengkapnya bisa dilihat langsung di &lt;a href=&quot;http://groups.yahoo.com/neo/groups/id-php/conversations/topics/31277&quot; target=&quot;_blank&quot;&gt;milis&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Permasalahannya sebagai berikut:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;Php-ers,&lt;br /&gt;
&lt;br /&gt;
Saya lagi di rundung dilema. Dimana pada awal nya desain salah satu class Transaksi saya telah dirancang utk menjadi ramping dan tidak bergantung. Tetapi sejalan nya waktu utk mendapatkan 1 informasi, saya harus mendeklarasi class2 utk meload bbrp kepingan informasi sehingga membentuk informasi transaksi yg utuh. Maka saya menggabungkan bbrp class tsb menjadi 1. &lt;br /&gt;
&lt;br /&gt;
Dan masalah mulai muncul di permukaan ketika class gabungan ini mulai byk dipakai dan membawa byk informasi, aplikasi menjadi lambat. Ini adalah link utk bisa di unduh file starUML utk melihat secara grafis dlm format UML. Utk yg satu hal 2 hal tidak dpt melihat UML. Saya mencoba utk menggambarkan nya dlm kata2.&lt;br /&gt;
&lt;br /&gt;
class Transaksi pembelian menampung semua informasi pembelian, item2 yg dibeli, kemana item2 akan ditransfer, DP yg telah di bayarkan, mutasi item2 yg telah diterima. Dan setiap class memiliki detail tersendiri. jadi setiap class bersifat one-to-many. Masalah muncul ketika saya harus menampilkan daftar pembelian berikut dengan data penerimaan barang. Yang jumlah nya kalau di hitung scr matematis,&lt;br /&gt;
Jika Pembelian memiliki 50 item, maka akan ada data mutasi 50, data transfer 50 dan transaksi diterima yg kmungkinan bs lebih dari 5-10 kita pakai 5 transaksi yg memuat 50 data. Maka total 50 + 50 + 50 + (5 * 50) = 400 data.&lt;br /&gt;
&lt;br /&gt;
Dan dalam 1 bulan bisa lbh dari 30 transaksi penjualan. Maka rata2 perbulan ada 30 * ~400 = 12000 data yg saya harus sajikan. Mungkin paging solusi yg terbaik, tetapi yg menjadi pertanyaan saya adalah bagaimana strategi atau cara terbaik agar class tetap ramping tetapi mudah utk mendapatkan data yg tersebar dlm kepingan2 kecil. Terima kasih.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh90BCYO71BQtXSE9CZqtkL5iQtWp8P7poiEC7g72MKFglQn85vLM3YDWGgO86aIa5ijnOYzsvpU6N6ehxKDpJycA8aV2X1JhbrZcBZ3ZhykYF70M90mZV4JxAL38hzZK1y1sHU8XLTd7U/s1600/PurchaseUML.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh90BCYO71BQtXSE9CZqtkL5iQtWp8P7poiEC7g72MKFglQn85vLM3YDWGgO86aIa5ijnOYzsvpU6N6ehxKDpJycA8aV2X1JhbrZcBZ3ZhykYF70M90mZV4JxAL38hzZK1y1sHU8XLTd7U/s1600/PurchaseUML.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Adesanto Asman&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Kelas yang &quot;ramping atau tidak bergantung&quot; dan &quot;performa aplikasi&quot; itu gak selalu berhubungan. belum tentu dengan ramping dan tidak&lt;br /&gt;
bergantungnya kelas terus aplikasi pasti berjalan lebih cepat. Disini gue melihat adanya kekurang pahaman tentang prinsip loose coupled dan high cohesion. dimana prinsip kolonial VOC jaman dulu divide et impera (devide and conquer) ditelan mentah-mentah. pokoknya belah apa yang bisa dibelah, pisah apa yang bisa dipisah. akhirnya setelah semuanya dipisah, bingung make-nya gimana. gak perlu kecewa ^^. dalam proses belajar hal seperti ini wajar ^^. gue juga harus melewati masa-masa ini kok ^^. dan tetap harus belajar karena masih jauh dari sempurna :). gue pengen banget bahas thema ini tapi ga disini kali ya :D tar kepanjangan dan aga2 OOT.&lt;br /&gt;
&lt;br /&gt;
so sekarang gue mo coba jawab inti permasalahannya. yang gue ngerti lo punya masalah terutama dalam bikin report karena lo butuh semua object dari transaction object, purchased object, details object, payment object, mutasi object dan lain sebagainya. sementara kadang dalam report itu loe paling cuma butuh 1 maksimal 3 informasi dari masing2 objekt (misalnya mungkin dari payment cuma nominalnya doang, dan dari transaction cuma transaction numbernya doang). tapi lo malah load semua informasi dari semua object. dan harus loe oper ini semua ke front end view class.&lt;br /&gt;
&lt;br /&gt;
kalo emang lo punya akses ke database layer (nulis sql statement dan sejenisnya) hal ini bisa lo pecahkan dengan mendefinisikan satu select join statement. dimana di select kolom-kolom yang diperlukan saja untuk reporting. select statement ini bahkan juga bisa di simpan dalam bentuk &quot;view&quot; apabila databasenya mendukung. setelah itu bisa dibikin satu class baru yang member variabelnya berisi kolom2 dalam select statement ini. dengan ini lo hanya punya satu object yang hanya merequest ke satu select statement ^^.&lt;br /&gt;
&lt;br /&gt;
contoh:&lt;br /&gt;
&lt;br /&gt;
kira kira data access object classnya begini&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class TransactionReportDAO implements InterfaceDAO{
  
  public function getStatement(){
    return &quot;SELECT transaction.id as transaction_number,
                   purchased.id as purchased_number, purchased.amount as
                   purchased_amount, item.name as item_name *dan seterusnya*
            FROM transaction LEFT JOIN purchased ON
                 transaction.id = purchased.transaction_id
            LEFT JOIN (dan seterusnya)
            WHERE (where klausa nya);&quot;
  }
  
  /**
   * return TransactionReport
   */
  public function getResult(){
    //populated the result to object TransactionReport
  }
}

&lt;/pre&gt;&lt;br /&gt;
terus model dari Entity class nya ya kira-kira kayak gini&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class TransactionReport{
  
  private $transactionId;
  
  private $purchasedId;
  
  private $purchasedNumber;
  
  private $amount;
  
  private $itemName;
  
  //member variabel yang lain
  
  public function getTransactionId(){
    return $this-&gt;transactionId;
  }
  
  public function setTransactionId ($transactionId){
    $this-&gt;transactionId = $transactionId;
  }
  
  //getter dan setter yang lainnya.
  
}
&lt;/pre&gt;&lt;br /&gt;
dan service class nya kira2 begini:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class TransactionService{
  
  /**
   * return TransactionReport[]
   */
  public static function getAllTransactionReport(){
    
    return DBService::getInstance()-&gt;execute(new TransactionReportDAO())
                     -&gt;getResult();
    
  }
  
  //service service yang lainnya
  
}
&lt;/pre&gt;&lt;br /&gt;
Dimana pada akhirnya di view loe bisa kira2 begini:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;&amp;lt;table&amp;gt;
  &amp;lt;?php
  /* @var TransactionReport[] $dataList */
  $dataList = TransactionService::getAllTransactionReport();
/* @var TransactionReport $data */
foreach($dataList as $data) :
?&amp;gt;
&amp;lt;tr&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;?php echo $data-&gt;getTransactionId(); ?&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;?php echo $data-&gt;getPurchasedId(); ?&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;?php echo $data-&gt;getAmount(); ?&amp;gt;&amp;lt;/td&amp;gt;
  .... dan seterusnya ...
&amp;lt;/tr&amp;gt;

&amp;lt;?php endforeach; ?&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
seperti lo lihat, loe cuma punya satu sql request, yang bisa lo modifikasi sedikit buat pagination ato sejenisnya. tapi sql requestnya tetap satu. trade off-nya tentunya tiap kali lo mo bikin report yang isinya lain loe musti bikin sql statement dan entity object yang baru. tapi dari sisi performa ini masih lebih baik.&lt;br /&gt;
&lt;br /&gt;
Sekarang kalo misalnya lo ga punya akses ke database layer. dimana lo sebagai view developer cuma bisa pakai model yang sudah di definisikan. mau tidak mau memang kita waktu meng initialize objectnya kita dapat semua informasi yang ada di kolomnya meskipun kita tidak pakai. akan tetapi ada design pattern yang bisa ngebantu kita untuk meload data hanya waktu dibutuhkan saja. apabila pattern ini di implementasikan dalam meng handle model. kita masih bisa lah mempertahankan performa sedikit ^^. pattern ini umum dipakai di framework-framework ORM. namanya &lt;a href=&quot;http://en.wikipedia.org/wiki/Lazy_initialization&quot; target=&quot;_blank&quot;&gt;Lazy initialization&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
gue kasih contoh penggunaannya ya.&lt;br /&gt;
&lt;br /&gt;
anggap entity class lo.. seperti yang lo gambar di uml, ya mirip2 lah&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class Transaction{
  
  private $transactionId;
  
  //member transaction yang lainnya
  
  /**
   * @var Purchased[]
   */
  private $purchased
    
    //getter and setter
}

class Purchased{
  private $purchasedId;
  
  //member purchased yang lainnya
  
  /**
   * @var Items[]
   */
  private Items;
  
  /**
   * @var Mutasi[]
   */
  private mutasi;
  
  /**
   * @var Payments[]
   */
  private payments;
  
  //getter and setter
}

class Items{
  
  private itemId;
  
  //member item yang lainnya
  
  //getter and setter
  
}
&lt;/pre&gt;&lt;br /&gt;
so class mutasi dan payments ga gue gambarin lah.. kira2 begitu.&lt;br /&gt;
&lt;br /&gt;
waktu lo pake di view misalnya ya bakal kira2 kayak gini&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;&amp;lt;table&amp;gt;
  &amp;lt;?php
    /* @var Transaction[] $dataList */
    $transactionList = TransactionService::getAllTransaction();
    /* @var Transaction $transaction */
    foreach($transactionList as $transaction ) :
    
      /* @var Purchased[] $purchasedList*/
      $purchasedList= $transaction-&gt;getPurchased();
      /* @var Purchased $purchased*/
      foreach($purchasedList as $purchased) :
      
        /* @var Payments[] $paymentList*/
        $paymentList= $purchased-&gt;getPayments();
        /* @var Payment $payment*/
        foreach($paymentListas $payment) :
  ?&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;?php echo $transaction-&gt;getTransactionId(); ?&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;?php echo $purchased-&gt;getPurchasedId(); ?&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;?php echo $payment-&gt;getAmount(); ?&amp;gt;&amp;lt;/td&amp;gt;
    .... dan seterusnya ...
  &amp;lt;/tr&amp;gt;
  
  &amp;lt;?php 
        endforeach; 
      endforeach; 
    endforeach; 
  ?&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
jangan kaget liat foreach nya. memang begini jadinya, kompleksitas komputasi dari satu kali foreach isi 100 data sama dengan 3 foreach isi 2x5x10 data.&lt;br /&gt;
&lt;br /&gt;
dengan lazy initialization, waktu lo request $transactionList maka member variabel $purchased sebenernya masih kosong(null). select statement yang terjadi di database layer hanya untuk mengisi object Transaction saja. select statement untuk purchased, payment, mutasi dan items belum terjadi. jadi di dalam variabel $transactionList isinya cuma sedikit, yaitu informasi tentang transaction saja. informasi tentang purchased baru diminta ketika loe panggil $transaction-&gt;getPurchased();&lt;br /&gt;
&lt;br /&gt;
dalam contoh gue, loe cuma request transaction, purchased dan payments saja. mutasi dan items tidak ikut di load karena gak lo request. dengan ini lo hanya berkesan bawa-bawa semua data, padahal datanya sendiri di dalam object belum ada, dan hanya diisi ketika dibutuhkan.&lt;br /&gt;
&lt;br /&gt;
tentu ini pun ada tradeoff nya, seperti yang kita tahu, request database itu mahal sekali, gak peduli data yang diminta banyak atau sedikit. tapi semuanya tergantung pertimbangan design dan situasi mana yang terbaik. tehnik ini biasanya didukung sama tehnik lainnya seperti mekanisme caching misalnya, untuk mengurangi request langsung ke database.&lt;br /&gt;
&lt;br /&gt;
semoga gue membantu.</description><link>http://arthur.purnama.de/2009/08/lazy-initialization.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh90BCYO71BQtXSE9CZqtkL5iQtWp8P7poiEC7g72MKFglQn85vLM3YDWGgO86aIa5ijnOYzsvpU6N6ehxKDpJycA8aV2X1JhbrZcBZ3ZhykYF70M90mZV4JxAL38hzZK1y1sHU8XLTd7U/s72-c/PurchaseUML.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-1623609936057795451</guid><pubDate>Wed, 14 Jan 2009 20:54:00 +0000</pubDate><atom:updated>2014-01-03T00:45:49.089+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>ORM Patterns</title><description>Kali ini gue mau membahas 2 Design Pattern untuk Object Relational Mapping. Beberapa hari lalu ada di milis ada yang tanya mengenai bedanya ORM dan Active Record. Dan gue coba untuk membahasnya disana. Supaya gak hilang gue post juga di blog gue beserta pertanyaan awalnya. Diskusi lengkapnya bisa disimak langsung &lt;a href=&quot;http://groups.yahoo.com/neo/groups/id-php/conversations/topics/27453&quot; target=&quot;_blank&quot;&gt;di milis&lt;/a&gt; id-php.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot;&gt;&lt;/script&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;&gt;&lt;/link&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;&gt;&lt;/link&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;Topik dibuka dengan pertanyaan sebagai berikut:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;Teman2.. saya tertarik sekali dengan konsep2 baru mendesain&lt;br /&gt;
aplikasi,khususnya aplikasi web.&lt;br /&gt;
Saya lagi belajar dan baca2 artikel bout ORM dan ActiveRecord. Di buku&lt;br /&gt;
yg saya baca, ORM itu Object Relational Mapping. Jadi proses mapping&lt;br /&gt;
semua struktur pada table di database menjadi sebuah class pd OOP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Di buku dijelaskan proses mappingnya. Yaa sampe disitu saya ngerti.&lt;br /&gt;
Yang bikin saya nggak ngerti,&lt;br /&gt;
&lt;br /&gt;
1. Mengapa kita harus susah2 mapping? kan udah ada class2 ActiveRecord&lt;br /&gt;
dan class2 ORM seperti Propel utk PHP ( hmm gak pernah pake Propel )&lt;br /&gt;
ato pake framework2 yg udah fada itur MVC dan ActiveRecordnya. Bahkan&lt;br /&gt;
dengan menggunakan framework2 itu kita udah bisa kan bikin aplikasi&lt;br /&gt;
skala enterprise tanpa perlu design mapping secara manual.&lt;br /&gt;
&lt;br /&gt;
2. Apakah class ORM dan ActiveRecord yg udah ada menyalahi aturan dan&lt;br /&gt;
konsep dari ORM itu sendiri?&lt;br /&gt;
Maksudnya, contoh kita pake cakephp. define model Student. naahh di&lt;br /&gt;
model student cuman ada definisi variabel2 association aja. gak ada yg&lt;br /&gt;
namanya definisi ( mapping ) semua entitas2 yg ada di table di class /&lt;br /&gt;
model Student itu. Karena semua itu dihandle oleh property $this-&amp;gt;data&lt;br /&gt;
dan method save() , find() .&lt;br /&gt;
&lt;br /&gt;
3. saya tertarik untuk bikin class ORM yg sangat2 simple. Yaaahh&lt;br /&gt;
paling nggak udah bisa save dan find one to one, dan one to many aja.&lt;br /&gt;
Tapi,, kebanyakan saya liat di source code-source code class2 ORM (&lt;br /&gt;
seperti fitur active record di cakephp ) kok sedikitpun nggak ngikut&lt;br /&gt;
konsep ORM yg dijelaskan di buku?&lt;br /&gt;
&lt;br /&gt;
Hmmm kyknya itu aja dehh..&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Terimakasih :)&lt;br /&gt;
&lt;br /&gt;
polutan&lt;br /&gt;
&lt;/blockquote&gt;Karena sudah janji mo nulis, maka gue mo nepatin janji gue.&lt;br /&gt;
&lt;br /&gt;
tentang ORM sudah pernah dibahas di milist PHP sebelah. threadnya bisa dilihat &lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/message/38305&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
threadnya juga sempat mengalami perdebatan menarik tentang masa depan ORM. Soal masa depan ORM gak gue ungkit disini ^^. Tapi gue akan coba menuturkan kekurangan dan kelebihannya dari pandangan gue. ^^&lt;br /&gt;
&lt;br /&gt;
so kembali ke pertanyaannya mas polutan.&lt;br /&gt;
Kalo gue baca pertanyaannya dan berusaha memahami maksudnya. maka gue berkesimpulan bahwa lo mencampur aduk kan antara Konsep dasar ORM dan implementasi ORM di dalam framework (misalnya cakephp).&lt;br /&gt;
Gue rasa kalo lo bisa mengerti dengan benar konsep dasar ORM itu sendiri, maka lo tidak akan bertanya seperti ini. mohon maaf dulu nih kalo ternyata kesimpulan gue salah.&lt;br /&gt;
&lt;br /&gt;
Supaya pemahaman lo ama gue sama maka dari itu coba kita sinkonisasi saja pemahaman ORM nya. Secara garis besar gue ambil dari wiki:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&quot;is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming languages&quot;&lt;/blockquote&gt;&lt;br /&gt;
jadi tujuannya merubah informasi yang disimpan berorientasi relational (one to one, one to many, many to many), menjadi object supaya dapat dibaca dan berkolaborasi dengan aplikasi yang ditulis berorientasi obyek (inheritance, abstract, interface, composition, aggregation dsb.).&lt;br /&gt;
&lt;br /&gt;
So tujuannya seperti itu. bagaimana menuju ke situ. ada banyak cara. Kalau kita bicara lo mo pergi ke satu tujuan, maka banyak cara untuk menuju ke sana (jalan kaki, naik mobil, naik angkot, kereta dsb). maka cara menuju ke ORM itu adalah Design Pattern nya. 2 Design Pattern yang terkenal dan cukup sering dipakai untuk ORM yaitu:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Active Record Pattern&lt;/li&gt;
&lt;li&gt;Data Mapper Pattern&lt;/li&gt;
&lt;/ul&gt;So sekarang mestinya kita bisa sepaham bahwa ORM itu adalah konsep/idenya dan Design Pattern adalah implementasinya. Buku-buku tentang ORM umumnya menjelaskan konsep ORM dan memberikan contoh implementasinya tanpa mengacu pada bahasa pemrogramman tertentu. apabila contohnya ditulis dalam bahasa pemrogramman tertentu (misalnya java). itu hanyalah sekedar alat bantu untuk mengerti dan memahami konsep tersebut. Pada dasarnya selama bahasa pemrogramman yang dipilih berorientasi objekt. maka sudah semestinya contoh2 tersebut juga dapat diimplementasikan menggunakan syntax bahasa tersebut. Mulai dari sini gue mau mencoba menjelaskan dulu pemahaman implementasi ORM tanpa dipengaruhi bahasa pemrogramman tertentu (misal php). syntax contohnya tentu gue bikin menggunakan syntax php, dengan harapan supaya bisa lebih dimengerti.&lt;br /&gt;
&lt;br /&gt;
Kita mo mreubah informasi yang disimpan secara relational menjadi object supaya bisa berkolaborasi dengan aplikasi kita yang ditulis dengan paradigma berorientasi object. apa itu object? object itu instance dari sebuah kelas. jadi jelas sekali disini bahwa tidak perduli Design Pattern mana yang kita mo pake. semuanya butuh yang namanya kelas. untuk menciptakan object.&lt;br /&gt;
&lt;br /&gt;
contoh sebuah kelas.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class Person{
  
  private $name;
  private $birthDate;
  
  public function setName($name){
    $this-&amp;gt;name = $name;
  }
  
  public function getName(){
    return $this-&amp;gt;name;
  }
  
  public function setBirthDate($birthDate){
    $this-&amp;gt;birthDate = $birthDate;
  }
  
  public function getBirthDate(){
    return $this-&amp;gt;birthDate;
  }
  
}
&lt;/pre&gt;sebuah kelas yang indah bukan? lalu? apa hubungannya sama ORM? kalo lo kolega kerja gue dan gue yang bikin ini kelas, gue kasih elo, terus gue bilang. ini adalah ORM class dari table &quot;Person&quot; di database, loe bakal telan omongan gue mentah-mentah? :) that will be not so clever ^^. Sebuah kelas adalah sebuah kelas. Dia gak akan secara ajaib bisa mewakili sebuah entitas tertentu, apalagi entitas tersebut ada di system yang berbeda (database).&lt;br /&gt;
&lt;br /&gt;
Maka dari itu kita butuh yang namanya mapping. Kita me-Map table dan attribute di database ke kelas yang sudah kita buat. Istilahnya kita memberikan pernyataan bahwa Kelas ini beserta member variabelnya mewakili table x beserta attributenya dalam database. Tehniknya tentu berbeda-beda, dari bahasa yang satu ke bahasa yang lain, dari framework yang satu ke framework yang lain.&lt;br /&gt;
&lt;br /&gt;
Untuk contoh kelas yang diatas. maka gue kasih contoh kira2 aplikasi gue nge-map nya seperti ini&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class Person extends MyORM{
  
  private $name;
  private $birthDate;
  
  public function setName($name){
    $this-&amp;gt;name = $name;
  }
  
  public function getName(){
    return $this-&amp;gt;name;
  }
  
  public function setBirthDate($birthDate){
    $this-&amp;gt;birthDate = $birthDate;
  }
  
  public function getBirthDate(){
    return $this-&amp;gt;birthDate;
  }
  
  protected function map(){
    
    $map = array(
      &#39;table&#39; =&amp;gt; &#39;person&#39;,
      &#39;name&#39; =&amp;gt; &#39;person_name&#39;,
      &#39;birthDate&#39; =&amp;gt; &#39;person_birth_date&#39;
    );
    
    return $map;
  }
  
}
&lt;/pre&gt;sekedar contoh. ceritanya gue nge-map kelas ini ke table person di database, dan variabel member nya masing gue map ke tabel attributenya. ini sekedar contoh saja. tehnik nge-map seperti gue bilang barusan, bisa berbeda-beda.&lt;br /&gt;
&lt;br /&gt;
So ini dasarnya Mapping di ORM tanpa pengaruh bahasa pemrograman tertentu. sekarang gue mau masuk ke php.&lt;br /&gt;
&lt;br /&gt;
gue melihat kelas ORM gue yang panjang dan gue juga melihat dimana nama kelas dan nama tabel nya mirip, nama member variabel dan nama tabel attribute nya juga mirip2. Kalau saja gue bisa membujuk sang&lt;br /&gt;
database designer dan sang application programmer untuk mengikuti aturan-aturan tertentu, gue bisa membuat ORM class gue sedemikian ringkasnya, karena segala sesuatunya sudah berjalan berdasarkan aturan tertentu.&lt;br /&gt;
&lt;br /&gt;
you got me bro. i&#39;m trying to make a convention here. untuk itu gue harus melihat apakah bahasa pemrogramman gue mendukung ide gue tersebut. maka gue coba2 buka manual php.&lt;br /&gt;
&lt;br /&gt;
php5 punya fungsi menarik yang dikenal dengan istilah &quot;magic method&quot;. lebih lengkapnya silahkan baca &lt;a href=&quot;http://www.php.net/manual/en/language.oop5.magic.php&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
pada prinsipnya, gue bisa bereaksi dan melakukan sesuatu apabila orang yang menggunakan object gue memanggil class member yang tidak gue definisiin di kelas gue.&lt;br /&gt;
&lt;br /&gt;
sebagai contoh&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$person = new Person();
$person-&amp;gt;someVar = &#39;someValue&#39;;
$person-&amp;gt;someMethod(&#39;parameter1Val&#39;, &#39;parameter2Val&#39;);
&lt;/pre&gt;variabel someVar dan methode someMethod beserta parameternya, kagak gue definisiin di kelas gue diatas. akan tetapi dengan magic method gue bisa bereaksi dan melakukan sesuatu apabila ada orang yang mencoba untuk memanggil class member yang tidak gue definisikan.&lt;br /&gt;
&lt;br /&gt;
karena sifat dasar php sebagai dynamic language dimana loe bisa main ngedefinisiin variabel tanpa deklarasi lebih dahulu. maka pada statement&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$person-&amp;gt;someVar = &#39;someValue&#39;;
&lt;/pre&gt;lo gak akan mengalami error, hanya saja apabila satu saat nanti loe mo pake lagi, misalnya saja&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;echo $person-&amp;gt;someVar
&lt;/pre&gt;maka loe tidak mendapatkan &#39;someValue&#39; sebagai output, tapi string kosong. kalo loe&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;var_dump($person-&amp;gt;someVar);
&lt;/pre&gt;hasilnya pasti NULL.&lt;br /&gt;
&lt;br /&gt;
akan tetapi pada statement&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$person-&amp;gt;someMethod(&#39;parameter1Val&#39;, &#39;parameter2Val&#39;);
&lt;/pre&gt;lo bakal dapet php error yang bilang &quot;method is not defined&quot;.&lt;br /&gt;
&lt;br /&gt;
Dengan menggunakan php magic method gue bisa bereaksi terhadap hal2 seperti ini. Daripada melemparkan error atau nilai null, maka gue bisa menjalankan programm logik yang konkrit atau menyimpan nilai tersebut. contohnya bisa dilihat di &lt;a href=&quot;http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members&quot; target=&quot;_blank&quot;&gt;php manual&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
satu hal lagi yang menarik. php memiliki fungsi standard bernama &lt;a href=&quot;http://www.php.net/manual/en/function.get-class.php&quot; target=&quot;_blank&quot;&gt;get_class()&lt;/a&gt; untuk mengetahui nama kelas sebuah object.&lt;br /&gt;
&lt;br /&gt;
berbekal informasi ini. gue mau mencoba menjalankan ide gila gue. idenya seperti ini.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;nama dari sebuah kelas mewakili nama dari sebuah tabel dalam&lt;br /&gt;
database. nama kelas tersebut harus dimulai dengan huruf besar, akan&lt;br /&gt;
tetapi nama tabelnya harus huruf kecil.&lt;/li&gt;
&lt;li&gt;Apabila orang meng-instantiate class tersebut, maka harus terjadi&lt;br /&gt;
validasi apakah terdapat sebuah tabel dengan nama kelas tersebut dalam&lt;br /&gt;
database. jika tidak maka lempar TableNotExistException.&lt;/li&gt;
&lt;li&gt;Nama dari member variabel mewakili nama dari table attribute. nama&lt;br /&gt;
variabel harus dimulai dengan huruf kecil, dan tabel attribute juga&lt;br /&gt;
harus ditulis dengan huruf kecil&lt;/li&gt;
&lt;li&gt;Apabila orang mencoba memanggil atau menset nilai sebuah member&lt;br /&gt;
variabel, maka harus terjadi validasi apakah terdapat sebuah tabel&lt;br /&gt;
attribute dengan nama tersebut dalam database. jika tidak maka lempar&lt;br /&gt;
TableAttributeNotExistException.&lt;/li&gt;
&lt;li&gt;Apabila nama kelas atau member variabel lebih dari 1 suku kata, maka&lt;br /&gt;
ditulis CamelCase, sedangkan di database ditulis menggunakan&lt;br /&gt;
strip_bawah sebagai pemisah.&lt;/li&gt;
&lt;li&gt;fungsi standard yang akan dikenal untuk sementara adalah save,&lt;br /&gt;
update, dan delete.&lt;/li&gt;
&lt;li&gt;fungsi dinamis yang akan dikenal adalah findBy yang diikuti dengan&lt;br /&gt;
column name ditulis menggunakan CamelCase misal: findByBirthDate&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Dengan ini berarti kalau gue mo nge definisiin ORM class dari person, gue tinggal tulis&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;class Person extends MyORM{

}
&lt;/pre&gt;pendek sekali bukan? mengingatkan anda pada sebuah php framework. errrrr.. apa ya? ^^ pada contoh ini setiap ORM class harus meng-extend class MyORM untuk menunjukkan bahwa kelas ini adalah ORM class yang memiliki ketentuan2 seperti diatas. implementasinya sendiri terjadi di kelas MyORM. kalau mau kita bisa bikin MyORM abstract. supaya tidak bisa di instantiate oleh pengguna ORM kita.&lt;br /&gt;
&lt;br /&gt;
implementasi MyORM kira2 bakal kayak gini&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;abstract class MyORM{
  
  /* array untuk menyimpan table attribute kita */
  private $tableAttribute = array();
  
  /* variabel untuk menyimpan table name kita */
  private $tableName = null;
  
  public function __construct(){
    
    /* ambil nama kelas menggunakan get_class($this) */
    /* jadikan huruf awal menjadi huruf kecil dan rubah
CamelCase dengan strip_bawah */
    /* periksa apakah dalam database ada kelas dengan nama tersebut */
    /* jika tidak throw TableNotExistException */
    /* jika ya maka simpan nama tabel dalam variabel $tableName */
  }
  
  public function __set($name, $value){
    /* jadikan huruf awal dari $name menjadi huruf kecil dan
rubah CamelCase dengan strip_bawah */
    /* periksa apakah dalam database ada kelas dengan nama tersebut */
    /* jika tidak throw TableAttributeNotExistException */
    /* jika ya maka simpan dalam $tableAttribute[$name] = $value */
  }
  
  public function __get($name){
    /* jadikan huruf awal dari $name menjadi huruf kecil dan
rubah CamelCase dengan strip_bawah */
    /* periksa apakah variabel tersebut sudah ada dalam
$tableAttribute */
    /* Jika ya maka return $tableAttribute[$name] */
    /* Jika tidak maka throw TableAttributeNotFoundException */
  }
  
  public function __call($name, $args){
    /* periksa apakah $name diawali dengan findBy */
    /* jika tidak throw MethodNotExistException */
    /* jika ya maka ambil text setelah findBy lalu oper ke
local variable $colName */
    /* jadikan huruf awal dari $colName menjadi huruf kecil dan
rubah CamelCase dengan strip_bawah */
    /* periksa apakah dalam database ada kelas dengan nama tersebut */
    /* jika tidak throw TableAttributeNotExistException */
    /* jika ya maka lakukan SELECT dengan where clause $colName
= $args[0] (argumen pertama) */
    /* ambil resultnya dan map setiap baris ke dalam object dan
kumpulkan object tersebut dalam satu array */
    /* return array result */
  }
  
  public function save(){
    /* save implementation */
  }
  
  public function delete(){
    /* delete implementation */
  }
  
  public function update(){
    /* update implementation */
  }
  
}
&lt;/pre&gt;dengan begini sewaktu gue tulis&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;$person = new Person();
$person-&amp;gt;personName = &#39;Some Name&#39;;
&lt;/pre&gt;dia akan &quot;magically&quot; mapped variabel personName ke attribute person_name pada table person menggunakan &quot;convention&quot; yang sudah didefinisikan.&lt;br /&gt;
&lt;br /&gt;
So sekarang. apakah dengan begini gue melanggar prinsip dasar ORM?. seperti yang loe lihat gue gak perlu mapping lagi. cuma bikin kelas kosong. Well. menurut gue. gue gak melanggar prinsip dasar ORM. karena mapping itu ada, hanya saja gue trick menggunakan convention over configuration. Ini gue lakukan karena &quot;kebetulan&quot; php memberikan gue kesempatan untuk melakukan hal ini. Ruby mungkin punya trick lain, begitu juga Java, .Net dan yang lainnya. Apabila implementasi-nya tidak sesuai dengan dibuku. sebenarnya harus dianalisa lebih jauh. apakah ini benar2 melenceng jauh dari konsep, atau hanya sekedar memanfaatkan fitur2 dari bahasa pemrogramman tersebut untuk membuat bekerja jadi lebih mudah saja, tanpa melanggar konsep dasarnya.&lt;br /&gt;
&lt;br /&gt;
Sekedar info, menurut gue, result hasil dari ORM request di cakePHP kurang sesuai dengan Konsep ORM, karena hasilnya disimpan dalam array dimana semestinya disimpan dalam objekt. lebih lanjut bisa lihat &lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/message/38341&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Jaman sekarang emang ngetrend convention over configuration. gue sih gak gitu nge fans sama yang satu ini. emang sih bisa jadi lebih cepat. tapi gue ngerasa setiap aplikasi itu unik. dan keunikan itu gak bisa dicapai menggunakan standard. Gue perna dapat proyek bikin web aplikasi kecil buat satu bank asal jerman di luxembourg. mereka mau pake grails (groovy on rails) konsepnya sama convention over configuration. waktu kerja brutto 2 bulan. waktu kerja murni kalo gue itung2 sebenernya cuma 2 minggu. sisa waktunya adalah menyesuaikan aplikasi tersebut sesuai permintaan client. html css javascriptnya sih bukan jadi masalah besar. justru malah convention nya yang memberatkan dan bikin jadi tidak fleksibel.&lt;br /&gt;
&lt;br /&gt;
gue pribadi masih jauh lebih suka kalau gue punya class yang jelas seperti contoh awal. bukan kelas kosong begitu. keuntungannya lebih banyak dan kalaupun emang capek ngetik. capeknya kebayar waktu maintanance phase. bayangin coba kalo ORM class kosong begitu. berarti loe kalo mo pake classnya kudu buka database client atau database manager dong? buat ngeliat ini kelas membernya apa aja. coba kalo loe tulis semua member variabel dan methodnya. terus loe kerja pake IDE. enak kan ada autocomplete nya. loe tinggal pilih dari autocomplete nya. gak usah pusing2 buka2 database admin. dan tentunya juga gak usah takut salah tulis ^^. Keunggulan bahasa dinamis biasanya memang bisa mengerjakan tugas dengan cepat. tapi kelebihannya itu membuat kekurangannya sendiri. banyak hal terlalu magic. methode tidak didefinisikan, tapi kalo dipanggil bisa return sesuatu. variabel tidak ada datatypenya, sewaktu2 bisa number, sewaktu2 bisa string, sewaktu2 bisa boolean, kayak banci taman lawang aja. (ngomong2 di taman lawang masih banyak banci gak ya?) hal seperti ini gak bikin aplikasi makin robust, tapi buggy.&lt;br /&gt;
&lt;br /&gt;
ORM yang menggunakan convention seperti RoR atau Grails biasanya tetap punya kemampuan mapping. tapi hanya dipakai apabila nama kelas dan tabel nya tidak sama. jadi untuk costumisasi atau configurasi ^^. gue gak tahu CakePHP punya gak hal seperti itu. bayangin coba kalo $person-&amp;gt;name sudah dipake dimana2 terus karena satu dan lain hal kita harus ganti nama kolomnya jadi &quot;nama&quot; gue gak akan mau disuruh cari &quot;name&quot; di seluruh aplikasi gue untuk diganti jadi &quot;nama&quot;. mending gue &quot;map&quot; member variabel &quot;name&quot; untuk menunjuk ke kolom &quot;nama&quot;. dengan ini gue cuma ganti di satu tempat.^^&lt;br /&gt;
&lt;br /&gt;
Salah satu kelebihan ORM yang juga suka jadi bahan pertimbangan adalah portabilitas. ya. aplikasi lo bakal jadi tidak bergantung pada database tertentu. built once runs on any database. ya ya. marketing gag. Memangnya seberapa sering sih kita musti bikin aplikasi yang kedepannya bakal sering ganti database? gue pribadi sih belum pernah. ada baiknya loe coba perhatiin bagaimana ORM tersebut meng-handle request2 lo. terutama request berat yang berhubungan sama beberapa table. atau bagaimana dia menghandle sebuah tree structure dalam database.&lt;br /&gt;
&lt;br /&gt;
Setiap database punya dialekt dan fungsi2 khusus. terutama database proprietary seperti oracle, db2 dan sebangsanya. ini dibuat bukan cuma sekedar nunjukin bahwa ini produkt proprieter. tapi lebih untuk memberikan kemudahan dan performa dalam melakukan request komplex yang tidak didefinisikan di standard SQL. mereka juga kadang memiliki algoritma sendiri yang membuat SQL Request jadi lebih cepat. hal ini tidak mudah diimplementasikan di sebuah ORM yang mau bisa jalan di semua jenis database system. kadang request yang sebenarnya bisa dilakukan hanya dengan sekali select di sebuah database (katakanlah misalnya oracle) sama ORM nya bisa jadi dilakukan dalam 5 kali select. bagaimana dia menghandle sequenze? bagaimana dia menghandle transaction? dsb dsb dsb. ini jelas merupakan hal yang menjadi bahan pertimbangan penting apakah aplikasi kita perlu pakai ORM atau langsung pakai fungsi dan dialekt database tersebut.&lt;br /&gt;
&lt;br /&gt;
Semoga tulisan gue menjawab pertanyaan lo dan memberikan pencerahan daripada bikin bingung.</description><link>http://arthur.purnama.de/2009/01/orm-patterns.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-902410558504609050</guid><pubDate>Sun, 07 Dec 2008 22:01:00 +0000</pubDate><atom:updated>2014-01-02T23:11:37.103+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Object Cloning di PHP 5</title><description>&lt;div class=&quot;separator&quot; style=&quot;float: left; clear: both;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOhQGQQCJT0H-rqcHEgLl1bgvIljLviQynyLo3LWdnuFgH0apT_PWpT-NdEHCZy2eAnmKSD-7k75STlzrA99VubCMC8Yafu6VcMBJiNgt_9IziUBrm1oEeM2QMcz94FviWEFkvKeFs2qI/s1600-h/914335_85510317_2.jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 116px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOhQGQQCJT0H-rqcHEgLl1bgvIljLviQynyLo3LWdnuFgH0apT_PWpT-NdEHCZy2eAnmKSD-7k75STlzrA99VubCMC8Yafu6VcMBJiNgt_9IziUBrm1oEeM2QMcz94FviWEFkvKeFs2qI/s200/914335_85510317_2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5277368475002518226&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Beberapa waktu lalu sempat ada yang bertanya tentang &lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/message/22522&quot; target=&quot;_blank&quot;&gt;apa efektifnya menggunakan object cloning di PHP 5&lt;/a&gt;. Untuk mengetahui efektifitasnya, maka mungkin ada baiknya untuk mengetahui kenapa PHP 5 support object cloning. &lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/message/22536&quot; target=&quot;_blank&quot;&gt; Jawaban gue atas thread ini&lt;/a&gt;, gue masukin ke blog gue sebagai referensi gue. Dan gue harap juga bisa membantu yang lain kalau sedang belajar tentang object cloning di PHP 5. Apabila ada yang perlu di koreksi, ditambahkan atau dikritik, gue terima dengan senang hati.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;&lt;br /&gt;
Pada dasarnya informasi tentang object cloning bisa dibaca di &lt;a href=&quot;http://www.php.net/manual/en/language.oop5.cloning.php&quot; target=&quot;_blank&quot;&gt;dokumentasi PHP 5&lt;/a&gt;. Untuk mengetahui kenapa ada clone object, perlu kita ketahui, bahwa di php 5 sekarang object itu sudah gak &lt;span style=&quot;font-style:italic;&quot;&gt;pass by value&lt;/span&gt;, tapi &lt;span style=&quot;font-style:italic;&quot;&gt;pass by reference&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Apa artinya itu? Mungkin bisa gue jelaskan seperti ini. Misalnya kita bekerja di sebuah gudang Laptop. Apabila kita menyimpan sebuah laptop, maka kita dapat secarik kertas kecil yang berisi catatan laptop tersebut ada di bagian mana di gudang. Misalnya Blok 5, Rak 3, Kotak nomer 8. Catatan ini kita bisa istilahkan sebagai &quot;referensi&quot; kita pada obyek laptop tersebut.&lt;br /&gt;
&lt;br /&gt;
Apabila kita ingin memberikan obyek tersebut kepada orang lain (variabel lain). Maka kita sebenarnya membuat fotokopi dari catatan kita, dan memberikannya kepada orang tersebut. Disini kita lihat, kita hanya mengkopi &quot;referensi&quot; kita. Obyeknya tetap mengacu pada laptop yang sama. Artinya apabila orang lain melakukan perubahan pada laptop tersebut, maka sewaktu kita melihat kembali laptop tersebut, kondisinya sudah berubah.&lt;br /&gt;
&lt;br /&gt;
Object Cloning dalam contoh ini berarti. Kita membuat satu cloning dari laptop tersebut. Bentuk dan kondisinya sama persis. Akan tetapi, karena Kotak nomer 8 pada Rak 3 di Blok 5 sudah diisi sama laptop pertama tadi, maka laptop cloningan ini harus ditaruh di kotak yang lain. Misalnya saja Kotak nomer 2 pada Rak 4 di Blok 5. Setelah itu kita membuat catatan kecil tentang alamat laptop tersebut, dan memberikannya pada teman kita. Dengan ini apabila teman kita melakukan perubahan pada laptop tersebut, dia tidak merubah laptop (obyek) kita, tapi laptop kloningan.&lt;br /&gt;
&lt;br /&gt;
Sekarang mari kita coba mengggunakan contoh code.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
class Account {
    public $balance;

    function __construct($balance) {
        $this-&gt;balance = $balance;
    }
}

class Person {
    private $name;
    private $age;
    private $id;
    public $account;

    function __construct($name,$age, Account $account) {
        $this-&gt;name = $name;
        $this-&gt;age = $age;
        $this-&gt;account = $account;
    }

    function setId($id) {
        $this-&gt;id = $id;
    }

    function getId() {
        return $this-&gt;id;
    }

    $account = new Account(0);
    $person = new Person(&#39;Oka&#39;, 21, $account);
    $person-&gt;setId(2);
    $person2 = $person;
    $person2-&gt;setId(4);
    echo $person-&gt;getId().&#39; &#39;.$person2-&gt;getId();
?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Di PHP 4 hasil dari echo tersebut adalah &quot;2 4&quot;; Akan tetapi di PHP 5 hasil dari echo tersebut adalah &quot;4 4&quot;; ini disebabkan di PHP 5 pada statement $person2 = $person object Person pada $person di  &lt;span style=&quot;font-style:italic;&quot;&gt;pass by reference&lt;/span&gt; ke $person2, dalam arti di dalam variable $person2 isinya bukan copy (clone) dari object $person, tapi isinya hanyalah sebuah pointer yang menunjuk ke memory, dimana object $person di simpan.&lt;br /&gt;
&lt;br /&gt;
Oleh karena itu setiap perubahan yang dilakukan di object $person2 akan ikut mempengaruhi object $person. Kenapa dibuat seperti ini di php5? nampaknya php5 berusaha untuk menyamakan behaviour syntax nya pada bahasa2 berparadigma OOP lainnya. CMIIW. supaya orang yang biasa kerja di java, .net atau sejenisnya tidak kaget waktu kerja ber OOP pakai PHP dan sudah biasa dengan asumsi bahwa statement &quot;=&quot; untuk object itu, pasti parse by reference.&lt;br /&gt;
&lt;br /&gt;
Tambahan info. Dalam bahasa pemrogramman berorientasi obyek. Biasanya orang mengenal tipe data &quot;primitiv&quot; dan tipe data &quot;obyek&quot;. Tipe data primitiv seperti integer itu selalu &lt;span style=&quot;font-style:italic;&quot;&gt;pass by value&lt;/span&gt;, sedangkan tipe data obyek itu &lt;span style=&quot;font-style:italic;&quot;&gt;pass by reference&lt;/span&gt;.  Oleh karena ini, apabila kita di PHP5 ingin memiliki copy utuh dari sebuah object, dimana apabila kita merubah state dari object kopian tersebut tidak mempengaruhi object aslinya, kita diberikan solusi clone.&lt;br /&gt;
&lt;br /&gt;
Mari kita coba merubah code gue diatas dengan clone:&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
$account = new Account(0);

$person = new Person(&#39;Oka&#39;, 21, $account);

$person-&gt;setId(2);

$person2 = clone $person;

$person2-&gt;setId(4);

echo $person-&gt;getId().&#39; &#39;.$person2-&gt;getId();
?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Dengan ini di PHP 5 hasil echonya bisa sama dengan PHP 4 yaitu &quot;2 4&quot;.  Di thread milist ada yang bertanya, kenapa gak di instance ulang saja seperti ini?&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
$person = new Person(&quot;Oka&quot;, 21, new Account(200));
$person2 = new Person(&quot;Oka&quot;, 21, new Account(200));
$person3 = new Person(&quot;Oka&quot;, 21, new Account(200));
?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Mari kita lihat keefektivan dari clone. Dengan clone kita mendapat copy yang sama persis dari object yang di clone. sedangkan contoh pada contoh diatas, untuk membuat 3 object yang statenya sama, kita harus memasukkan kembali nilai dari parameter tersebut.&lt;br /&gt;
&lt;br /&gt;
Kasusnya mungkin bisa seperti ini. Bayangkan kalau object $person yang kita bikin itu mau digunakan di sebuah class yang bukan tanggung jawab kita. Misalnya (lagi2) kolega kerja kita.&lt;br /&gt;
&lt;br /&gt;
Bekerja Object Oriented yang baik adalah dimana kolega kerja kita tidak perlu tahu menahu seluk beluk yang terjadi di dalam object yang kita bikin (loose coupled). Bisa jadi misalnya, ini misal ya, bahwa state dalam object tersebut seperti nama, umur dan account balancenya didapat dari $_POST (informasi yang diberikan user lewat user interface). Dan karena satu dan lain hal, kolega kita tidak bisa membaca atau tidak tahu menahu soal $_POST. Yang dia tahu hanya object yang di dapat dari kita. Satu-satunya state yang bisa dia ganti misalnya adalah Id nya dengan menggunakan public method setId().&lt;br /&gt;
&lt;br /&gt;
Disini dia gak punya lagi kesempatan untuk bikin instance baru dari class Person yang statenya sama persis sama object $person yang kita berikan. Dia kan gak tahu bahwa waktu menginstance object $person kita memberikan nilai &quot;Oka&quot;, 21 dan account balance 200 pada masing2 class attributenya. Maka dari itu, digunakanlah tehnik clone ini.&lt;br /&gt;
&lt;br /&gt;
Mari kita coba ya pakai contoh code. Sebagai contoh kita bertanggung jawab untuk UI (Presentation Tier), dan kolega kita yang bertanggung jawab di bagian Database (Persistent Tier).&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
$person = new Person ($_POST[&#39;name&#39;], $_POST[&#39;age&#39;], new
Account($_POST[&#39;balance&#39;]));
$person-&gt;setId($_POST[&#39;id&#39;]);

$persistancePerson-&gt;insertNewPerson($person);
?&amp;gt;
&lt;/pre&gt;Sampai disini tugas kita kelar dan kita memberikan object $person kepada kolega kita yang ngurusin insert ke database. Soal SQL statement mah dia jagonya lah, kita gak peduli.  Nah sekarang sebelum die melakukan insert ke database, dia pengen coba-coba dulu periksa, udah ada belon data dengan id tersebut di database, kalau memang sudah ada maka akan diberikan id baru, lalu di save. Supaya dia gak mengganggu object state yang diterima dari kita, maka untuk coba-coba, dia bikin clone dari object tersebut.&lt;br /&gt;
&lt;br /&gt;
Misalnya isi dari methode insertNewPerson(Person $person) seperti berikut: &lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
public function insertNewPerson(Person $person){
   $person2 = clone $person;

  while($this-&gt;idAlreadyExist($person2-&gt;getId())){
         $person2-&gt;setId($this-&gt;getNextId());
  }

  $DBObject::getInstance()-&gt;execute(&#39;INSERT INTO person ......&#39;);
}
?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Dengan ini dia mencoba-coba menggunakan object kopian dari $person. Pada $person2-&gt;setId() hanya object $person2 saja yang terganti statenya. Object $person tetap seperti sediakala, sewaktu dia menerima dari kita.&lt;br /&gt;
&lt;br /&gt;
Manakah yang lebih cepat, membuat instance baru, atau mencopy. Disini kita bisa &lt;a href=&quot;http://www.php.net/manual/en/language.oop5.cloning.php&quot; target=&quot;_blank&quot;&gt;membaca kembali dokumentasinya&lt;/a&gt;. Disitu ditulis:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;When an object is cloned, PHP 5 will perform a shallow copy of all of the object&#39;s properties. Any properties that are references to other variables, will remain references. &lt;/blockquote&gt;&lt;br /&gt;
Menurut pemahaman gue tentang Computer system, untuk bikin instance baru itu pasti lebih ribet, mungkin ngecheck nilai dari parameternya bener tidak, nama classnya exist tidak, terus generate segalanya dalam bentuk object, lalu cari memory yang kosong untuk di simpan. Kalau copy object kan dia gak perlu ngejalanin semuanya itu. tinggal cari memory kosong, terus kopi ajah mentah-mentah (shallow copy) dari memory object aslinya.&lt;br /&gt;
&lt;br /&gt;
Gue harap informasi ini bisa memberikan pencerahan. </description><link>http://arthur.purnama.de/2008/12/object-cloning-di-php-5.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOhQGQQCJT0H-rqcHEgLl1bgvIljLviQynyLo3LWdnuFgH0apT_PWpT-NdEHCZy2eAnmKSD-7k75STlzrA99VubCMC8Yafu6VcMBJiNgt_9IziUBrm1oEeM2QMcz94FviWEFkvKeFs2qI/s72-c/914335_85510317_2.jpg" height="72" width="72"/><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-4163004126555207938</guid><pubDate>Sun, 07 Dec 2008 20:00:00 +0000</pubDate><atom:updated>2014-01-02T23:12:28.523+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Pengecualian di PHP 5</title><description>&lt;div class=&quot;separator&quot; style=&quot;float: left; clear: both;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihIf4VTcpXmvKN3asGBRAA9cTW1lCZdxIPZIhOjclpCigcLGDJFT8VdzIGfqMGAnFArmkLrKygtrNG_xorvLZ-uSd_qNV_huD8-V5W39aC8c7wpLFf15-2uzF4JOeZRcgBfkoyUTQG2zQ/s1600-h/995000_46458615_2.jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 123px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihIf4VTcpXmvKN3asGBRAA9cTW1lCZdxIPZIhOjclpCigcLGDJFT8VdzIGfqMGAnFArmkLrKygtrNG_xorvLZ-uSd_qNV_huD8-V5W39aC8c7wpLFf15-2uzF4JOeZRcgBfkoyUTQG2zQ/s200/995000_46458615_2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5277156932703930770&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Beberapa waktu lalu di milist id-php ada yang sempat bertanya tentang &lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/message/22437&quot; target=&quot;blank&quot;&gt;Exception di PHP 5&lt;/a&gt;. Beberapa contoh yang diberikan, menurut gue masih kurang menunjukkan kemampuan dari exception itu sendiri, maka dari itu gue mencoba untuk ikutan memberikan jawaban dan contoh.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/message/22478&quot; target=&quot;_blank&quot;&gt;Tulisan gue di milist&lt;/a&gt;, gue coba tulis kembali di blog gue, untuk sekedar jadi arsip gue. Mungkin juga bisa membantu yang lain apabila ada yang cari-cari informasi tentang exception di PHP 5. Beberapa dari contoh yang gue kasih di tulisan gue waktu itu gue perbaiki karena ada kesalahan di syntaxnya. Apabila masih ada yang perlu di koreksi atau kritik dan saran, gue terima dengan senang hati.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;&lt;br /&gt;
Secara umum penggunaan exception bisa &lt;a href=&quot;http://www.php.net/manual/en/language.exceptions.php&quot; target=&quot;_blank&quot;&gt;dibaca di dokumentasi PHP 5&lt;/a&gt;. Beberapa dari contoh yang disebutkan di milist, menunjukkan bahwa exception dapat digunakan untuk melihat backtrace error. Memang benar dengan exception kita bisa melihat backtrace error dari programmnya. Tapi untuk backtrace sendiri PHP sebenarnya sudah punya &lt;a href=&quot;http://de3.php.net/manual/en/function.debug-backtrace.php&quot; target=&quot;_blank&quot;&gt;debug_backtrace&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Bukan berarti kita tidak boleh menggunakan Exception untuk melakukan backtrace. Tentu saja boleh, malah kalau kita bekerja menggunakan orientasi obyek, kita justru dipermudah dalam hal backtrace menggunakan Exception. Akan tetapi gue pengen kasih contoh tujuan yang sebenarnya dari exception itu sendiri.&lt;br /&gt;
&lt;br /&gt;
Sebelum itu gue mau mencoba mengutip satu contoh yang diberikan di milist dalam thread ini.  &lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
if (!is_writable($this-&gt;file)) {
    throw new Exception(&quot;file &#39;{$file}&#39; is not writeable&quot;);
}
file_put_contents($file,$xmlObj-&gt;asXML());

//apa bedanya klo saya buat seperti ini ? :
if (!is_writable($this-&gt;file)) {
    echo &quot;Aduuwwhhh filenya ndak bisa ditulisi!&quot;;
    exit();
}
file_put_contents($file,$xmlObj-&gt;asXML());`
?&amp;gt;
&lt;/pre&gt;Contoh tersebut membuat PHP mengeluarkan error message &quot;uncaught exception&quot;. Ini sebenarnya sebuah error yang tidak boleh ada. Kalau di java, hal seperti ini membuat code java nya sendiri gak bisa di compile, sampai sang programmer membuat try-catch block pada programm code yang berpotensi untuk melempar exception tersebut.&lt;br /&gt;
&lt;br /&gt;
Seperti yang gue bilang diatas, kita bisa menggunakan exception, sebagai error handler, tapi bukan berarti exception itu melulu merupakan sebuah &quot;error&quot;. Dengan exception kita diberi kesempatan untuk melakukan sesuatu (handle) terhadap exception tersebut.&lt;br /&gt;
&lt;br /&gt;
Gue akan memberikan contoh yang mengacu pada contoh diatas. Dan gue coba berikan sebuah skenario dimana penggunaan exception bisa digunakan.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Gue harus membuat sebuah methode (dalam class) yang dapat menulis xml kedalam sebuah file.&lt;/li&gt;
&lt;li&gt;Untuk menulis file kedalam xml, maka gue butuh 2 parameter, yaitu file, dan string.&lt;/li&gt;
&lt;li&gt;Parameter file tersebut harus sebuah file resource, harus bisa dibaca dan harus bisa ditulis.&lt;/li&gt;
&lt;li&gt;Parameter string tersebut harus sebuah string, dan merupakan xml yang conform.&lt;/li&gt;
&lt;li&gt;Apabila semua prosedur itu dipenuhi maka xml tersebut bisa ditulis kedalam file.&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;Berikut adalah contoh kelasnya.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
class PutXMLToFile{

   public function putThatThing($file, $xml){
        if(!is_file($file)){
           throw new ExceptionIsNotAFile(&#39;Resource is not a File!&#39;);
        }

        if(!is_readable($file)){
           throw new ExceptionFileNotReadable(&#39;File not readable.&#39;);
        }

        if(!is_writeable($file)){
           throw new ExceptionFileNotWriteable(&#39;File not writeable&#39;);
        }

        if(!is_string($string)){
           throw new ExceptionIsNotAString(&#39;not a string&#39;);
        }

        if(!is_xml_conform($string)){
           throw new ExceptionIsNotXMLConform(&#39;not xml conform&#39;);
        }

        file_put_contents($file,$string);
   }
}
?&amp;gt;
&lt;/pre&gt;Dengan ini kita akan memberikan code ini - misalnya - kepada kolega kerja kita, yang bertanggung jawab untuk user interface. Katakanlah ada 2 kolega kita yang bertanggung jawab untuk UI, yang satu UI untuk browser biasa, yang satu UI untuk mobile browser.&lt;br /&gt;
&lt;br /&gt;
Requirementnya sebagai berikut. &lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Apabila file, bukan sebuah file, maka buka UI file management untuk memilih atau mengupload file.&lt;/li&gt;
&lt;li&gt;Apabila file tidak dapat dibaca, atau tidak dapat ditulis, maka buka UI file access management untuk mengedit file access.&lt;/li&gt;
&lt;li&gt;Apabila string bukan string, tampilkan error message.&lt;/li&gt;
&lt;li&gt;Apabila string tidak xml conform, maka tampilkan UI xml editor untuk mengedit xml file tersebut.&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;Sekarang gue bukin contoh untuk UI mobile browser. Gue anggap user interface object nya sudah jadi saja.&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
$userInterface = new MobileUserInterface();

try{
   $putXMLToFile = new PutXMLToFile();
   $putXMLToFile-&gt;putThatThing($file, $string);
}catch (ExceptionIsNotAFile $e){
    $userInterface-&gt;openFileManager();
}catch (ExceptionFileNotReadable $e){
     $userInterface-&gt;openFileAccessManager();
}catch (ExceptionFileNotWriteable $e){
     $userInterface-&gt;openFileAccessManager();
}catch (ExceptionIsNotAString $e){
     $userInterface-&gt;showError($e-&gt;getMessage());
}catch (ExceptionIsNotXMLConform $e){
     $userInterface-&gt;openXMLEditor();
}
?&amp;gt;
&lt;/pre&gt;Seperti yang bisa kita lihat, fungsi pada contoh pertama untuk put xml to file jadi lebih loose coupled dan mudah diimplementasikan di berbagai macam kebutuhan. Kolega kita yang ingin mengerjakan UI untuk browser biasa misalnya bisa melakukan seperti code diatas, hanya saja object nya bukan new MobileUserInterface() tapi new StandardUserInterface() misalnya.&lt;br /&gt;
&lt;br /&gt;
Dalam try{} block kolega kita juga bisa untuk tidak hanya menulis code yang akan menangkap exception dari object kita, tapi juga dari object lain. Dalam arti di dalam try{} block bisa terjadi algoritma yang cukup komplex.&lt;br /&gt;
&lt;br /&gt;
Misalnya saja requierement yang diatas ditambahkan lagi:  &lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Setelah berhasil put xml to string, maka save informasi tersebut ke dalam database,&lt;/li&gt;
&lt;li&gt;lalu kirimkan email kepada orang yang bersangkutan.&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;Database object dan email object, bisa jadi memiliki exception mereka sendiri yang sudah selayaknya ditangkap entah itu connection not avaliable, column or table not exist, database not exist, sql statement syntax error dan sejenisnya.&lt;br /&gt;
&lt;br /&gt;
Pada email object bisa jadi, mail server not responding, atau email address invalid atau email address not exist in database, dan sejenisnya.&lt;br /&gt;
&lt;br /&gt;
Exception tersebut juga bisa ditangkap dan dilakukan sesuatu(handle) terhadap exception tersebut. Bisa jadi hanya menampilkan error. Tapi seperti contoh di atas, tidak selalu exception itu merupakan sebuah error.  Berikut adalah contoh pengembangan code yang diatas: &lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;&amp;lt;?php
$db = DBObject::getInstance();

try{
   $putXMLToFile = new PutXMLToFile();
   $putXMLToFile-&gt;putThatThing($file, $string);

   $db-&gt;beginTransaction();
   $modelSomething-&gt;insertSomething();
   $modelAnything-&gt;updateAnything();

   $email = Email::getInstance();
   $email-&gt;setTo($emailAddressTo);
   $email-&gt;setSubject($emailSubject);
   $email-&gt;setMessage(emailMessage);
   $email-&gt;send();

   $db-&gt;endTransaction();

}catch (ExceptionIsNotAFile $e){
    $userInterface-&gt;openFileManager();
}catch (ExceptionFileNotReadable $e){
     $userInterface-&gt;openFileAccessManager();
}catch (ExceptionFileNotWriteable $e){
     $userInterface-&gt;openFileAccessManager();
}catch (ExceptionIsNotAString $e){
     $userInterface-&gt;showError($e-&gt;getMessage());
}catch (ExceptionIsNotXMLConform $e){
     $userInterface-&gt;openXMLEditor();
}catch (ExceptionDBException $e){
     $db-&gt;rollbackTransaction();
     $userInterface-&gt;showError($e-&gt;getMessage());
}catch (ExceptionEmailException $e){
     $db-&gt;rollbackTransaction();
     $userInterface-&gt;showError($e-&gt;getMessage());
}
?&amp;gt;
&lt;/pre&gt;Semoga tulisan gue bisa memberi sedikit pencerahan.</description><link>http://arthur.purnama.de/2008/12/pengecualian-di-php-5.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihIf4VTcpXmvKN3asGBRAA9cTW1lCZdxIPZIhOjclpCigcLGDJFT8VdzIGfqMGAnFArmkLrKygtrNG_xorvLZ-uSd_qNV_huD8-V5W39aC8c7wpLFf15-2uzF4JOeZRcgBfkoyUTQG2zQ/s72-c/995000_46458615_2.jpg" height="72" width="72"/><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-6560053668191780410</guid><pubDate>Sun, 07 Dec 2008 17:46:00 +0000</pubDate><atom:updated>2014-01-02T23:12:47.662+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Publication</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Konsep Visibility pada PHP 5</title><description>&lt;div class=&quot;separator&quot; style=&quot;float: left; clear: both;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__E1CDJRJ-xCee-eK-MV-kMFY0OV8Zp6-Cf0jIOdN36KCFA2iM6xTEZfaL7dV0R-lj1QP4VTWGG3O7dQozoDtMdKM1RnOLIY6ds3a5iAESa4xf2CMsqeDSuYt1er-5jdRghq00SjArt0/s1600-h/961824_85419476_2.jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 117px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__E1CDJRJ-xCee-eK-MV-kMFY0OV8Zp6-Cf0jIOdN36KCFA2iM6xTEZfaL7dV0R-lj1QP4VTWGG3O7dQozoDtMdKM1RnOLIY6ds3a5iAESa4xf2CMsqeDSuYt1er-5jdRghq00SjArt0/s200/961824_85419476_2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5277130549593284770&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Beberapa waktu lalu di milist PHP-UG ada yang nanya tentang &lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/message/37977&quot; target=&quot;_blank&quot;&gt;konsep Visibility pada PHP 5&lt;/a&gt;. Banyak juga yang sudah menjawab. Dan menurut gue jawabannya juga bagus-bagus. Tapi gue juga ikutan jawab, karena sebagian besar jawabannya tidak mengacu pada konsep dasar tentang Visibility secara umum dalam pemrograman berorientasi objekt.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/message/38148&quot; target=&quot;_blank&quot;&gt;Tulisan gue di milist&lt;/a&gt;, gue masukin di blog sebagai arsip gue pribadi. Mungkin juga berguna buat yang lain kalau-kalau satu saat ingin cari tahu mengenai konsep visibility. Kalau ada kritik, koreksi atau tambahan, tentunya gue dengan senang hati menerima.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot; language=&quot;javascript&quot; &gt;&lt;/script&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; /&gt; &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; /&gt; &lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all() &lt;/script&gt;&lt;br /&gt;
Secara umum penggunaan Visibility pada PHP 5 bisa dilihat langsung di &lt;a href=&quot;http://www.php.net/manual/en/language.oop5.visibility.php&quot; target=&quot;_blank&quot; &gt;dokumentasinya PHP 5&lt;/a&gt;. Setelah kita tahu bagaimana visibility berfungsi pada function, atau member variabel, gue rasa penting juga sebenarnya bertanya, kenapa sebenarnya ada visibility? Kapan pakainya? Buat kalian yang beranjak dari PHP &amp;lt; 5, maka pertanyaan yang sebenarnya juga cukup menarik, kenapa PHP sekarang support visibility?&lt;br /&gt;
&lt;br /&gt;
Private, public, protected merupakan bagian dari prinsip &quot;information hiding&quot; dalam ilmu komputer. Kalau ingin tahu apa itu prinsip &quot;information hiding&quot; silahkan lihat di &lt;a href=&quot;http://en.wikipedia.org/wiki/Information_hiding&quot; target=&quot;_blank&quot;&gt;wikipedia&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Disitu hanya dijelaskan secara gamblang saja. Ada banyak sekali hal yang bersangkutan dengan &quot;information hiding&quot;, dan pada kesempatan ini gue pengen coba untuk menjelaskan hanya pada bagian visibility.&lt;br /&gt;
&lt;br /&gt;
Menjelaskan topik informatika paling enak pake analogi, jadi gue berusaha beranalogi. Gue coba2 cari di google analogi yang lebih pas, tapi gue gak ketemu. Kalau ada yang bisa memberikan analogi yang lebih pas, silahkan dibagi ^^.&lt;br /&gt;
&lt;br /&gt;
Analogi gue kali ini adalah mobil. Mobil punya setir, punya starter, punya perseneling, dan minimal punya pedal gas dan rem (kopling untuk transmisi manual). Semua mobil punya &quot;fungsi&quot; ini. Dan semua pengemudi tahu dan &quot;berharap&quot; bahwa fungsi tersebut ada di dalam sebuah mobil. Keberadaan fungsi2 tersebut dalam sebuah mobil bisa kita lihat sebagai bentuk &quot;public visibility&quot;.&lt;br /&gt;
&lt;br /&gt;
Mobil bisa jalan karena ada mesinnya. Masalahnya disini adalah, bagaimana bentuk mesinnya, bagaimana cara kerjanya. atau. apakah sebenarnya mobil tersebut jalan pakai mesin? Hal itu semua sudah bukan urusan pengemudi mobil. Hal itu sudah urusan perusahaan yang bikin itu mobil. Bisa jadi mas &lt;a href=&quot;http://www.google.com/search?source=ig&amp;hl=en&amp;rlz=&amp;=&amp;q=joko+suprapto&amp;btnG=Google+Search&amp;aq=0&amp;oq=joko+suprapto&quot; target=&quot;_blank&quot;&gt;Joko Suprapto&lt;/a&gt; punya methode lain buat bikin mobil bisa jalan ^^ (Ilmu gaib mungkin? ^^ ). &lt;br /&gt;
&lt;br /&gt;
Fungsi mesin tidak hanya sekedar urusan perusahaan, akan tetapi mesin merupakan bagian paling penting dari inovasi perusahaan. Apakah mobil tersebut bisa ngebut, irit bensin, tidak berisik, ramah lingkungan, semuanya ditentukan dari kerja mesin tersebut. Karena semua jerih payah berpikir para insinyur automobile ada di dalam situ, perusahaan melindungi informasi tersebut, dan ingin agar fungsi tersebut tidak digunakan untuk kepentingan lain, selain untuk menjalankan mobil, ^^ dengan menggunakan fungsi2 &quot;publik&quot; yang sudah didefinisikan (setir, perseneling, pedal, dsb). Pokoknya pengemudi hanya tahu, untuk jalanin sebuah mobil, kudu starter dulu, masukin perseneling. dan kalo injek gas, mobilnya jalan, kalo di rem berhenti. Fungsi mesin disini bisa kita lihat sebagai bentuk &quot;private visibility&quot;.&lt;br /&gt;
&lt;br /&gt;
Perusahaan pembuat mobil tahu, bahwa dia gak akan bisa membuat mobil yang sesuai sama selera seluruh umat manusia ^^. Yang satu ingin mobilnya lebih nyaman, yang satu pengen bisa lebih cepat, yang satu ingin lebih irit, yang satu ingin lebih ramah lingkungan, dan lain sebagainya. Maka dari itu perusahaan pembuat mobil membuat beberapa komponen mobil memiliki kesempatan untuk di expand atau dimodifikasi. Entah itu pasang AC, pasang, Nitro, pasang katalisator, ganti jok mobil, ganti velg, diceperin dan lain sebagainya. Spesifikasi dan informasi komponen-komponen yang bisa di expand atau dimodifikasi tersebut diberikan oleh perusahaan mobil, ke bengkel2 mobil. Apakah itu bengkel resmi ato bukan untuk sementara tidak relevan ^^. &lt;br /&gt;
&lt;br /&gt;
Seperti halnya mesin pada perusahaan mobil. sebagai pengemudi, kita tetap tidak tahu menahu tentang komponen ini. Kita tetap hanya mengetahui fungsi-fungsi publik. Kita tetap mengendarai mobil seperti biasanya. Hanya saja mobil kita mungkin sekarang lebih cepat, lebih irit, lebih nyaman, atau lebih-lebih yang lainnya. ^^. Analogi yang ini bisa kita lihat sebagai bentuk &quot;protected visibility&quot;.&lt;br /&gt;
&lt;br /&gt;
So itu analoginya visibility. Kalo dilihat dari &lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/message/37977&quot; target=&quot;_blank&quot; &gt;subject threadnya&lt;/a&gt; ada yang nanya tentang visibility jenis &quot;global&quot;. Jenis itu sepertinya spesifik di php doang, dimana function berdiri sendiri, tidak dalam sebuah kelas. CMIIW. Agak sulit menganalogikannya dalam kasus mobil diatas, karena paradigma object oriented itu melihat semuanya berupa object. Kalau gue memisalkan fungsi dengan visibility &quot;global&quot; sebagai kunci stang (yang jaman dulu tuh, yang buat dipasang dari setir ke pedal, tauk deh ada yang bisa bayangin kah) gak bisa juga. Karena kunci stang adalah object ^^ yang punya fungsi yaitu - seperti namanya - ngunci setir. ^^ &lt;br /&gt;
&lt;br /&gt;
Setelah panjang berteori fundamental visibility pada pemrogramman berorientasi obyek. sekarang mari kita coba menjawab pertanyaan kenapa ada visibility? Kapan pakainya, dan kenapa PHP sekarang support visibility?&lt;br /&gt;
&lt;br /&gt;
PHP berkembang dari sekedar Personal Home Page &lt;span style=&quot;font-style:italic;&quot;&gt;pre-processor&lt;/span&gt; tools yang dibuat Rasmus Lerdorf, menjadi sebuah &lt;span style=&quot;font-style:italic;&quot;&gt;Full Blown Web Application language&lt;/span&gt;. Gue gak bilang enterprise ^^, karena untuk menjadikannya enterprise gak cukup pengetahuan PHP doang seperti layaknya sodara kita di java dan .net ^^. &lt;br /&gt;
&lt;br /&gt;
Untuk membuat aplikasi, banyak komponen2 yang akan sering digunakan berulang-ulang di setiap project. Daripada setiap kali harus tulis ulang, mendingan dipakai lagi. Muncullah berbagai macam jenis framework di PHP yang umumnya punya tujuan yang sama, yaitu membuat pembangunan aplikasi web menjadi lebih cepat, mudah, dan bug free.&lt;br /&gt;
&lt;br /&gt;
Membuat framework, sama halnya dengan membuat mobil, para developer framework menentukan melalui fungsi apa framework tersebut digunakan (public), fungsi-fungsi apa yang critical dan tidak boleh digunakan untuk kepentingan lain (private), dan fungsi-fungsi apa yang punya kemungkinan untuk di expand atau diganti (protected). Pengguna framework hanya akan dihadapkan dengan fungsi2 yang memiliki visibility public dalam membangun web aplikasinya.&lt;br /&gt;
&lt;br /&gt;
Karena visibility baru di support setelah PHP 5, pembuatan framework memiliki problem dalam penggunaan visibility. Untuk mengantisipasi hal ini, Segala macam bentuk &lt;span style=&quot;font-style:italic;&quot;&gt;code convention&lt;/span&gt; digunakan dalam komunitas framework. Salah satunya adalah &lt;a href=&quot;http://pear.php.net/manual/en/standards.naming.php&quot; target=&quot;_blank&quot;&gt;PEAR convention&lt;/a&gt; yang memberikan tanda strip bawah ( _ ) untuk setiap private member variabel dan private method.&lt;br /&gt;
&lt;br /&gt;
Framework gak selalu harus pakai punya orang. Buat mereka yang bekerja &lt;span style=&quot;font-style:italic;&quot;&gt;product developing&lt;/span&gt;, umumnya punya methode dan fungsi2 proprietary yang juga digunakan dalam pekerjaan sehari-hari. Dalam hal ini bisa jadi masing-masing memiliki &lt;span style=&quot;font-style:italic;&quot;&gt;code convention&lt;/span&gt; sendiri-sendiri.&lt;br /&gt;
&lt;br /&gt;
Sekarang gue mo coba memberikan contoh praktis dalam bentuk code untuk belajar memahami kapan menggunakan dan memilih visibility. Code ini jauh dari sempurna dalam konteks design-nya. Diantara kalian pasti bisa membuat yang jauh lebih baik dari ini. Akan tetapi menurut gue ini bagus untuk membantu memahami prinsip visibility.&lt;br /&gt;
&lt;br /&gt;
Gue mau tetap bergerak di lingkup analogi gue, yaitu mobil. Gue mau membuat sebuah kelas &quot;mobil&quot;. Untuk bisa memahami lebih baik, perlu diketahui bahwa dalam bekerja menggunakan paradigma berorientasi obyek, programmer harus berpikir bahwa code yang dia tulis suatu saat akan &quot;digunakan&quot; oleh orang lain, gue kasih tanda kutip, karena maksudnya disini bukan dimodifikasi atau dirubah.&lt;br /&gt;
&lt;br /&gt;
Untuk itu gue buat skenario sebagai berikut.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Kelas mobil yang gue tulis disini adalah bagian dari sebuah aplikasi game. Anggap saja game balap mobil. Tanggung jawab gue adalah menulis kelas mobil ini dan kelas ini satu saat nanti akan digunakan oleh kolega kerja gue yang memprogramm kelas &quot;pengemudi&quot;. Untuk itu gue udah berdiskusi sama dia, apa fungsi yang harus ada, yang perlu dia ketahui. lalu sama2 bikin daftarnya.  &lt;ul&gt;&lt;li&gt;Fungsi setir. Menerima informasi kiri atau lurus atau kanan (-1, 0 atau 1)&lt;/li&gt;
&lt;li&gt;Fungsi startEngine. Mengirimkan informasi kembali apakah mesin berhasil di starter (true atau false)&lt;/li&gt;
&lt;li&gt;Fungsi stopEngine. mengirimkan informasi kembali apakah mesin berhasil dimatikan (true atau false)&lt;/li&gt;
&lt;li&gt;Fungsi setPerseneling. menerima informasi perseneling (0 sampai 5)&lt;/li&gt;
&lt;li&gt;Fungsi gas. menerima informasi tekanan seberapa besar gas diinjak (0-5)&lt;/li&gt;
&lt;li&gt;Fungsi rem. menerima informasi tekanam seberapa besar rem diinjak (0-5)&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;So cukup. Sisanya dia gak perduli bagaimana gue mengimplementasikannya. Dia sebenarnya juga tidak berhak tahu ^^. Tapi gue berpikir agak jauh ke depan. bisa jadi code gue nanti bagus dan ingin terus dipakai, tapi karena satu dan lain hal, beberapa komponen sudah tidak begitu relevan lagi, baik itu kurang bagus, kurang cepat, atau kurang-kurang yang lainnya. Untuk itu gue akan mencoba mendefinisikan komponen apa yang kira-kira bisa diganti atau ditambah.&lt;br /&gt;
&lt;br /&gt;
Setelah berpikir, maka gue menulis daftarnya.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Fungsi tangkiBensin&lt;/li&gt;
&lt;li&gt;Fungsi knalpot&lt;/li&gt;
&lt;li&gt;Fungsi airConditioner&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;So setelah ini kalo ada fungsi lain yang gue butuh, gue bebas berkreatifitas. Mau berapa banyak kek fungsinya dan namanya apa. Itu sudah terserah gue. Sekarang mari kita buat kelasnya.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;class Mobil{

   private $engineStart = false;
   private $warna = &#39;putih&#39;;
   private $brand = &#39;bmw&#39;;
   private $perseneling = 0;

   public function __construct(){
       echo &#39;objek mobil dibuat&#39;;
       $this-&gt;tangkiBensin();
       $this-&gt;airConditioner();
       $this-&gt;knalpot();
   }

   public function setWarna($warna){
       $this-&gt;warna = $warna;
   }

   public function getWarna(){
       return $this-&gt;warna;
   }

  public function setBrand($brand){
      $this-&gt;brand = $brand;
  }

  public function getBrand(){
      return $this-&gt;brand;
  }

  public function engineStart(){
      $this-&gt;engineStart = true;
  }

  public function engineStop(){
      $this-&gt;engineStart = false;
  }

  public function isEngineStart(){
      return $this-&gt;engineStart;
  }

  public function setPerseneling($perseneling){
      $this-&gt;perseneling = $perseneling;
  }

  public function gas($gas){
      echo &quot;nge-gas dengan tekanan pedal &quot;.$gas;
      $this-&gt;knalpot();
  }

  public function rem($rem){
     echo &quot;nge-rem dengan tekanan pedal &quot;.$rem;
  }

  public function setir($arah){
       switch($arah){
            case -1:
                $this-&gt;moveLeft();
                break;
            case 0:
                $this-&gt;moveStraight();
                break;
           case 1:
                $this-&gt;moveRight();
                break;
           default:
                throw new Exception(&#39;hanya bisa 
                      menerima nilai -1, 0 atau 1&#39;);
       }
  }

  protected function tangkiBensin(){
        echo &quot;tangki bensin muat 60 liter&quot;;
  }

  protected function knalpot(){
       echo &quot;knalpot standard&quot;;
  }

 protected function airConditioned(){
     echo &quot;gak punya AC&quot;;
 }

 private function moveLeft(){
     //TODO: implement how to move left
 }

 private function moveRight(){
     //TODO: implement how to move right
 }

 private function moveStraight(){
     //TODO: implement how to move Straight
 }

}
&lt;/pre&gt;Okay, mari kita lihat dengan seksama. Pertama-tama member variabel. Gue nambahin warna dan brand, hanya sekedar tambahan saja untuk mendefinisikan personalitas sebuah objekt. Yang mau gue tunjukin disini adalah penggunaan visibility private pada getter dan setter (misal setBrand dan getBrand). &lt;br /&gt;
&lt;br /&gt;
Tentu saja kita bisa pasang visibility apa saja pada member variabel. Tapi sudah merupakan best practice, bahwa member variabel itu sebaiknya private atau protected, dan member variabel tersebut hanya bisa dibaca dan ditulis melalui getter dan setter methodenya (kalo gue gak salah, best practice ini pelopornya java beans CMIIW). Apa alasannya? Dengan ini kita memiliki kontrol penuh atas nilai yang diberikan kepada member variabel tersebut. Sebagai contoh, apabila kita hanya punya warna atau merk tertentu, kita bisa bikin validator di dalam set methode untuk menentukan apakah warna yang diberikan pada argument tersebut valid atau tidak.&lt;br /&gt;
&lt;br /&gt;
Mungkin contoh warna dan merk tidak begitu critical. Tapi coba bayangkan kalau perseneling member variabel gue pasang public, terus temen gue pasang angka 6, dengan cara $mobilObj-&gt;perseneling = 6; padahal mobil gue cuma bisa nerima sampe 5. Gue gak mau bayangin apa yang akan terjadi ^^. Apabila memang dibutuhkan, maka gue dengan mudah bisa implementasikan if atau switch statement di methode setPerseneling untuk menghindari hal seperti ini.&lt;br /&gt;
&lt;br /&gt;
Selain itu, untuk perseneling, gue gak memberikan methode getPerseneling. dalam hal ini, gue gak punya alasan konkrit. Tapi bisa saja terjadi dalam pekerjaan, bahwa kita tidak mau orang membaca kembali nilai yang sudah dia berikan ^^.&lt;br /&gt;
&lt;br /&gt;
Seperti yang bisa dilihat, gue membuat fungsi tangkiBensin, knalpot dan airConditioned sebagai protected karena gue merasa bagian itu satu saat bisa di modifikasi oleh orang lain. Sisanya fungsi moveLeft, -Right, dan -Straight merupakan contoh implementasi gue tentang bagaimana gue menjalankan mobil. Mungkin bisa lebih dari ini fungsinya. Tapi ini sekedar contoh saja. Fungsi ini digunakan oleh methode setir dimana dia memvalidasi argument yang diberikan menggunakan switch statement, dan melempar exception apabila argument tersebut tidak valid.&lt;br /&gt;
&lt;br /&gt;
Exception gak akan gue jelasin disini ^^, jadi makin banyak entar ^^. Gue sudah pernah &lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/message/22478&quot; target=&quot;_blank&quot;&gt;jelasin tentang exception&lt;/a&gt; deh ^^.&lt;br /&gt;
&lt;br /&gt;
Setelah kelas mobil gue kelar, gue kasih ke temen gue. Dan akhirnya dia bisa pake deh. Bagaimana dia makenya, kira2 begini: &lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;class Pengemudi{

      //member variabel pengemudi
      private $mobilObj;

     //lots of code implementing pengemudi

    public function setMobil(Mobil $mobilObj){
        $this-&gt;mobilObj = $mobilObj;
    }

    public function nyetirUgalUgalan(){
         if(!$this-&gt;mobilObj-&gt;isEngineStart()){
              $this-&gt;mobilObj-&gt;engineStart();
         }
         $this-&gt;mobilObj-&gt;setPerseneling(1);
         $this-&gt;mobilObj-&gt;gas(5);
         try{
             $this-&gt;mobilObj-&gt;setir(-1);
             $this-&gt;mobilObj-&gt;setir(1);
             $this-&gt;mobilObj-&gt;setir(-1);
             $this-&gt;mobilObj-&gt;setir(1);
         }catch(Exception $e){
             echo $e-&gt;getMessage();
             print_r($e-&gt;getTrace());
         }
         $this-&gt;mobilObj-&gt;rem(5);
         $this-&gt;mobilObj-&gt;setPerseneling(0);
         $this-&gt;mobilObj-&gt;engineStop();
    }

}
&lt;/pre&gt;Ok gue harap semua tahu apa yang code diatas lakukan. Sedikit informasi, bahwa gue melakukan &lt;span style=&quot;font-style:italic;&quot;&gt;Type Hinting&lt;/span&gt; pada methode setMobil. Untuk jelasnya bisa baca &lt;a href=&quot;http://www.php.net/language.oop5.typehinting&quot; target=&quot;_blank&quot;&gt;dokumentasinya PHP&lt;/a&gt;. &lt;span style=&quot;font-style:italic;&quot;&gt;Type Hinting&lt;/span&gt; berguna sekali, membuat code jadi lebih robust dan stabil. Di tempat lain (biasanya istilahnya controller atau main methode kalo di java, di php katakanlah index.php) ada code yang membuat objekt sang pengemudi, membuat objekt mobil dan memberikannya kepada si pengemudi. Kira-kira begini: &lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;$mobilObj = new Mobil();
$mobilObj-&gt;setWarna(&#39;orange&#39;);
$mobilObj-&gt;setBrand(&#39;Metro Mini&#39;);
$pengemudi = new Pengemudi();
$pengemudi-&gt;setMobil($mobilObj);
$pengemudi-&gt;nyetirUgalUgalan();
&lt;/pre&gt;Di kemudian hari, kelas gue sudah mulai banyak dipakai di dalam system. Akan tetapi system tersebut butuh satu mobil lagi. Bedanya sekarang, mobil tersebut harus pasang AC, punya knalpot remus ^^ dan tangki bensin nya bisa isi 100 liter. Lebih canggihnya lagi, mobil tersebut gak cuma bisa belok ke kiri, kanan dan lurus, tapi sekarang bisa keatas dan kebawah (bisa terbang ^^. Ga usah protes. Suka-suka gue. Aplikasi gue kok :P). Mobil tersebut akan digunakan oleh pengemudi baru yang jauh lebih berpengalaman. Istilahnya sekarang &quot;pilot&quot;. Mobil-mobil yang sudah dimiliki oleh pengemudi lainnya tidak boleh diganggu-gugat. Mereka sudah senang dengan keadaannya tersebut (prinsip &lt;span style=&quot;font-style:italic;&quot;&gt;never touch a running system&lt;/span&gt;). So apa yang gue lakukan? Gue akan bikin satu class mobil baru yang mewarisi fungsi-fungsi class mobil gue yang lama. Yang suka pake bahasa inggris, pasti kenal yang istilahnya &lt;span style=&quot;font-style:italic;&quot;&gt;inheritance&lt;/span&gt;.^^&lt;br /&gt;
&lt;br /&gt;
So mari, coba kita bikin. &lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;class MobilBaru extends Mobil{

  public function setir($arah){
       switch($arah){
            case -1:
                $this-&gt;terbang(&#39;kiri&#39;);
                break;
            case 0:
                $this-&gt;terbang(&#39;kanan&#39;);
                break;
           case 1:
                $this-&gt;terbang(&#39;atas&#39;);
                break;
           case -2:
                 $this-&gt;terbang(&#39;bawah&#39;);
                 break;
           case 2:
                 $this-&gt;terbang(&#39;lurus&#39;);
                 break;
           default:
                throw new Exception(&#39;hanya bisa menerima nilai -2,
-1, 0, 1 atau 2&#39;);
       }
  }

  protected function tangkiBensin(){
        echo &quot;tangki bensin muat 100 liter&quot;;
  }

  protected function knalpot(){
       echo &quot;knalpot remus&quot;;
  }

 protected function airConditioned(){
     echo &quot;pake AC Central Daikin ^^&quot;;
 }

 private function terbang($arah){
     //TODO: implement how to fly
 }

}
&lt;/pre&gt;So mari kita cerna pelan-pelan. Code gue sekarang agak lebih sedikit. Kenapa? Karena sebagian besar fungsi, sudah di implementasikan di parent class. Bahkan gue ga nulis constructor. Yang gue lakukan adalah memodifikasi methode sesuai tugas gue. Perhatikan bahwa gue meng-&lt;span style=&quot;font-style:italic;&quot;&gt;override&lt;/span&gt; methode setir, tangkiBensin dan knalpot. Perlu diperhatikan disini, apabila gue melakukan override pada methode setir, maka fungsi setir disini tidak dapat membaca private method yang ada di kelas mobil. Ini bukan sesuatu yang buruk, tapi justru baik. Karena private methode tersebut diperuntukkan khusus pada kelas Mobil.&lt;br /&gt;
&lt;br /&gt;
Sekarang kita membuat kelas MobilBaru dimana behaviornya berbeda sekali (bisa terbang ^^) meskipun masih masuk definisi mobil. Maka dari itu, bagaimana setir di implementasikan supaya mobil tersebut bisa bersikap sesuai yang diharapkan (terbang ^^), ditulis method baru, dan diberikan visibility private.&lt;br /&gt;
&lt;br /&gt;
Disini sebenarnya, sekali lagi bebas saja mau berapa methodenya, namanya apa, dsbnya. Sebagai contoh gue bikin satu methode namanya terbang. Sekarang bagaimana bentuk kelas pengemudinya? yaa kira2 begini lah: &lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;class Pilot{

      //member variabel pilot
      private $mobilObj;

     //lots of code implementing pilot

    public function setMobil(MobilBaru $mobilObj){
        $this-&gt;mobilObj = $mobilObj;
    }

    public function terbangUgalUgalan(){
         if(!$this-&gt;mobilObj-&gt;isEngineStart()){
              $this-&gt;mobilObj-&gt;engineStart();
         }
         $this-&gt;mobilObj-&gt;setPerseneling(1);
         $this-&gt;mobilObj-&gt;gas(5);
         try{
             $this-&gt;mobilObj-&gt;setir(1);
             $this-&gt;mobilObj-&gt;setir(-2);
             $this-&gt;mobilObj-&gt;setir(1);
             $this-&gt;mobilObj-&gt;setir(-2);
         }catch(Exception $e){
             echo $e-&gt;getMessage();
             print_r($e-&gt;getTrace());
         }
         $this-&gt;mobilObj-&gt;rem(5);
         $this-&gt;mobilObj-&gt;setPerseneling(0);
         $this-&gt;mobilObj-&gt;engineStop();
    }

}
&lt;/pre&gt;So sekarang agak ribet. Mohon dicerna pelan-pelan. Perhatikan pada setMobil, type hint gue sekarang MobilBaru, artinya, object yang dioper pada argument cuma boleh berupa instanz dari kelas MobilBaru. Ini berguna sekali. Coba bayangkan kalau type hint nya tetap Mobil. Dia bakal sama sekali gak protes, ketika tuh pilot kita kasih objekt MobilBaru karena MobilBaru adalah sebuah mobil ^^ (inherit class Mobil). Berikutnya, waktu kita kasih dia object Mobil, pada bagian setMobil(), dia masih gak protes, karena Mobil adalah sebuah mobil (astaga...). Tapi giliran dia mo terbangUgalUgalan(). Mobilnya bakal protes. kenapa? karena dia gak mengenal argument -2 ^^.  Kalo masih bingung. mari kita lihat code yang menggunakan kelas ini :  &lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;//Mari kita anggap methode setMobil pada kelas Pilot 
//bentuknya begini:
//   public function setMobil(Mobil $mobilObj){
//        $this-&gt;mobilObj = $mobilObj;
//    }

//Perhatikan type hint nya Mobil.

//so sekarang main method atau controller atau index.php nya

$mobilObj = new MobilBaru();
$mobilObj-&gt;setWarna(&#39;orange&#39;);
$mobilObj-&gt;setBrand(&#39;Metro Mini&#39;);
$pengemudi = new Pilot();
$pengemudi-&gt;setMobil($mobilObj);
$pengemudi-&gt; terbangUgalUgalan(); // &lt;&lt; No error

$mobilObj = new Mobil();
$mobilObj-&gt;setWarna(&#39;orange&#39;);
$mobilObj-&gt;setBrand(&#39;Metro Mini&#39;);
$pengemudi = new Pilot();
$pengemudi-&gt;setMobil($mobilObj);
$pengemudi-&gt; terbangUgalUgalan(); // &lt;&lt; error: 
                                  // hanya bisa menerima
                                  // nilai -1, 0 atau 1
&lt;/pre&gt;
So gue sudah selesai. panjang juga ya? ^^ Sekali lagi, gue harap semoga bermanfaat.</description><link>http://arthur.purnama.de/2008/12/konsep-visibility-pada-php-5.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__E1CDJRJ-xCee-eK-MV-kMFY0OV8Zp6-Cf0jIOdN36KCFA2iM6xTEZfaL7dV0R-lj1QP4VTWGG3O7dQozoDtMdKM1RnOLIY6ds3a5iAESa4xf2CMsqeDSuYt1er-5jdRghq00SjArt0/s72-c/961824_85419476_2.jpg" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7222188647511650027</guid><pubDate>Wed, 16 Jul 2008 07:18:00 +0000</pubDate><atom:updated>2014-01-02T23:15:02.065+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>File Upload Progress dengan PHP 5 dan APC</title><description>&lt;div class=&quot;separator&quot; style=&quot;float: left; clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmCuyXYND4H_wN-Dv_SvMA2ZYhAXE09xmgBDF0KkkM3JLKFzPYhtSBq_X7wGvLJjfgt_oeUxygUToNJu7d6nr33kPgg7VhMfu8AGL9J34AOJDOSTzoIa7ypxE8f8fYYvpO45VWTvn9W90/s1600-h/progress_php.png&quot; imageanchor=&quot;1&quot; style=&quot;border: 0pt none ; background-color: transparent; margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBcJMgR7cMyvt41LKorBzPM_yk4CbjlGAJ5BZqIV_WtKL3wnbvs3BPbpMKwPenu8lc7-ouwcLnaMKOBpWhrEV4H24Mmdq5yydblZFHgczbS6ViBmRaHE3TCK1LK2IjBUxq4fzGkbsKjTg/s400-r/progress_php.png&quot; style=&quot;border: 0pt none ;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Beberapa hari lalu, secara nggak sengaja gue baca-baca &lt;a href=&quot;http://www.php.net/releases/5_2_0.php&quot; target=&quot;_blank&quot;&gt;PHP 5.2.0 Release Announcement&lt;/a&gt; (tumben ^^) dan ngelihat kalimat ini di daftar &lt;i&gt;key features&lt;/i&gt; nya &quot;&lt;i&gt;Hooks for tracking file upload progress were introduced&lt;/i&gt;&quot;. Ho ho ho &lt;i&gt;was ist das&lt;/i&gt;? Penasaran banget, gue coba tanya-tanya kang google, dan mampir di &lt;a href=&quot;http://the-stickman.com/web-development/php/upload-progress-tracking-in-php52/&quot; target=&quot;_blank&quot;&gt;satu blog&lt;/a&gt; yang bertanya di PHP Development mailing list tentang fungsi tracking yang dijanjikan tersebut. Yang menjawab tidak lain dan tidak bukan adalah &lt;a href=&quot;http://lerdorf.com/&quot; target=&quot;_blank&quot;&gt;Rasmus Lerdorf&lt;/a&gt; sendiri, dan menyatakan bahwa fungsi tersebut masih berada pada level C dan membutuhkan fungsi pendukung untuk digunakan dalam php.&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot;&gt;&lt;/script&gt;&lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;&lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all()&lt;/script&gt;&lt;br /&gt;
Sudah lama gue coba cari-cari cara untuk bisa menampilkan laporan tentang kemajuan proses sewaktu meng-&lt;i&gt;upload&lt;/i&gt; file. Gue sebenarnya cari cara, dimana menulis codenya itu murni dalam PHP. Tapi sayangnya kebanyakan yang gue temuin itu &lt;a href=&quot;http://webscripts.softpedia.com/script/Internet-Browsers-C-C/FTP/LightLoader-44313.html&quot; target=&quot;_blank&quot;&gt;menggunakan cgi dan ditulis dalam Perl&lt;/a&gt;. Sayangnya gue gak begitu ngerti Perl, dan gue kurang suka sama bahasanya karena &quot;terlalu dinamis&quot;, sehingga membuat code yang ditulis cepat untuk menjadi  sulit dibaca.&lt;br /&gt;
&lt;br /&gt;
Gue juga sempat coba pakai &lt;a href=&quot;http://digitarald.de/project/fancyupload/&quot; target=&quot;_blank&quot;&gt;Fancyupload &lt;/a&gt;yang ditulis oleh &lt;a href=&quot;http://digitarald.de/&quot; target=&quot;_blank&quot;&gt;Harald Kirschner&lt;/a&gt;, sebuah &lt;i&gt;multi file uploader&lt;/i&gt; yang bekerja menggunakan Flash. Fancyupload ini gue lihat juga dipakai sama &lt;a href=&quot;http://www.joomla.org/&quot; target=&quot;_blank&quot;&gt;Joomla!&lt;/a&gt; CMS. Sayangnya ada 2(dua) kekurangan yang menurut gue cukup penting. Fancyupload ini tidak jalan di mac, dan setiap data yang di upload&lt;i&gt; content-type&lt;/i&gt; nya pasti &quot;application/octet-stream&quot;, bikin sebel. Biasanya gue kalo periksa file yang di upload, gue pasti periksa berdasarkan &lt;i&gt;extension &lt;/i&gt;dan &lt;i&gt;content-type&lt;/i&gt; nya, kalo beda biasanya filenya tidak gue terima.&lt;br /&gt;
&lt;br /&gt;
Rasmus sendiri, menurut blog tersebut, langsung menyatakan bahwa dia telah menulis fungsi pendukung tersebut di dalam &lt;a href=&quot;http://www.php.net/apc&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;Alternative PHP Cache&lt;/i&gt;&lt;/a&gt;, sebuah PHP &lt;i&gt;library &lt;/i&gt;yang merupakan bagian dari &lt;i&gt;PHP Extension Community Library &lt;/i&gt;(PECL). &lt;a href=&quot;http://progphp.com/progress.php&quot; target=&quot;_blank&quot;&gt;Contohnya&lt;/a&gt;, beserta &lt;a href=&quot;http://progphp.com/progress.phps&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;source code&lt;/i&gt;&lt;/a&gt; nya pun langsung diberikan. Tapi, menurut gue, sialnya, dia menulis contohnya menggunakan &lt;a href=&quot;http://developer.yahoo.com/yui/&quot; target=&quot;_blank&quot;&gt;Yahoo! User Interface Framework&lt;/a&gt; dan gak pake komentar. Bukannya gue gak suka sama framework. Tapi menurut gue, kurang bijaksana sekali memberikan contoh code menggunakan framework, gak peduli se&lt;i&gt;-straightforward&lt;/i&gt; apapun contohnya. Dan untuk sebuah contoh code, menurut gue lagi, komentar itu luar biasa pentingnya untuk mengerti &lt;i&gt;step-by-step&lt;/i&gt; apa saja yang terjadi, atau mengapa terjadi, di dalam code tersebut.&lt;br /&gt;
&lt;br /&gt;
Oleh karena itu, gue mau mencoba untuk membuat versi yang lebih sederhana, tanpa framework apapun dan penuh komentar ^^. Dalam kesempatan ini gue mau coba jabarkan dari awal, mulai dari menginstall APC modul itu sendiri, mengkonfigurasi modul tersebut, hingga menggunakannya.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Instalasi dan Konfigurasi APC&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Untuk menggunakan fungsi &lt;i&gt;file upload tracker&lt;/i&gt; menggunakan APC, kita butuh php 5.2+. Gue sudah mencoba menginstall APC ini diatas Windows dan Debian &lt;i&gt;based &lt;/i&gt;Linux. Untuk Windows kita harus mendownload APC library secara &lt;a href=&quot;http://pecl4win.php.net/ext.php/php_apc.dll&quot; target=&quot;_blank&quot;&gt;manual&lt;/a&gt;.  &lt;a href=&quot;http://www.php.net/downloads.php&quot; target=&quot;_blank&quot;&gt;PECL zip package&lt;/a&gt; yang disediakan oleh php.net tidak mengikutsertakan library APC dalam distribusinya.&lt;br /&gt;
&lt;br /&gt;
Setelah di download php_apc.dll tersebut tinggal dimasukkan ke dalam &lt;i&gt;extension directory&lt;/i&gt; yang telah di definisikan di dalam php.ini. Untuk menginstall APC di dalam Debian based Linux gue menggunakan &lt;a href=&quot;http://baheyeldin.com/technology/linux/installing-php-apc-on-ubuntu-dapper-and-debian.html&quot; target=&quot;_blank&quot;&gt;tutorial yang ini&lt;/a&gt;. Untuk install di distribusi linux yang lain dan &lt;i&gt;Operating System&lt;/i&gt; yang lain silahkan cari di google. Kesuksesan dan kegagalan instalasi biasanya dipengaruhi berbagai macam aspek, yang tidak semuanya gue tahu dan tidak bisa gue jabarkan panjang lebar disini.&lt;br /&gt;
&lt;br /&gt;
Pokoknya setelah kalian berhasil menginstall APC tersebut, maka kita harus mengatur konfigurasinya di dalam php.ini. Yang pertama adalah mendaftarkan &lt;i&gt;library &lt;/i&gt;tersebut dalam daftar extension supaya dikenal oleh PHP.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot; name=&quot;code&quot;&gt;extension=php_apc.dll
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Di linux tidak berbeda jauh&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot; name=&quot;code&quot;&gt;extension=apc.so
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Setelah ini, kita harus menyalakan fungsi RFC 1867, dan tergantung kalian ingin mencoba file upload dimana, lokal server atau remote server, ada beberapa perbedaan dalam konfigurasinya supaya nanti codenya bisa di test. Gue akan kasih lihat disini konfigurasi lokal server gue yang gue sadur dari IBM yang &lt;a href=&quot;http://www.ibm.com/developerworks/library/os-php-v525/index.html&quot; target=&quot;_blank&quot;&gt;membahas thema yang sama&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot; name=&quot;code&quot;&gt;...
post_max_size = 400M
...
upload_max_filesize = 400M
...
[APC]
apc.rfc1867 = on
apc.max_file_size = 200M
...
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Mari kita lihat, gue merubah nilai maximum file size diatas 200M, kenapa? Karena apabila kita mengupload file di lokal server, maka file tersebut ter-upload begitu cepatnya, sehingga APC tidak sempat bereaksi untuk menghitung kemajuannya. Oleh karena itu untuk mengetest di lokal server kita butuh file yang cukup besar, biasanya diatas 150M. Oleh karena itu juga, kita butuh merevisi nilai maximum file size di php.ini. Untuk remote server atau produktif server, kita hanya perlu menyalakan fungsi RFC 1867 saja, dalam arti, kita hanya perlu menambahkan  &quot;apc.rfc1867 = on&quot; di dalam php.ini kita. Selebihnya bisa dibiarkan sesuai nilai standardnya.&lt;br /&gt;
&lt;br /&gt;
Untuk mengetest apakah semua instalasi dan konfigurasi berjalan dengan baik dan benar, maka setelah restart apache kita harung menengok phpinfo(). Apabila disitu terdapat informasi tentang APC seperti &lt;i&gt;screenshot&lt;/i&gt; dibawah, maka apc sudah terinstall dengan benar dan kita bisa mulai menggunakannya.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4nLMoZvO5yWXH_U74pNrHC7QBtGxPovTP6GcWLPDOWFlBTA51hXZ6cyDhsBrlA-lj1kExEqWPqoqxdD3JmOQ-Qqs0Ur0gBcMvDbIJ8jgOM6ojN3Unp7nvM70dCv1lmtM4E_5Q4CaLAw/s1600-h/apc_info_php.png&quot; imageanchor=&quot;1&quot; style=&quot;border: 0pt none ; background-color: transparent; margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_VioVvCNQI0axyGy0AA4qLqiGfBH5Zq8HID2Vi9pdIrO1UVttUAlo06JPmF747y7Cs5o7f-MhEmr8vNg0NIA6FQZ7ASIIEgsiL5hT4lCpl0aPk_EO-4PT7c12rF59fii2HMwcJruUxMY/s400-r/apc_info_php.png&quot; style=&quot;border: 0pt none ;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Kalau kalian ingin tahu lebih lanjut tentang arti dan fungsi dari masing-masing konfigurasi APC silahkan membaca &lt;a href=&quot;http://www.php.net/manual/en/apc.configuration.php&quot; target=&quot;_blank&quot;&gt;dokumentasinya&lt;/a&gt;. Sekarang kita bisa memulai untuk bereksperimen menampilkan informasi proses upload file. Sekedar informasi, semua code yang akan gue tulis, baik itu php, html atau javascript code, berada dalam satu file, yaitu upload_progress.php. Hal ini gue lakukan sebenarnya hanya untuk kemudahan saja dalam mengerti penggunaan APC. Kalau kalian sudah mengerti, silahkan implementasikan dengan cara kalian sendiri-sendiri, dan gunakan Framework apa saja yang kalian suka.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Upload Form&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Mari kita bikin upload form yang sederhana saja.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: html&quot; name=&quot;code&quot;&gt;&amp;lt;form action=&quot;upload_progress.php&quot; enctype=&quot;multipart/form-data&quot; 
      id=&quot;upload_form&quot; method=&quot;post&quot; 
      onsubmit=&quot;postForm(&#39;upload_form&#39;); 
      return false;&quot; target=&quot;hiddenframe&quot;&amp;gt;
&amp;lt;input id=&quot;progress_key&quot; name=&quot;APC_UPLOAD_PROGRESS&quot; 
       value=&quot;&amp;lt;?php echo uniqid()?&amp;gt;&quot; type=&quot;hidden&quot;&amp;gt;
&amp;lt;input id=&quot;test_file&quot; name=&quot;test_file&quot; type=&quot;file&quot;&amp;gt;
&amp;lt;input value=&quot;Upload!&quot; type=&quot;submit&quot;&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;div id=&quot;progress_win&quot;&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;iframe name=&quot;hiddenframe&quot; style=&quot;display: none;&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
So, selesai. Sekarang mari lihat satu-satu. di baris pertama untuk form tag, kita punya atribut action yang mengacu pada dirinya sendiri apabila form tersebut di submit. Atribute enctype, karena kita ingin mengupload file, atribut method seperti biasa, post. Kita memiliki atribut Id yang pada atribut onsubmit di berikan sebagai parameter kepada fungsi javascript postForm. Dan kita memiliki atribut target, yang memiliki nilai &quot;hiddenframe&quot;. Nilai ini mengacu pada nama iFrame yang didefinisikan di baris 8(delapan).&lt;br /&gt;
&lt;br /&gt;
Dengan menggunakan atribut target pada form tag, maka apabila form tersebut di &lt;i&gt;submit&lt;/i&gt;, proses submit tersebut akan dijalankan di Iframe, sehingga halaman dimana form tersebut berada tidak akan di reload. Dengan atribut onsubmit, maka sebelum form tersebut di submit, maka fungsi yang ada di dalam onsubmit tersebut dijalankan. &lt;i&gt;Return false&lt;/i&gt; sebenarnya menyatakan bahwa setelah menjalankan fungsi tersebut maka gagalkan operasi submit form. Kenapa digagalkan? nanti gue kasih tahu di bagian javascript.&lt;br /&gt;
&lt;br /&gt;
Baris berikutnya kita punya satu hidden input field. Field ini &lt;b&gt;WAJIB&lt;/b&gt; ada apabila kalian ingin menggunakan APC untuk mendeteksi kemajuan upload file. Atribut Id pada input field ini bisa kalian definisikan sesuka kalian, gue definisikan sebagai progress_key. Atribut name harus sesuai dengan konfigurasi APC pada apc.rfc1867_name yang bisa dilihati di phpinfo(). setelah itu kita memiliki atribut value yang gue beri nilai yang unik. Nilai yang unik ini penting untuk orientasi APC ketika memproses kemajuan upload file. Apabila pada waktu bersamaan ada beberapa orang yang mengupload file, katakanlah user A dan B dan kalian memberikan id pada atribut value nya sama, maka APC bisa bingung, 2 progress dari 2 orang berbeda, tapi idnya sama, yang mana punya siapa? ^^&lt;br /&gt;
&lt;br /&gt;
Di baris 6 kita punya div tag. Ini fungsinya sebagai container untuk menampilkan &lt;i&gt;progress bar&lt;/i&gt; nya. Disini gue gak akan menjabarkan cara membentuk progress bar, karena untuk itu sudah banyak tutorialnya, gue hanya akan menunjukkan total prosesnya dalam persen. Sekarang mari kita lihat javascriptnya.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Javascript&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Karena kita akan bekerja menggunakan AJAX, maka mari kita buat fungsi yang mempersiapkan sebuah &lt;i&gt;instance &lt;/i&gt;dari HTTP Request Object, supaya nanti tinggal dipakai. Thema AJAX sendiri gak akan gue bahas panjang lebar. Contoh dan Tutorial bisa lihat di salah satu &lt;a href=&quot;http://arthur.purnama.de/2007/09/ajax-tutorial_14.html&quot; target=&quot;_blank&quot;&gt;artikel dalam blog gue&lt;/a&gt; atau cari di google.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js&quot; name=&quot;code&quot;&gt;function createRequestObject()
   var requestObject;
   requestObject = false;
   if( window.ActiveXObject ){
       for( var i = 5; i; i-- ){
           try{
              if( i == 2 ){
               requestObject = 
                     new ActiveXObject( &quot;Microsoft.XMLHTTP&quot; );   
           }else{       
               requestObject =
                     new ActiveXObject( &quot;Msxml2.XMLHTTP.&quot; + i + &quot;.0&quot; );
           }
           break;
         }catch( excNotLoadable ){                       
               requestObject = false;
         }
       }
   }else{
       requestObject = new XMLHttpRequest();
   }
   return requestObject;
}

var http = createRequestObject();
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
So, dengan ini kita sudah mempersiapkan sebuah &lt;i&gt;instance&lt;/i&gt; dari HTTP Request Object. Sekarang kita buat fungsi postForm() yang akan dipanggil ketika html form yang barusan kita buat di submit.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js&quot; name=&quot;code&quot;&gt;function postForm(formName){
 document.getElementById(formName).submit();
 setTimeout(&#39;updateProgress()&#39;, 100);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Isinya mudah saja. HTML form dengan nama yang didefinisikan di submit. setelah itu kita menunggu 100ms sebelum menjalankan fungsi updateProgress(). Kenapa harus menunggu? Karena file yang di upload butuh waktu untuk mencapai server. Apabila kita tidak menunggu, maka APC tidak memiliki informasi apapun untuk dikirimkan kembali ke kita, dalam hal ini APC akan mengirimkan nilai false. Dan itu sangat tidak baik.&lt;br /&gt;
&lt;br /&gt;
Interval 100ms gue gunakan hanya untuk lokal server. Untuk remote server ada baiknya untuk mendefinisikan interval yang lebih besar, satu hingga dua detik (2000ms) karena pengiriman data dari client hingga ke server bisa memakan waktu lama tergantung kecepatan internet.&lt;br /&gt;
&lt;br /&gt;
Sekarang mari kita lihat apa isi di dalam fungsi updateProgress().&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js&quot; name=&quot;code&quot;&gt;function updateProgress(){
 progress_key = document.getElementById(&#39;progress_key&#39;).value;
 http.open(&quot;GET&quot;, &#39;upload_progress.php?progress_key=&#39;+progress_key, true);
   http.onreadystatechange = function () {
       if (http.readyState == 4) {
           if (http.status == 200) {
             the_object = eval(&quot;(&quot; + http.responseText + &quot;)&quot;);           
             if(!the_object.done){
               result = Math.round(
                         (the_object.current/the_object.total) * 100);
               document.getElementById(&#39;progress_win&#39;).innerHTML = 
                         result +&#39;%&#39;;
               setTimeout(&quot;updateProgress()&quot;,500);
             }else{
               document.getElementById(&#39;progress_win&#39;).innerHTML = &#39;100%&#39;;
             }
           }
       }
   }
 http.send(null);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Disini kita lihat bahwa kita mengirimkan GET Request ke server dengan parameter progress_key yang diambil dari input hidden field yang unik tadi. Server nantinya akan mengirimkan response text berupa &lt;a href=&quot;http://en.wikipedia.org/wiki/JSON&quot; target=&quot;_blank&quot;&gt;JSON&lt;/a&gt;. Response text tersebut akan dirubah menjadi javascript object dengan eval(). Lalu kita check apakah object atribut &quot;done&quot; didefinisikan dalam object. Apabila tidak, maka hitung kemajuannya dalam persen, lalu tampilkan nilainya dalam div container. Setelah itu tunggu beberapa saat, dalam hal ini gue memasang interval 500ms, dan ulangi proses tersebut. &lt;br /&gt;
&lt;br /&gt;
Server akan menambahkan atribut &quot;done&quot; apabila proses upload sudah selesai. Dan apabila ini terjadi, maka angka persen di div container akan ditulis &quot;100%&quot;. Mengenai definisi return array oleh APC silahkan baca &lt;a href=&quot;http://www.php.net/manual/en/apc.configuration.php&quot; target=&quot;_blank&quot;&gt;manualnya &lt;/a&gt;pada bagian RFC1867. Dengan ini javascript kita kelar. Sekarang kita bisa lihat PHP scriptnya.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PHP script&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Disini script kita akan meng-&lt;i&gt;handle &lt;/i&gt;2 macam proses, yang pertama adalah upload file itu sendiri, dan yang kedua adalah membaca kemajuan proses upload.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot; name=&quot;code&quot;&gt;if($_SERVER[&#39;REQUEST_METHOD&#39;]==&#39;POST&#39;) {
  //implement your upload code here
  //e.g. @move_uploaded_file($filename, $destination)
  exit;
} else if(isset($_GET[&#39;progress_key&#39;])) {
  $status = apc_fetch(ini_get(&#39;apc.rfc1867_prefix&#39;).
                         $_GET[&#39;progress_key&#39;]);
  echo json_encode($status);
  exit;
}else{
  //you can implement some code to display error here
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Scriptnya mudah saja apabila request method yang diterima adalah post, maka upload filenya. disini kita bisa memasukkan code yang biasa kita implementasikan kalau kita ingin mengupload file.&lt;br /&gt;
&lt;br /&gt;
Apabila request method nya bukan post, maka periksa apakah GET parameter dengan nama &quot;progress_key&quot; di definisikan, jika ya maka ambil informasi tentang status upload file dengan apc_fetch(). Fungsi ini_get() disini adalah untuk mengambil prefix yang didefinisikan di konfigurasi apc (bisa dilihat di phpinfo()). Setiap file yang di upload dan memiliki hidden field &quot;APC_UPLOAD_PROGRESS&quot; pada formnya, APC bisa mengidetentifisikan kembali melalui prefix yang didefinisikan di php.ini dan value yang didefinisikan di hidden field tersebut.&lt;br /&gt;
&lt;br /&gt;
Fungsi apc_fetch() akan mengirimkan array atau boolean false. Apabila dia mengirimkan array, maka kita akan merubah array tersebut menjadi JSON dengan json_encode() function dan mengirimkannya kembali ke client dalam bentuk plain text. &lt;br /&gt;
&lt;br /&gt;
Jadi deh. Tinggal di test. Source code yang kumplit bisa kalian dapatkan &lt;a href=&quot;http://purnama.de/upload_progress.phps&quot; target=&quot;_blank&quot;&gt;disini&lt;/a&gt; dan di bawah ini hasilnya, kalian bisa langsung coba ^^.&lt;br /&gt;
&lt;br /&gt;
Happy coding.</description><link>http://arthur.purnama.de/2008/07/file-progress-upload-dengan-php-5-dan.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBcJMgR7cMyvt41LKorBzPM_yk4CbjlGAJ5BZqIV_WtKL3wnbvs3BPbpMKwPenu8lc7-ouwcLnaMKOBpWhrEV4H24Mmdq5yydblZFHgczbS6ViBmRaHE3TCK1LK2IjBUxq4fzGkbsKjTg/s72-c-r/progress_php.png" height="72" width="72"/><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-4196396079904141243</guid><pubDate>Fri, 20 Jun 2008 21:02:00 +0000</pubDate><atom:updated>2014-01-02T23:13:33.661+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Portfolio</category><title>Zend PHP 5 Certified Engineer</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0DA0RYkPrU_i5ZTJuhYsP7XOV88NYw6iM4vIujuwVpVX-M1iK4eB3xucwyVEVrmY6dMgAOjxK2IHnWUtihwyr6SGBjpBMRD5QaffLHzeANNV4egHLHyoieA7baUqqqnWNyJ_3pjUu9M/s1600-h/zend_logo.jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0DA0RYkPrU_i5ZTJuhYsP7XOV88NYw6iM4vIujuwVpVX-M1iK4eB3xucwyVEVrmY6dMgAOjxK2IHnWUtihwyr6SGBjpBMRD5QaffLHzeANNV4egHLHyoieA7baUqqqnWNyJ_3pjUu9M/s400/zend_logo.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5214079545836866178&quot; /&gt;&lt;/a&gt; Well, from today i am a proud Zend PHP 5 Certified Engineer. It was not easy though, even with the fact that i already worked with PHP for about 5 years ^^. But there was just some question i not familiar with, because i never use it in my daily work with PHP. Difference between PHP 4 and PHP 5 was asked but it is not so difficult to answer. But some of the PHP specific questions is really hard to answer, especially the questions related to stream functions ^^. The New Object Oriented Paradigm and Security issues was for me the easiest one. &lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt; I took the Exam in Frankfurt am Main, in a Training Center named Brand EDV Training located in Ostbahnhof area. Well from the outside looks not so promising, the building seems so old and dusty. But well Frankfurt is an old town actually, and this is not the downtown.&lt;br /&gt;
&lt;br /&gt;
As i entered the office, it&#39;s looked more and more promising. ^^ Well the reception was very kind. He asked about my ID and asked me to sign some forms about Terms and Condition, Privacy Policy and something like that. He said, i&#39;m not like an Indonesian, more like Chinese. I said, &quot;how can you say that?&quot;. And he said, &quot;because my MOTHER COME FROM INDONESIA.&quot; Huh? cool, well he looks like an Indonesian to me, but more like East Indonesian, maybe Maluku, Timor or somewhere around there. ^^ Definitely not from Java.&lt;br /&gt;
&lt;br /&gt;
Well after some more chit chat, he brought me into some kind of a class room and prepare the exam for me. I had 90 minutes to finish the exam, and i was finish in about 45 minutes. I took a mock exam a week before, and can answer it in about 30 minutes, but the real exam is actually tougher than that.&lt;br /&gt;
&lt;br /&gt;
Anyway this icon is just nice to put on my blog ^^. What about the ZCE title? Should i put that on my name to? along with the German Dipl. Inf.? Boah, it will be too much show off, will it not? &lt;br /&gt;
&lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYWwcKyY-SAAMH3EUa_pvzS8nzbXnUzA4NoHaHRoQ-ADEPLAnD1-4621vYiehi3fhGFOuUHMIRzFq_I7xuVGmyBMK3QEaupNOqBr5Hg6llsH6ehNKp9uKfGaC7OWOrY80_rP5IGx7SEw0/s1600-h/php5_zce_logo.gif&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYWwcKyY-SAAMH3EUa_pvzS8nzbXnUzA4NoHaHRoQ-ADEPLAnD1-4621vYiehi3fhGFOuUHMIRzFq_I7xuVGmyBMK3QEaupNOqBr5Hg6llsH6ehNKp9uKfGaC7OWOrY80_rP5IGx7SEw0/s400/php5_zce_logo.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5214078333699219938&quot; /&gt;&lt;/a&gt;</description><link>http://arthur.purnama.de/2008/06/zend-php-5-certified-engineer.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG0DA0RYkPrU_i5ZTJuhYsP7XOV88NYw6iM4vIujuwVpVX-M1iK4eB3xucwyVEVrmY6dMgAOjxK2IHnWUtihwyr6SGBjpBMRD5QaffLHzeANNV4egHLHyoieA7baUqqqnWNyJ_3pjUu9M/s72-c/zend_logo.jpg" height="72" width="72"/><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-3400404045523046540</guid><pubDate>Thu, 10 Apr 2008 18:07:00 +0000</pubDate><atom:updated>2014-01-02T23:14:03.241+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>My Google App Engine Account</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks8cdPa477kJZMgtJands2cDD51xT0ZqoJNrGVDrBSNyCU8f_KEQofRju6ZR0A_9lYKJrq07C1rFgyFzlgQ2dO7ewVqu23w9GIPUzfRquOlMg5BLZLsSSx_TmUz1wcvfU2rgTK96fQTk/s1600-h/google_app_engine.png&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks8cdPa477kJZMgtJands2cDD51xT0ZqoJNrGVDrBSNyCU8f_KEQofRju6ZR0A_9lYKJrq07C1rFgyFzlgQ2dO7ewVqu23w9GIPUzfRquOlMg5BLZLsSSx_TmUz1wcvfU2rgTK96fQTk/s400/google_app_engine.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5189164379883045314&quot; /&gt;&lt;/a&gt; Google App Engine enables you to build web applications on the same scalable systems that power Google applications. No assembly required. It&#39;s easy to scale. AND It&#39;s free to get started.  How&#39;s that sounds, huh? That&#39;s the new Google App Engine.&lt;br /&gt;
&lt;br /&gt;
On April 7th, 2008 i read an article on ZDNet.com telling that &lt;a href=&quot;http://blogs.zdnet.com/Google/?p=999&quot;&gt;Google announces App Engine&lt;/a&gt;. I thinked: &quot;WOW! this is great news&quot;. I really want to try it. Well the problem is the service is being opened up to the first 10,000 developers that request an account. Of course its free, but 10, 000 is not much. But i try to request an account anyway. In fact, at that time Google can not accept account request anymore. &lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
But, Google give an option that, if there is another chance to request an account, you will be informed. And there it is 3 days later, i got an email from google that informed me, i have the opportunity to try one of the newest google service. ^^ &lt;br /&gt;
&lt;quote&gt; Hello,&lt;br /&gt;
&lt;br /&gt;
Thanks for signing up to try Google App Engine!  Your account has been activated, so you can begin building applications!&lt;br /&gt;
&lt;br /&gt;
To start creating applications with Google App Engine, simply follow this link (you may need to sign in with your xxxxxx.xxxxxx@gmail.com Google Account):&lt;br /&gt;
&lt;br /&gt;
http://appengine.google.com/&lt;br /&gt;
&lt;br /&gt;
Thanks!&lt;br /&gt;
The Google App Engine Team&lt;br /&gt;
&lt;/quote&gt;&lt;br /&gt;
I can just say YES! At that time. Quick browse the tutorial and download the App Engine for local test. Google did his homework and create a nice &lt;a href=&quot;http://www.youtube.com/watch?v=bfgO-LXGpTM&quot;&gt;video tutorial&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/appengine/docs/gettingstarted/&quot;&gt;Getting Started Guide&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Kevin Gibbs says on &lt;a href=&quot;http://www.youtube.com/watch?v=3Ztr-HhWX1c&quot;&gt;Google Campfire One&lt;/a&gt; that Python are the first language for Google App. Well I say, I am waiting for PHP to be Next!!&lt;br /&gt;
&lt;br /&gt;
Okay folks!! Just wait my next Masterpiece on Google App Engine ^^.</description><link>http://arthur.purnama.de/2008/04/my-google-app-engine-account.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks8cdPa477kJZMgtJands2cDD51xT0ZqoJNrGVDrBSNyCU8f_KEQofRju6ZR0A_9lYKJrq07C1rFgyFzlgQ2dO7ewVqu23w9GIPUzfRquOlMg5BLZLsSSx_TmUz1wcvfU2rgTK96fQTk/s72-c/google_app_engine.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-6740493483280961498</guid><pubDate>Wed, 26 Mar 2008 17:31:00 +0000</pubDate><atom:updated>2014-01-02T23:23:08.499+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Tutorial</category><title>Install PHP Extension untuk Zend Debugger</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic9oFU7edyhWwDuHJspvb0LZew0gzmMqK9w5macMCVpLmRlBBLZqzdInlERx5eEZHV3kVlvwOpRDb9dvhO9-0DTu2XPPkoherGo7NvxiyK0PkZUD1Ookfa4nRJcgLil6KJ5S8l7qpEaxg/s1600-h/zend_debugger_mysql.png&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic9oFU7edyhWwDuHJspvb0LZew0gzmMqK9w5macMCVpLmRlBBLZqzdInlERx5eEZHV3kVlvwOpRDb9dvhO9-0DTu2XPPkoherGo7NvxiyK0PkZUD1Ookfa4nRJcgLil6KJ5S8l7qpEaxg/s400/zend_debugger_mysql.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5183646087922171122&quot; /&gt;&lt;/a&gt;Biasanya kalo gue nge-debug PHP-code yang gue tulis, gue pasti kalo gak pake fungsi &lt;a href=&quot;http://de3.php.net/manual/en/function.printf.php&quot; &gt;print_f()&lt;/a&gt; ya pake &lt;a href=&quot;http://de3.php.net/manual/en/function.echo.php&quot; &gt;echo&lt;/a&gt;. Tapi sejak pake Zend Studio for Eclipse gue ngerasa sudah saatnya gue cobain pake Zend Debugger. Itung-itung biar kelihatan lebih professional, dan tentunya disiplin diri sedikit. Dan juga gue cukup kenal dengan Debugger Panel-nya Eclipse waktu memprogram aplikasi Java.&lt;br /&gt;
&lt;br /&gt;
Hal lain yang tentunya gue kesengsem banget pengen cobain, ya... PHPUnit-nya jek. Mantep banget kan tuh, gak perlu repot-repot lagi Unit-Testing di browser. Bisa lebih semangat ber-&lt;i&gt;Test Driven Development&lt;/i&gt; ria. Bikin test filenya atau jalanin testnya juga tidak sulit, tinggal ceklak-ceklik beres.&lt;br /&gt;
&lt;br /&gt;
Tapi! Tidak disangka-sangka, baru klik &lt;i&gt;Run &amp;gt; Debug as &amp;gt; PHP Script&lt;/i&gt; lah langsung error &lt;i&gt;Call to undefined function mysql_connect()&lt;/i&gt;. Ternyata tidak semua PHP Extension merupakan bawaannya Zend Debugger. Beberapa kudu install sendiri. Setelah ubek-ubek google coba ini itu. Akhirnya nyala juga. Nah supaya yang lain gak punya masalah juga seperti gue, gue pengen bagi-bagi pengalaman gue install PHP-Extension buat Zend Debugger.&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.min.js&quot;&gt;&lt;/script&gt; &lt;script language=&quot;javascript&quot; src=&quot;http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPhp.min.js&quot;&gt;&lt;/script&gt;&lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt; &lt;link href=&quot;//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeEclipse.min.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;&lt;script type=&quot;text/javascript&quot;&gt; SyntaxHighlighter.all()&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Referensi gue waktu cari-cari di google saat itu bisa dilihat &lt;a href=&quot;http://benramsey.com/archives/zend-executable-debugger-eclip se-plugin/&quot;&gt;disini&lt;/a&gt;, &lt;a href=&quot;http://www.phpforum.de/forum/showthread.php?p=1129160&quot;&gt;disini&lt;/a&gt;, &lt;a href=&quot;http://www.thierryb.net/pdtwiki/index.php?title=Using_PDT_:_Installation_:_Installing_the_Zend_Debugger&quot;&gt;disini&lt;/a&gt; dan &lt;a href=&quot;http://www.zend.com/forums/index.php?t=msg&amp;th=4554&amp;start=0&amp;S=ad125f65a32b36cda0658f8bfba16281&quot;&gt;disini&lt;/a&gt;. Dari 4 sumber itu, sebenarnya semuanya tidak membuahkan hasil, tapi setidaknya sudah menunjukkan jalan, musti utak-atik dimana. Yang terakhir adalah forum dari Zend sendiri. Dan gue sempet posting saking &lt;i&gt;desperate&lt;/i&gt;-nya. Tapi sampai gue ketemu sendiri titik masalahnya dimana, tidak ada yang response pertanyaan gue.&lt;br /&gt;
&lt;br /&gt;
Sebelum gue mulai, mungkin ada baiknya kalau kalian tahu bahwa ada 2 macam Zend Debugger. Yang satu untuk IDE, kita bilangnya Client Debugger, dan yang satu lagi untuk Web Server, atau kita bilangnya Server Debugger. Yang akan gue bahas kali ini sebenarnya tentang Client Debugger, tapi Server Debugger bakal gue singgung juga sedikit.&lt;br /&gt;
&lt;br /&gt;
Contoh yang gue pakai buat Tutorial ini semuanya menggunakan Zend Studio, tapi gue yakin PDT juga sama saja. Jadi tunggu apalagi, download &lt;i&gt;PDT All in one package&lt;/i&gt; &lt;a href=&quot;http://downloads.zend.com/pdt/all-in-one/&quot;&gt;disini&lt;/a&gt;. Distribusi ini sudah dilengkapi dengan Zend Debugger Client.&lt;br /&gt;
&lt;br /&gt;
Untuk mencoba paket yang sudah ada Server Debuggernya, ada baiknya kalian install &lt;a href=&quot;http://www.zend.com/en/products/core/downloads&quot;&gt;Zend Core&lt;/a&gt;. Tidak usah takut, meskipun trial, Zend Core tidak akan expired, karena untuk Zend Core, Zend menjual support, bukan softwarenya.&lt;br /&gt;
&lt;br /&gt;
So gue langsung ajah, gue gak akan ngebahas installnya, karena ini bukan tutorial untuk install software tapi untuk install PHP Extension di Zend Client Debugger.&lt;br /&gt;
&lt;br /&gt;
Bikin PHP Project baru, lalu buat satu php file, kita beri nama index.php. Dengan file ini kita coba untuk membuka koneksi ke mysql. Gue anggap kalian semua sudah install mysql server, dan punya test database. So kita tulis script untuk connect ke mysql di index.php yang kita buat tadi:&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: php&quot;&gt;&amp;lt;?php

$link = mysql_connect(&#39;localhost&#39;, &#39;mysql_user&#39;, &#39;mysql_password&#39;);
if (!$link) {
    die(&#39;Not connected : &#39; . mysql_error());
}

// connect to database
$db_selected = mysql_select_db(&#39;database&#39;, $link);
if (!$db_selected) {
    die (&#39;Can\&#39;t use foo : &#39; . mysql_error());
}

?&amp;gt;
&lt;/pre&gt;So sekarang coba &lt;i&gt;Run &amp;gt; Run As &amp;gt; PHP Script&lt;/i&gt;. Hasilnya pasti bakal kayak gini: &lt;br /&gt;
&lt;pre class=&quot;brush: html&quot;&gt;&lt;b&gt;Fatal error&lt;/b&gt;:  Call to undefined function mysql_connect() in &lt;b&gt;K:\root\test\index.php&lt;/b&gt; on line &lt;b&gt;3&lt;/b&gt; 
&lt;/pre&gt;&lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHQXlK42sIlTZKyGns56gbuuqsrbYmfFvWYE9x909JrCbu1Qt86f6nO5-dRi5dP2z5m5eeO5GvnlTdRBzAzyUkFfmTOPAZ_-z-79icXlsSmVvZKWAJfWCVmK81uaPSq6-kirZHiI7Kjk/s1600-h/mysql_error.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHQXlK42sIlTZKyGns56gbuuqsrbYmfFvWYE9x909JrCbu1Qt86f6nO5-dRi5dP2z5m5eeO5GvnlTdRBzAzyUkFfmTOPAZ_-z-79icXlsSmVvZKWAJfWCVmK81uaPSq6-kirZHiI7Kjk/s400/mysql_error.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185110164963966210&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Ok untuk lebih yakin bahwa Zend Debugger tidak di install MySQL extension, mari kita coba bikin phpinfo(). Kita ganti script di index.php yang tadi dengan phpinfo(). Lalu  coba lagi &lt;i&gt;Run &amp;gt; Run as &amp;gt; PHP Script&lt;/i&gt;. Sekarang kalian bisa lihat halaman phpinfo, dan kalau kalian cari disitu, tidak akan ketemu informasi tentang mysql. Ada beberapa extension juga yang tidak ada disitu. Dan dalam kesempatan ini kita akan coba install extension tersebut.&lt;br /&gt;
&lt;br /&gt;
Dari tutorial-tutorial referensi gue diatas, semuanya kasih tahu bahwa gue harus buka  plugin Zend Debugger untuk eclipse. Tergantung installasi plugin tersebut dapat ditemukan di &lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;[install_dir]\plugins\org.zend.php.debug.debugger.[operating_system]_5.2.12.v20071210\resources\
&lt;/pre&gt;&lt;br /&gt;
Di dalam situ ada 2 direktori, yang satu &lt;i&gt;php4&lt;/i&gt; yang satu &lt;i&gt;php5&lt;/i&gt;. Buka yang &lt;i&gt;php5&lt;/i&gt; isinya kira-kira begini: &lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwJ3F6kkQzhiQloG9fKOEWSFfdjPwkRjpSEtnsFcgzBQOBeTOuqRnFjKGSAo7Y2WmsG7x_yEB9nSOt1Bzi9Dml7Jqg02OUzWNbr7wHJCkvmkAm8a0AQ_vR2S80bsD68YVxJZ2xmJXs1mI/s1600-h/client_debugger_file.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwJ3F6kkQzhiQloG9fKOEWSFfdjPwkRjpSEtnsFcgzBQOBeTOuqRnFjKGSAo7Y2WmsG7x_yEB9nSOt1Bzi9Dml7Jqg02OUzWNbr7wHJCkvmkAm8a0AQ_vR2S80bsD68YVxJZ2xmJXs1mI/s400/client_debugger_file.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185114812118580498&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Kalau kalian buka php.ini nya pakai text editor, isinya cuma ini:&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: bash&quot;&gt;zend_extension_ts=.\ZendDebugger.dll
&lt;/pre&gt;&lt;br /&gt;
Mulai dari sini, menurut referensi gue, gue bisa ambil kesimpulan ada 2 kemungkinan: &lt;ol&gt;&lt;li&gt;Menggunakan Zend Server Debugger extension&lt;/li&gt;
&lt;li&gt;Mengcopy extension file ke plugin directory&lt;/li&gt;
&lt;/ol&gt;Gue sekarang mau coba bahas 2 kemungkinan itu dan masalah-masalah yang sempat gue hadapi saat itu.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Menggunakan Zend Server Debugger extension&lt;/strong&gt;&lt;br /&gt;
Karena server kita sudah disetting semuanya untuk koneksi ke mysql, extension yang diperlukan juga sudah di install, apalagi disana juga sudah diinstall ZendDebugger. Kenapa juga tidak dipakai juga untuk Client Debugging.&lt;br /&gt;
&lt;br /&gt;
Untuk menggunakan Zend Server Debugger extension, caranya mudah saja. Di Eclipse, buka Window &amp;gt; Preferences... &amp;gt; PHP &amp;gt; PHP Executables. Disana klick Add. Terus isi kira-kira seperti ini. Ingat ini settingan gue. Address path kalian bisa lain.&lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo_eI-pGuA0Aye678Q8YI2bz8Jq5xZ065w058CP-VKMnnBztnqjtFSIhik13Gxxt8Cn5hI822YloXsWCdednxErBLen9qgUjr8S2CG6KgxBtt5jBtLs5tFP_rFu715o07_qrfIqRESxxo/s1600-h/add_zend_debugger.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo_eI-pGuA0Aye678Q8YI2bz8Jq5xZ065w058CP-VKMnnBztnqjtFSIhik13Gxxt8Cn5hI822YloXsWCdednxErBLen9qgUjr8S2CG6KgxBtt5jBtLs5tFP_rFu715o07_qrfIqRESxxo/s400/add_zend_debugger.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185125532356951330&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Setelah klickt Finish, set default setting yang loe tadi bikin, kira-kira seperti ini:&lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvqH0ZRmh-s422PKdXXiu53UVF5uw-uTVFgowuaeKOqfFWKX-Oddy9nO_Qs_7D1GOxajEtrlMemgd4JO3iwOE6zRrqbJyY7ctqXjD9jZUkmdM-LYB7-b6g6NFzK-wgdrQul7Rp9Ex3Lo/s1600-h/debugger_gue.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvqH0ZRmh-s422PKdXXiu53UVF5uw-uTVFgowuaeKOqfFWKX-Oddy9nO_Qs_7D1GOxajEtrlMemgd4JO3iwOE6zRrqbJyY7ctqXjD9jZUkmdM-LYB7-b6g6NFzK-wgdrQul7Rp9Ex3Lo/s400/debugger_gue.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185126618983677234&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Sekarang coba lagi Run as &amp;gt; PHP Script index.php-nya. Kali ini pasti berhasil. Beberapa dari kalian pasti ada yang mengalami keluarnya pop-up ini:&lt;br /&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpeOvKuSixCKlj6f8Sr9FBN0vWGYTdNf0t_j5QP43sJGIU_9kN4lq-SAHV2O075ffTKtwYRsyfifoZnucSSlgck5uvV6JywpHYxcwhafVtJF0I4QUI7EqyCkvp8WoBi-5SpN0fY8B8BIA/s1600-h/old_zend_debugger.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpeOvKuSixCKlj6f8Sr9FBN0vWGYTdNf0t_j5QP43sJGIU_9kN4lq-SAHV2O075ffTKtwYRsyfifoZnucSSlgck5uvV6JywpHYxcwhafVtJF0I4QUI7EqyCkvp8WoBi-5SpN0fY8B8BIA/s400/old_zend_debugger.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185127550991580482&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Ini disebabkan karena Plugin zend debugger Eclipse dibuat untuk php versi 5.2.5 dan Zend Core memiliki php versi 5.2.4. Apabila diantara kalian Web servernya menggunakan versi yang sama dengan Eclipse Zend Debugger, maka pop-up warning tersebut tidak akan muncul.&lt;br /&gt;
&lt;br /&gt;
Cara ini sebenarnya sangat tidak disarankan, karena bisa menimbulkan &quot;hal-hal yang tidak diinginkan&quot; lebih jelasnya apa gue sendiri saat ini tidak tahu, tapi yang pasti Zend tidak akan extra membuat 2 Debugger apabila toh semuanya sama saja.&lt;br /&gt;
&lt;br /&gt;
Maka dari itu sangat disarankan cara yang kedua.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Mengcopy extension file ke plugin directory&lt;/b&gt;&lt;br /&gt;
Copy directory ext dari directory php - untuk zend core ada di [install_dir]/lib/phpext - ke Zend Debugger Plugin. copy juga libmysql.dll dan lib .dll yang lainnya yang dibutuhkan. Kira-kira akhirnya seperti ini: &lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0kAjFnGmh0VE-nP9F1XRNSHRuXz_oHUuaVuvrOUBuMIv9xGGSbDCNuzxSKYsT5qiIOd9l0ueVRxVj1C1YYbhss8KUc7HJZv1T-XPnH6pDn4JqbVELjoKYbQOWWoo_Ibw7-miF1errzQU/s1600-h/copy_ext.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0kAjFnGmh0VE-nP9F1XRNSHRuXz_oHUuaVuvrOUBuMIv9xGGSbDCNuzxSKYsT5qiIOd9l0ueVRxVj1C1YYbhss8KUc7HJZv1T-XPnH6pDn4JqbVELjoKYbQOWWoo_Ibw7-miF1errzQU/s400/copy_ext.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5185133632665271634&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
INGAT: Perhatikan versi data yang ada di directory ext, bandingkan dengan angka yang tertera di php5ts.dll (PHP Interpreter). Pada contoh gambar diatas php5ts.dll memiliki versi 5.2.5.5. Apabila extension library yang ada di directory ext tidak memiliki versi yang sama, maka dijamin tidak akan berhasil. Informasi ini tidak dihimbau di referensi yang gue baca. Dan sempat bikin gue bingung waktu itu, kenapa kok tidak nyala-nyala extension-nya.  Selanjutnya tinggal menyesuaikan php.ini yang ada di plugin. Gue kasih contoh bagaimana konfigurasi php.ini gue.&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: bash&quot;&gt;zend_extension_ts=.\ZendDebugger.dll
extension_dir=&quot;.\ext&quot;
extension=php_soap.dll
extension=php_sockets.dll
extension=php_mysql.dll
extension=php_pdo.dll
extension=php_pdo_mysql.dll
extension=php_pdo_pgsql.dll
extension=php_zip.dll
extension=php_xsl.dll
extension=php_xmlrpc.dll
extension=php_mhash.dll
extension=php_mcrypt.dll
extension=php_mbstring.dll
extension=php_calendar.dll
extension=php_bz2.dll
extension=php_bcmath.dll
extension=php_curl.dll
extension=php_exif.dll
extension=php_ftp.dll
extension=php_gd.dll
extension=php_fdf.dll
extension=php_gd2.dll
extension=php_gettext.dll
extension=php_imap.dll
extension=php_ldap.dll
extension=php_mime_magic.dll
extension=php_ming.dll
extension=php_mysqli.dll
extension=php_openssl.dll
extension=php_pdo_odbc.dll
extension=php_pdo_sqlite.dll
extension=php_pgsql.dll
extension=php_sqlite.dll
extension=php_tidy.dll
&lt;/pre&gt;&lt;br /&gt;
Beberapa orang mungkin lebih sedikit, beberapa lebih banyak, tapi yang penting cuma 3  yang diatas: &lt;ul&gt;&lt;li&gt;Address Path dari zend_extension_ts&lt;/li&gt;
&lt;li&gt;Address Path dari extension_dir&lt;/li&gt;
&lt;li&gt;extension apa yang mau di install&lt;/li&gt;
&lt;/ul&gt;Setelah semua selesai. Silahkan dicoba lagi run index.php scriptnya dan check phpinfo() apakah kali ini extension tersebut terinstall dengan benar. Menurut gue sih mestinya sekarang sudah jalan. Selamat mencoba.</description><link>http://arthur.purnama.de/2008/03/install-php-extension-untuk-zend.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic9oFU7edyhWwDuHJspvb0LZew0gzmMqK9w5macMCVpLmRlBBLZqzdInlERx5eEZHV3kVlvwOpRDb9dvhO9-0DTu2XPPkoherGo7NvxiyK0PkZUD1Ookfa4nRJcgLil6KJ5S8l7qpEaxg/s72-c/zend_debugger_mysql.png" height="72" width="72"/><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-2594684404664161974</guid><pubDate>Thu, 13 Mar 2008 20:44:00 +0000</pubDate><atom:updated>2014-01-02T23:24:20.411+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>My Zend Studio for Eclipse License</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvryCy4I45nQHVUJDE9LRe9JCRgXwCznZ6rehbVEX1IEmQ1k6U16CZTSz82yD6d5sivEzYFue_r6bspUnybCCZCP8qwIasbCxUIQqNA7xu9eUZ7idvm5EGfHnYSJm49n9Qzlwqqr6DDY/s1600-h/zend_studio.png&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvryCy4I45nQHVUJDE9LRe9JCRgXwCznZ6rehbVEX1IEmQ1k6U16CZTSz82yD6d5sivEzYFue_r6bspUnybCCZCP8qwIasbCxUIQqNA7xu9eUZ7idvm5EGfHnYSJm49n9Qzlwqqr6DDY/s400/zend_studio.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5177337180159223394&quot; /&gt;&lt;/a&gt; Akhirnya setelah menunggu sekian lama (tepatnya 1 bulan kurang 2 hari), sambil ngeliatin &lt;i&gt;trial warning popup&lt;/i&gt; yang bikin deg-degan, gue bisa dapetin &lt;a href=&quot;http://www.zend.com/de/products/studio/&quot;&gt;Zend Studio for Eclipse&lt;/a&gt; &lt;a href=&quot;http://www.zend.com/de/store/software/studio/&quot;&gt;License&lt;/a&gt; dengan harga yang sangat terjangkau.&lt;br /&gt;
&lt;br /&gt;
Terima kasih gue sebesar-besarnya buat Perwakilan &lt;a href=&quot;http://www.zend.com&quot;&gt;Zend&lt;/a&gt; di indonesia &lt;a href=&quot;http://www.rynet.co.id/&quot;&gt;PT. Rynet Cipta Teknologi&lt;/a&gt; dan tentunya buat mas &lt;a href=&quot;http://risnandar.wordpress.com/&quot;&gt;Riki Risnandar&lt;/a&gt; sebagai &lt;i&gt;contact person&lt;/i&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt; Beberapa waktu lalu di milist sempat ada kabar bahwa perwakilan Zend di indonesia memberikan kesempatan untuk Komunitas PHP Indonesia membeli Zend Studio for Eclipse dengan harga yang sangat terjangkau: $99, atau tepatnya pada saat gue bayar €65,17 saja. Harga yang menurut gue luar biasa murahnya untuk produkt secanggih ini. &lt;br /&gt;
&lt;br /&gt;
Prosesnya cukup cepat, Selama di kantor hari ini, cuma email-emailan saja sama mas Riki sebagai &lt;i&gt;contact person&lt;/i&gt;, bayar lewat paypal, eh malam ini sudah bisa menikmati Zend Studio tanpa warning popup windows yang bikin deg-degan (angkanya turun terus tuh, belon kelar cobain semua featurenya ^^).&lt;br /&gt;
&lt;br /&gt;
Gue harap dengan adanya penawaran ini, komunitas PHP di indonesia bisa dapat semakin berkembang, dan bisa bekerja lebih efektiv dalam pengembangan produkt aplikasi web yang menggunakan PHP.&lt;br /&gt;
&lt;br /&gt;
Keep up the good work bro ^^.&lt;br /&gt;
&lt;br /&gt;
PS: Kalo udah abis gue bedah ini tools, gue posting dah trik-trik menarik. </description><link>http://arthur.purnama.de/2008/03/my-zend-studio-for-eclipse-license.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvryCy4I45nQHVUJDE9LRe9JCRgXwCznZ6rehbVEX1IEmQ1k6U16CZTSz82yD6d5sivEzYFue_r6bspUnybCCZCP8qwIasbCxUIQqNA7xu9eUZ7idvm5EGfHnYSJm49n9Qzlwqqr6DDY/s72-c/zend_studio.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-5565281160010152910</guid><pubDate>Fri, 29 Feb 2008 15:51:00 +0000</pubDate><atom:updated>2014-01-02T23:24:33.667+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>Zend Webinar</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOH-M8obaU7_o3QkudUOAUeNYEQjugt4GISQOGQO4YPITlb8kIGyE9JJMPI5-z8idaNve3HGHSEg1paXytCwndSnIgbhtYfzjV5baMG5O7Tb8ibYB-hdmRPu7Fhi4tS2wQvJj9Az6_ySg/s1600-h/logo.gif&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOH-M8obaU7_o3QkudUOAUeNYEQjugt4GISQOGQO4YPITlb8kIGyE9JJMPI5-z8idaNve3HGHSEg1paXytCwndSnIgbhtYfzjV5baMG5O7Tb8ibYB-hdmRPu7Fhi4tS2wQvJj9Az6_ySg/s400/logo.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5172431309260649154&quot; /&gt;&lt;/a&gt; Heute habe ich meine erste Webinar besucht. Diese Webinar würde von Zend veranstaltet und Organisiert. Es geht um seine neue Produkt aus der IDE reihe. Es heißt &lt;i&gt;Zend Studio For Eclipse&lt;/i&gt;. Ich habe dieses Produkt schon seit es noch in beta phase bereits probiert, aber ich habe noch nicht alle seine neue Funktionen ausprobiert, von daher dachte ich es lohnt sich diese Webinar zu besuchen. Das Webinar war sehr Interessant und hilfreich, abgesehen von der technisches Panne die mitten im Webinar passiert ist.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt; Unsere Sprecher war Jan Burkl, ein Zend PHP Berater aus Stuttgart. Sein Vortrag finde ich sehr gut strukturiert. Da ich das neue Zend Studio bereits benutze seit der noch in beta Phase war, habe ich ein paar dinge bereits erkannt.&lt;br /&gt;
&lt;br /&gt;
Was ich ziemlich interessant finde sind die neue Funktionen wie &lt;i&gt;Refactoring&lt;/i&gt;, &lt;i&gt;Unit-Testing&lt;/i&gt; und &lt;i&gt;Code profiling&lt;/i&gt;. Das hat er ganz schön und systematisch mit Beispielen erklärt.&lt;br /&gt;
&lt;br /&gt;
Ich glaube ich sollte solche Webinaren öfter besuchen ^^. </description><link>http://arthur.purnama.de/2008/02/zend-webinar.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOH-M8obaU7_o3QkudUOAUeNYEQjugt4GISQOGQO4YPITlb8kIGyE9JJMPI5-z8idaNve3HGHSEg1paXytCwndSnIgbhtYfzjV5baMG5O7Tb8ibYB-hdmRPu7Fhi4tS2wQvJj9Az6_ySg/s72-c/logo.gif" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-6274675600655559129</guid><pubDate>Tue, 05 Feb 2008 23:46:00 +0000</pubDate><atom:updated>2014-01-02T23:25:09.940+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>Acid Test, Zat asam untuk Browser</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTvcle9j605TjRDDtvxIOAhGC-QNhKYErvLAwZnslWvPWzHN10M0zF-LItwoymwBzRml0bSQt6T5ngPi8XBvTSdZoE57a7nsHrSrvOZbiMtyH09Ap-SnJJlBLECyV1BudOqV_olpkxuWc/s1600-h/corrosive_small.jpg&quot;&gt;&lt;img style=&quot;margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTvcle9j605TjRDDtvxIOAhGC-QNhKYErvLAwZnslWvPWzHN10M0zF-LItwoymwBzRml0bSQt6T5ngPi8XBvTSdZoE57a7nsHrSrvOZbiMtyH09Ap-SnJJlBLECyV1BudOqV_olpkxuWc/s400/corrosive_small.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5163654734199008258&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;So buat kalian-kalian atau kita-kita para &lt;span style=&quot;font-style: italic;&quot;&gt;Web Application Developer&lt;/span&gt;, istilah &lt;span style=&quot;font-style: italic;&quot;&gt;Cross Browser Compatibility &lt;/span&gt;sudah bukan kosakata baru dalam kamus. Semua pasti pernah ngerasain yang namanya lembur cuma gara-gara layout yang sudah cantik indah nan rapi di browser yang satu, berantakan gak karuan di browser yang lain.&lt;br /&gt;
&lt;br /&gt;
Ya ya, &lt;span style=&quot;font-style: italic;&quot;&gt;tough job huh?&lt;/span&gt; Kadang-kadang gue mikir, kenapa mereka(Browser Vendor) kok gak punya standarisasi sih buat bikin HTML Interpreter Engine? kenapa harus lain-lain interpretasinya? sudah kayak agama ajah. Padahal sudah ada organisasi seperti &lt;a href=&quot;http://w3c.org/&quot;&gt;W3C&lt;/a&gt; yang jelas-jelas sudah bikin  standard-nya.&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Untuk lebih menyemarakkan acara penyeramagaman Interpretasi pada browser -astaga bahasanya- sebuah organisasi yang menamakan dirinya  &lt;a href=&quot;http://webstandards.org/&quot;&gt;The Web Standards Project&lt;/a&gt;, menerbitkan beberapa &lt;span style=&quot;font-style: italic;&quot;&gt;code snippet&lt;/span&gt; yang berfungsi untuk mengetest apakah sebuah browser menginterpretasikan HTML, CSS, dan Javascript sesuai standard W3C. &lt;span style=&quot;font-style: italic;&quot;&gt;Code Snippet&lt;/span&gt; ini mereka beri nama Acid.&lt;br /&gt;
&lt;br /&gt;
Hingga saat ini sudah &lt;a href=&quot;http://www.acidtests.org/&quot;&gt;3 versi Acid&lt;/a&gt; yang diterbitkan oleh Web Standards Project. Acid yang &lt;a href=&quot;http://www.w3.org/Style/CSS/Test/CSS1/current/test5526c.htm&quot;&gt;pertama &lt;/a&gt;bahkan diterbitkan langsung oleh W3C. Dengan adanya test ini, setiap &lt;span style=&quot;font-style: italic;&quot;&gt;browser vendor&lt;/span&gt; berlomba-lomba memperbaiki browser mereka supaya &quot;lulus&quot; acid test.&lt;br /&gt;
&lt;br /&gt;
Belum lama ini &lt;a href=&quot;http://channel9.msdn.com/showpost.aspx?postid=367207&quot;&gt;Channel9&lt;/a&gt; dengan bangga melaporkan bahwa Internet Explorer 8 akan lulus &lt;a href=&quot;http://www.webstandards.org/files/acid2/test.html&quot; &gt;acid2&lt;/a&gt; test. Acid2 dirilis April 2005, sekarang tanggal berapa? Halo Microsoft, baru bangun ya? Oh, tenang dulu, ternyata Firefox 2.x pun belum mendukung sepenuhnya, meskipun tidak separah IE 6 atau IE 7. Browser vendor besar lainnya seperti Safari, Konqueror dan Opera, saat ini sudah sanggup &lt;a href=&quot;http://en.wikipedia.org/wiki/Acid2&quot;&gt;menginterpretasikan acid2 dengan benar&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Dengan adanya test ini, dan melihat bahwa setiap browser berlomba untuk memperbaiki produkt mereka supaya dapat menginterpretasikan acid test secara baik dan benar, kita sebagai web developer bisa sedikit bernapas lega. Setidaknya kita bisa lebih memfokuskan waktu kita untuk memperbaiki kesalahan dalam logik dan proses, daripada kesalahan dalam layout.</description><link>http://arthur.purnama.de/2008/02/acid-test-zat-asam-untuk-browser.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTvcle9j605TjRDDtvxIOAhGC-QNhKYErvLAwZnslWvPWzHN10M0zF-LItwoymwBzRml0bSQt6T5ngPi8XBvTSdZoE57a7nsHrSrvOZbiMtyH09Ap-SnJJlBLECyV1BudOqV_olpkxuWc/s72-c/corrosive_small.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6231031171309673290.post-7998015350572187073</guid><pubDate>Tue, 22 Jan 2008 14:19:00 +0000</pubDate><atom:updated>2014-01-02T23:25:33.112+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Journal</category><title>Sun acquires MySQL</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIqnabW_sdLXeiy5fytbTEQbyFerDUy5razwNn7O0Lh5YQU-BYiAV2e2wTkMl2VJspkIW7Jh6SNGM6tKM1qAs2bBTaalWQ0sxwxkpZDGbeFBbpp80HZDfXvjChgkMJ4Vj7tQJ_1zMIBNM/s1600-h/sunmysql2.gif&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIqnabW_sdLXeiy5fytbTEQbyFerDUy5razwNn7O0Lh5YQU-BYiAV2e2wTkMl2VJspkIW7Jh6SNGM6tKM1qAs2bBTaalWQ0sxwxkpZDGbeFBbpp80HZDfXvjChgkMJ4Vj7tQJ_1zMIBNM/s400/sunmysql2.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5158306062725625474&quot; /&gt;&lt;/a&gt;This journal from &lt;a href=&quot;http://www.golem.de/0801/57061.html&quot;&gt;Golem.de&lt;/a&gt; on 16th January 2008 is a surprise for me. The title on my RSS reader makes me want to klick it and read more about it.&lt;br /&gt;
&lt;br /&gt;
Actually i don&#39;t know how to react at that moment. I have a certain feeling that i can&#39;t described it. Well i just try to googled a little bit on that theme, and found the blog from &lt;a href=&quot;http://blogs.mysql.com/kaj/2008/01/16/sun-acquires-mysql/&quot;&gt;Kaj Arnö&lt;/a&gt; the Vice President Open Source Community Relations for MySQL. He is trying to give some answers about this event and the impact to the MySQL users, community members, customers, partners, and employees.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt; The deal is worth about $1 billion USD and at the same day &lt;a href=&quot;http://www.golem.de/0801/57063.html&quot;&gt;Oracle acquires BEA for $8,5 billion USD&lt;/a&gt;. Compare with BEA, MySQL ist very cheap. I think MySQL should be worth more than that, since it has more than $70 million or so in revenue. &lt;br /&gt;
&lt;br /&gt;
Kaj Arnö writes: &lt;blockquote&gt;Depending on one’s relationship to MySQL, the immediate reaction upon hearing the news may be a mixture of various feelings, including excitement, pride, disbelief and satisfaction, but also anxiety.&lt;/blockquote&gt;&lt;br /&gt;
Well i do feel a mixed of &quot;excitement, pride, disbelief, satisfaction, and anxiety&quot;, haha, because i don&#39;t really know what&#39;s the impact in that time.  Actually i want to post this to &lt;a href=&quot;http://tech.groups.yahoo.com/group/phpug/&quot;&gt;phpug&lt;/a&gt; and &lt;a href=&quot;http://tech.groups.yahoo.com/group/id-php/&quot;&gt;id-php&lt;/a&gt; but its already late at the office and i really want to go home. I considering to post it the next day at the morning. But someone post it already ^^. &lt;br /&gt;
&lt;br /&gt;
The discussion in the groups and at the office is almost the same. Will the MySQL do better in Solaris and Java in the future? Will the other OS and programming language (such as PHP ^^) be given less attention? How about the LAMP stack, will it be SAMJ(Solaris Apache MySQL Java) stack instead of LAMP stack in the future?&lt;br /&gt;
&lt;br /&gt;
Espescially about LAMP Stack, &lt;a href=&quot;http://arstechnica.com/news.ars/post/20080116-sun-targets-open-source-lamp-stack-with-mysql-acquisition.html&quot;&gt;Ryan Paul writing for Art Technica&lt;/a&gt; have a brief analyse to that matter.&lt;br /&gt;
&lt;br /&gt;
What&#39;s makes me comfortable in the end, is that Kaj said &lt;blockquote&gt;But I don’t expect that in any way to be at the cost of other popular operating systems (Linux, Windows, Mac OS/X, other Unixes etc.) or development environments (PHP, Ruby on Rails, Perl, Python, ODBC, C++, C#, VB etc.). MySQL grew with LAMP and MySQL without LAMP at its core is simply unimaginable. It was MySQLs part of LAMP that interested Sun in the first place.&lt;/blockquote&gt;&lt;br /&gt;
Well thats damn true, never takes &quot;My&quot;-SQL away from my LAMP ^^. And in the mean time, maybe i should play with &lt;a href=&quot;http://www.opensolaris.org/os/&quot;&gt;OpenSolaris&lt;/a&gt; a little bit, just in case ^^.</description><link>http://arthur.purnama.de/2008/01/sun-acquires-mysql.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIqnabW_sdLXeiy5fytbTEQbyFerDUy5razwNn7O0Lh5YQU-BYiAV2e2wTkMl2VJspkIW7Jh6SNGM6tKM1qAs2bBTaalWQ0sxwxkpZDGbeFBbpp80HZDfXvjChgkMJ4Vj7tQJ_1zMIBNM/s72-c/sunmysql2.gif" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>