SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)

    Create a new NullObject - on the fly?

    Having read of the benefits of sometimes using NullObjects here, I suddenly spotted a need for one.

    Say I have a simple CRUD app with 2 data entry forms.

    -edit an existing record
    -add a new record

    and, as usual I'd like to use the same form for both purposes, here is one field:
    PHP Code:
    // on the edit form
    <input type='text' id='title' name='title' value='{$page->title}' />

    // on the add new form
    <input type='text' id='title' name='title' value='' /> 
    It dawns on me that a null page class could do just fine for the latter case without having to do some nasty forking
    PHP Code:
    class NullPage{

    public 
    $title NULL ;


    if edit is true
    $page = (get a page result set using the object notation)
    else
    $page = new NullPage ;

    <input type='text' id='title' name='title' value='{$page->title}' />

    Brilliant.

    I suppose there is another way of course, just set the vars in my code

    $page->title = '' ;

    But say I then move off to work on People, then I'd need to make another, the NullPeople Class.

    Right, so whats the best way I can make a generic NullObject that always returns null values no matter what properties I call?

    (some __call magic no doubt ... I will be looking at that now)

    But I have this nagging doubt, is there no other magical way of doing the same thing without actually having to (include and then) create a class at all?

  2. #2
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    PHP Code:
    class NullObject {
    public 
    $data '' ;

    function 
    __get $property ){
     return 
    $this->data '' ;
    }
    }


    $n = new NullObject ;

    var_dump$n->title ) ; 
    My bad, not __call() but __get() - this is how I'd declare the class if you wanted empty strings back.

    But I'd still have to include that class for every file that depended on it.

    Anyone know of a better way?

  3. #3
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Bah, i though you could use new StdClass(), but the following issues a notice, too messy for my liking.
    PHP Code:
    <?php
    $page 
    = new stdClass();
    echo 
    $page->title;
    ?>
    Shouldn't you be requiring this object at the point of creating the 'real' object though anyway?

    The point being that you shouldn't *have* to add any special behavior when using a null object, that's the benefit it provides.

    Pseudo...
    PHP Code:
    <?php
    class PageFactory
    {
        public static function 
    Get($id)
        {
            require(
    'assets/page.class.php');
            require(
    'assets/page.null.class.php');
            if(
    page_exists($id))
            {
                return new 
    Page($id);
            }
            return new 
    PageNullObject();
        }
    }
    ?>
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  4. #4
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    The real object is a PDO result set, returned as a class.

    It is used inside another class;

    eg:
    PHP Code:
    if( !empty( $id ) ) {
         
    $action_label "Save changes" ;
         
    $page $this->PagesGateway->getRow$id );

    }else{
        
    $action_label "Add new page" ;
        
    $page = new NullObject ;

    }

    // later ... 1 of n form elements
    $form = <<<EOL

    <input type='text' id='title' name='title' value='
    {$page->title}' />

    EOL; 
    *DING* Unless I get my Gateway to return a null object on demand? Could be ...
    PHP Code:
        $page $this->PagesGateway->getRow(); 
    Where the Gateway is responsible for instantiating and supplying the NullObject ? !!

  5. #5
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    *DING* Unless I get my Gateway to return a null object on demand? Could be ...
    I thought I said that above?

    Boy, I'm rubbish at explaining stuff.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  6. #6
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Ah, so you did, ah well thanks for passing on the *DING* moment, and yes, stdClass() was what I was thinking about.

    Cheers Antony, get yer flippers n'goggles on dude, nearly lunchtime!

  7. #7
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    I decided to only return the NullObject only when explicitly asked, so I have to stipulate:

    $gateway->getRow( NULL ) ; // return a NullObject

    It dawned on me that I could use it to return a NullObject when say, $id was missing, but that is a whole other issue - and crossing into that terrritory sounds like hard to find bugs and undocumented features.

    $gateway->getRow() ; // choke or chuck an exception

    PHP Code:
    class Gateway {

    // other methods and properties

        
    function getRow$id$att=false$raw=false ){

        
    // if id set to null return a null object
         
    if ( NULL === $id ) )
                return new 
    NullObject ;

         
    // go ahead and get data 
         
    ...

         }



    Just in case anyone was wondering.
    Thanks again Anthony.
    Last edited by Cups; Sep 23, 2009 at 02:16. Reason: edited my comment above NULL ===


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •