NYCPHP Meetup

NYPHP.org

[nycphp-talk] lazy initialization woes

Jason Perkins jperkins at sneer.org
Wed Nov 10 19:54:59 EST 2004


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




More information about the talk mailing list