NYCPHP Meetup

NYPHP.org

[nycphp-talk] lazy initialization woes

Dan Cech dcech at phpwerx.net
Wed Nov 10 20:10:59 EST 2004


I'm not 100% on overloading in php5, but I think you need either:

class sales_order {
     ...

   public function has_a( $class ) {
     $this->relationships[ $class ] = 'has_a';
   }

   public function __get( $class, &$obj ) {
     if(array_key_exists( $class, $this->relationships )) {
       if( $this->relationships[ $class ] == 'has_a') {
         $this->$class =& $obj =& new $class( $this->id );
         return true;
       }
     }
     return false;
   }
}

or

class sales_order {
     ...

   public function has_a( $class ) {
     $this->relationships[ $class ] = 'has_a';
   }

   public function __get( $class ) {
     if(array_key_exists( $class, $this->relationships )) {
       if( $this->relationships[ $class ] == 'has_a') {
         return $this->$class =& new $class( $this->id );
       }
     }
   }
}

Dan

Jason Perkins wrote:
> I'm working on a project in PHP with the hopes of releasing it if I can 
> get it off of the ground and I've ran into a problem that I'm hoping 
> someone can lend a hand with. The basic notion is that a given object 
> will potentially contain other objects, but these contained objects 
> aren't known (or generated) until runtime.
> 
> For example, we'll instantiate a sales_order object and then, using its 
> has_a() method, add a customer object to it. To prevent cascades of 
> objects being instantiated, I'd plan to use lazy initialization - the 
> customer object won't be instantiated until the first time that it's 
> accessed through the customer class. The problem that I'm having is that 
> lazy initialization in PHP 5 is accomplished via the __get() method 
> which is called when an attribute (or contained class in this) isn't 
> available - it's passed the name of the property that wasn't found and 
> that's not enough information for me to return the attribute of the 
> contained object that was being accessed. Here's some quickly written 
> code with extra code stripped that'll demonstrate what I mean:
> 
> <?
> 
> class sales_order {
>     ...
> 
>   public function has_a( $class ) {
>     $this->relationships[ $class ] = 'has_a';
>   }
> 
>   public function __get( $class ) {
>     if(array_key_exists( $class, $this->relationships )) {
>       if( $this->relationships[ $class ] == 'has_a') {
>         $this->$class  = new $class( $this->id );
>         return;
>       }
>     }
>   }
> }
> 
> So if $attribute exists in the relationships array, it's instantiated 
> (and, yeah, I plan to move the contained objects into a declared array. 
> one thing at a time :) )
> 
> $sales_order = new sales_order;
> $sales_order->has_a( customer );
> print $sales_order->customer->name;
> 
> The last line fails, because __get is passed only 'customer' and not 
> 'customer->name' - I have no way of knowing what attribute of customer 
> was being accessed, so I can't return the requested data. Running this 
> code:
> 
> $sales_order = new sales_order;
> $sales_order->has_a( customer );
> print $sales_order->customer->name;
> print $sales_order->customer->name;
> 
> the fourth line works, because the customer object was instantiated 
> during line three (line three still fails to return a value). Does 
> anyone have any suggestions on how to get this working?
> 
> Apologies in advance for the verbosity of this email, I really did try 
> to strip out as much as I could.
> 
> thanks!
> 
> 
> -- 
> Jason N Perkins
> 
> _______________________________________________
> New York PHP Talk
> Supporting AMP Technology (Apache/MySQL/PHP)
> http://lists.nyphp.org/mailman/listinfo/talk
> http://www.newyorkphp.org




More information about the talk mailing list