craig campbell

Cool Object Building With PHP

created February 24, 2009 at 1:16 am
At work I write mostly PHP code and work among some very respected developers in the PHP community. One thing that bothers me about the PHP world is how most people think in terms of arrays instead of in terms of objects. This is understandable considering Object Oriented PHP didn't really come around until PHP 5 so using arrays is probably an old habit that is hard to get rid of, but that is no excuse. Arrays have their uses, but I think more often than not an object can be used instead.

One of the core problems most PHP developers run into is finding a way to map records in the database to PHP objects. This is understandable considering your database model is often very different from your object model, and at the moment PHP does not offer any great solutions that I know of. Basically my proposal involves two parts:

  1. a DAO (data access object) class
  2. a Builder class

What these classes do is very simple: The DAO contains the SQL to query the database and then calls a builder to take the resulting array and assemble an object (or a collection of objects) out of it which is then returned.

This implementation allows for no question about what is being returned and it forces you to use more objects in your code which is never a bad thing. Another plus is that you can cache the collections directly in memcache and therefore when you hit cache your PHP doesn't have to do any work at all with the data.

This is actually the method I am using on this site so I will demonstrate using real world examples, but before I do so I want to point out that much of the awesomeness in the example relies on a certain naming pattern for your classes. For example I have classes named Blog_Dao, Blog_Comment, Blog_Builder, etc.

The first code I am going to show you is the base DAO class I am using:
<?php
class Dao
{
    /**
     * @var Db
     */

    protected $_db;

    /**
     * @var Builder
     */

    protected $_builder;

    /**
     * constructor
     *
     * sets the database class this dao should use
     *
     * @return void
     */

    function __construct()
    {
        $this->_db = new Db();
    }

    /**
     * determines what builder class to use
     *
     * @param string $builder
     * @return Builder
     */

    protected function _getBuilder($builderName)
    {
        // if we have already instantiated a builder class
        if (!is_null($this->_builder)) {
            return $this->_builder;
        }

        // if we have not passed in a specific builder to use
        if (is_null($builderName)) {
            $builderName = str_replace('_Dao''_Builder'get_class($this));
        }

        // make sure the builder exists
        if (!class_exists($builderName)) {
            throw new Exception($builderName . ' does not exist!');
        }

        // instantiate the builder
        $this->_builder = new $builderName;

        return $this->_builder;
    }

    /**
     * calls the builder to build a collection of the stuff returned from the
     * dao!
     *
     * @param mixed $records
     * @param string $builder name of class to use for building
     * @return Collection
     */

    protected function _buildCollection($records$builder = null)
    {
        // if the database doesn't have any records
        if ($records === false) {
            return false;
        }

        $collection = new Collection();
        foreach ($records as $record) {
            $collection->append($this->_buildOne($record$builder));
        }
        return $collection;
    }

    /**
     * calls the builder and builds a single object
     *
     * @param mixed
     * @param string $builder
     * @return Object
     */

    protected function _buildOne($record$builder = null)
    {
        // if the database doesn't have any record
        if ($record === false) {
            return false;
        }

        $builder = $this->_getBuilder($builder);
        return $builder->assemble($record);
    }
}

The first thing you will probably notice is that $builder is optional! This means you only need to pass in a builder class if the builder is in some wacky place it shouldn't be. So the Blog_Comment_Dao class will default to the Blog_Comment_Builder which makes sense and it forces good use of objects cause it means everything you create a dao for is an object and that DAO should only return things related to that object. Another point of note is the Collection object. This is simply a child of ArrayObject to allow easier access to ArrayObject methods.

Anyway now it is time to see this in action! Here is actual code from this site to get all comments related to a given blog post taken from the Blog_Comment_Dao which extends the base Dao class:

/**
 * retrieves all comments for a given blog
 *
 * @param int $blogId
 * @return Collection
 */

public function get($blogId)
{
    $query = '/* ' . __METHOD__ . ' */' .
        "SELECT bc.id id,
                bc.name name,
                bc.website website,
                bc.email email,
                bc.body body,
                bc.posted_on posted_on
           FROM blog_comment bc
          WHERE bc.blog_id = :blog_id"
;

    $sth = $this->_db->prepare($query);
    $sth->bindValue(':blog_id'$blogId);
    $sth->execute();
    $records = $sth->fetchAllAssoc();

    return $this->_buildCollection($records);
}

Look how pretty that is! Now let's take a look at the Blog_Comment_Builder class to see how simple that is as well:
<?php
class Blog_Comment_Builder
{
    /**
     * creates a comment object from database record
     *
     * @param array
     * @return Blog_Comment
     */

    public function assemble(array $record)
    {
        $comment = new Blog_Comment();
        $comment->name = $record['name'];
        $comment->website = $record['website'];
        $comment->email = $record['email'];
        $comment->body = $record['body'];
        $comment->postedOn = new Date($record['posted_on']);
        return $comment;
    }
}

Something to note here is that these are not public properties. They are all protected, but each domain object extends a Domain_Object class that has magic __set() and __get() methods so you don't have to write setters and getters for every single property in every single class! For more on that check out this post by Matthew Purdon.

You can see that properties of objects can still be other objects such as the Date class here. In the case where you are showing a bunch of Users on your site and each one has a bunch of other classes associated it with it you probably wouldn't want to use the other class's builders because then you end up running queries in loops which is never a good thing. Instead you can handle that logic in the User_Builder cause at the end of the day even if there are other classes involved the Builder is just returning one object from one database record.

An obvious downfall here, of course, is that every object needs to have its own Builder class even though the builder seems like something that could happen automatically if there was better ORM support in PHP or any for that matter. This is something that PHP developers are used to, however, because no matter what framework you use, you still end up having to write tons of code to do even simple operations. Hopefully this will make your life easier.

