[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