32 comments

  • image
    February 24, 2009 at 10:47 am
    I think this is a very common pattern for building objects from database query result sets. I like what you have here, having done similar things myself many times in the past. I am not a fan of having to write a builder for each Model, even though you clearly show the power of the assemble method by building a proper date object for the postedOn property. I definitely agree that PHP in it's current state makes us do too much work in order to get something simple working.

    are you sure you want to delete this comment?

  • image
    Craig Campbell
    February 24, 2009 at 11:59 am
    I just updated the DAO code to make it cleaner and remove some duplicate code thanks to Matthew's suggestions.

    are you sure you want to delete this comment?

  • image
    JamesD
    February 26, 2009 at 8:10 pm
    I have actually found Propel to be a pretty good Object Relational Model for PHP.

    are you sure you want to delete this comment?

  • image
    March 2, 2009 at 6:02 pm
    Pretty nice article :). I don't like the magic methods much. They are a lot slower than regular setters / getters. However back to ORM. I found myself to like ActiveRecord more than DAO - VO. Well DAO/VO is also implemented in Java so seems like there has to be something right about that thing though.

    are you sure you want to delete this comment?

  • image
    July 25, 2010 at 11:39 pm
    Best Site Good Work pthc hussyfan
    8[ preteen nymphet models
    62092 naked nymphet
    474 cute little nymphets
    =( naked nymphet forum
    %]]] bbs nymphets
    >:[[[ nymphet top
    %P virgin nymphets
    485270 young pthc bbs
    hfrkz cp pthc
    >:DDD

    are you sure you want to delete this comment?

  • image
    July 25, 2010 at 11:39 pm
    It's serious pthc hussyfan
    8-( pthc topsites
    884 nymphets pics
    30447 chstcnt pthc cp pay sites
    8805 preteen nymphet models
    ngd naked nymphet
    vsrout top nymphet sites
    22662 virgin nymphets
    8-DD young pthc bbs
    9084 extreme nymphets
    230962

    are you sure you want to delete this comment?

  • image
    July 25, 2010 at 11:39 pm
    Gloomy tales little nymphets tgp
    lwg pthc hussyfan
    yftk pthc topsites
    immx naked nymphet
    :[ preteen loli nymphets
    torl nymphets family
    04707 young pthc bbs
    65878 cp pthc
    :]] extreme nymphets
    462650 sandra imageboard bbs loli pthc
    57430

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 1:32 am
    Jonny was here innocent angels pthc bbs toplist
    >:DD cp pics pthc
    21606 pthc cp videos toplist
    ncscky pthc cp pthc bbs
    qtta pthc forum img
    =-PP alina 14 pthc model
    0012 loli toplist pthc
    jnwzib hussyfan pthc gallery
    xctmf best p2p for pthc
    >:)) pthc loli cp zshare
    >:-]

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 1:35 am
    This site is crazy :) innocent angels pthc bbs toplist
    ouqr cp pics pthc
    >:-))) pthc boy
    >:-)) pthc cp pthc bbs
    :D young pthc
    9029 pthc bbs forum
    goul pthc girls
    :))) cp pthc bbs
    8069 pthc hussyfan r@ygold
    875 kazz310 pthc models
    gedmi

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 12:58 pm
    Very Good Site bbs zeps lol bbs
    wva ovens bbs
    >:OO gaijin bbs
    pxmeh bbs cgi loli imageboard
    :-] elweb bbs gateway
    yvd loli bbs
    %-DD max bbs touzokudan 12449
    hiup nn girl bbs
    yrs zeps bbs
    8-] pedoland bbs pthc
    ifxdh

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 12:58 pm
    magic story very thanks ovens bbs
    owrcj sandra img bbs
    lnycn angel bbs innocent
    :[[[ smuggler bbs
    14162 dark little bbs
    76891 lola bbs
    zmco loli bbs
    72815 max bbs touzokudan 12449
    65346 zeps bbs
    62925 young bbs
    udwshh

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 1:00 pm
    magic story very thanks ovens bbs
    owrcj sandra img bbs
    lnycn angel bbs innocent
    :[[[ smuggler bbs
    14162 dark little bbs
    76891 lola bbs
    zmco loli bbs
    72815 max bbs touzokudan 12449
    65346 zeps bbs
    62925 young bbs
    udwshh

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 1:00 pm
    Thanks funny site pthc bbs message board
    lxty lola bbs magazine
    yil ovens bbs
    >:-P sandra model bbs
    :-( max adult bbs
    >:-DDD elweb bbs gateway
    =-DDD lola links bbs
    vuq max bbs touzokudan 12449
    ysczf nn girl bbs
    925 klass bbs
    torjo

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 1:01 pm
    Thanks funny site pthc bbs message board
    lxty lola bbs magazine
    yil ovens bbs
    >:-P sandra model bbs
    :-( max adult bbs
    >:-DDD elweb bbs gateway
    =-DDD lola links bbs
    vuq max bbs touzokudan 12449
    ysczf nn girl bbs
    925 klass bbs
    torjo

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 2:37 pm
    Gloomy tales max bbs livedoor sports
    hwoxo boy bbs
    aksc girl child bbs
    4795 sandra bbs
    39566 loli bbs board
    nreh young love bbs
    %-D loli hc bbs
    25224 freedom bbs ls
    :[ bbs list young
    lvtujv yoda bbs
    141

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 2:37 pm
    Wonderfull great site asian bbs illegal bbs
    8]] zeps guide bbs board
    knyz girl child bbs
    877 loli bbs board
    bcfqp young love bbs
    1158 freedom bbs ls
    3649 yoda bbs
    170 best lol bbs
    qdwgc max4teen bbs
    qebk pthc bbs
    pci

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 2:37 pm
    magic story very thanks zeps guide bbs board
    9361 young bbs post
    dgtwfi max touzokudan bbs
    128 mixman bbs
    :-))) vlad model bbs
    677 ptsc bbs links
    122 loli bbs board
    243995 best lol bbs
    exxv fozya bbs
    739 pthc bbs
    >:[[[

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 4:19 pm
    Very funny pictures loli guest book bbs imageboard
    %]] felixx boy bbs
    yawra zeps bbs guide
    sogp pre bbs
    094 pedo
    qupbg peachy bbs
    %))) ranchi bbs gateway
    %( max bbs touzokudan livedoor
    lzmw ls magazine bbs
    %)) top list pedo sites
    :((

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 4:19 pm
    Punk not dead pedo star
    947 ls models bbs
    mzdvc pedo loli
    8(( bbs lola
    823131 felixx boy bbs
    >:[ zeps bbs guide
    ofb svens place bbs
    350 peachy bbs
    =))) young bbs links
    haq top list pedo sites
    059458

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 4:20 pm
    Wonderfull great site pedo star
    nxbcut pedo love
    =-]]] pedo aficionados
    888 zeps bbs guide
    ajqdh teeny bbs
    yybg peachy bbs
    =DDD ranchi bbs gateway
    >:-O young bbs links
    gzxeng top list pedo sites
    tbuwe great bbs
    8-)))

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 4:21 pm
    Wonderfull great site pedo star
    nxbcut pedo love
    =-]]] pedo aficionados
    888 zeps bbs guide
    ajqdh teeny bbs
    yybg peachy bbs
    =DDD ranchi bbs gateway
    >:-O young bbs links
    gzxeng top list pedo sites
    tbuwe great bbs
    8-)))

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 7:42 pm
    Excellent work, Nice Design loli cp dorki pedo
    1195 pedo art
    320 pedo cp
    cdcr pedo portal
    8[ pedo models
    tzkik child pedo pics
    %-] pedo files
    zjl little girl pedo
    :-] pedo boy
    %-O pedo top
    =)))

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 11:05 pm
    Good crew it's cool :) models gallery
    kruzlz little models top sites
    %-))) young little models
    80785 young nn models
    =-[[[ nn child models
    %-))) teen models
    =-[[[ young model galleries
    835245 bottomless models
    8PP lia model
    86607 sandra model jpg
    lscry

    are you sure you want to delete this comment?

  • image
    July 26, 2010 at 11:05 pm
    Gloomy tales little models top sites
    28151 nn junior models
    8OO nn child models
    58168 sandra model nn
    tlyw teenage models
    474 young model galleries
    rvorjl bottomless models
    2627 female models
    544804 lia model
    60805 pre teen models
    40802

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 5:38 am
    I'm happy very good site little tiny nymphets 672 pthc bdsm torrent finder fmyoo nymphet angels tgp 8P little nymphets magazine 816307 ls nymphet rapidshare series dcf young nymphet com 5465 nymphet highheels >:((( hq nymphets 2098 lesbian nymphets 8-DDD pthc 15 >:-((( tiny nymphet incest 041 land nymphets paysites top gqek pthc mclt =PP teenage nymphet schoolgirls sii model nymphet ukrainian tcmue www lovely nymphets org leucel pthc mom lesbian 779365 hacked nymphets art com 8-] nubile nymphet teenies vmhtw tgp nymphete 255

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 9:20 am
    Excellent work, Nice Design young kidz cp
    bjmv cp portal
    >:-PP cp fans club 9 best cp paysites
    013 young cp
    9825 dreamzone cp
    %-] cp paysite
    80052 free cp gallery
    >:OOO cp galleries
    8-[ cp bbs
    >:DD pedoclub illegal cp
    283619

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 12:50 pm
    Best Site good looking nn magazine models
    %] nn legal models
    mgnht illegal cp links
    19213 nn young girls
    acm cp topsite
    8219 russian cp bbs
    cyewb nn girls
    9916 nn young models galleries
    07630 nn model
    >:((( cp money maker
    =))

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 2:31 pm
    I'm happy very good site nn pre models movies nud
    zvxu nn cuties
    %O nn model galleries
    =) nn girl models
    hhb nn model board
    rxhn 14 yo models nn
    =D nn tgp
    8OO young beautiful models nn
    492 young nn galleries
    314998 pre teenage nn models
    8(((

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 2:32 pm
    i'm fine good work russian models nn
    aciqjm nn models photos
    :-[[[ nn model galleries
    349358 nn girl models
    7751 young little nn models
    %-))) nn girl index
    %((( nn model board
    dkgp 14 yo models nn
    djm nn child models galleries
    :((( nn teen models
    dkb

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 2:32 pm
    It's funny goodluck nn cuties
    :-DDD preteen models nn
    801 nn models photos
    rld nn model board
    =OO very very young nn model galleries
    534 nn young pre lola models
    6975 pre teenage nn models
    ojc nn teen models
    vyggnq young beautiful models nn
    =PPP nn girl links
    lfamb

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 5:57 pm
    It's serious little pre nn
    wrzxf child modeling nn video
    :PP young nn model forum
    8( young nn models pics
    8((( teen nn models
    =( young nn model videos
    %)) cute nn models
    987 nn teenmodel club
    xovjik nn girl guestbook
    guzra ls nn models
    sftxac

    are you sure you want to delete this comment?

  • image
    July 27, 2010 at 5:58 pm
    Best Site good looking nn model forum
    >:-))) little pre nn
    018548 nn teen model
    124930 child modeling nn video
    1356 nn young models
    xueow young nn model videos
    =-D nn preteen pics
    498918 cute nn models
    =-]] nn models video
    ssyzo nn girl guestbook
    fedn

    are you sure you want to delete this comment?