[prev in list] [next in list] [prev in thread] [next in thread] 

List:       php-general
Subject:    [PHP] $this = new Class();
From:       Olivier Lalonde <olalonde () gmail ! com>
Date:       2009-04-30 15:53:12
Message-ID: 880d9d590904300853h62b938aeo2df819c5505035df () mail ! gmail ! com
[Download RAW message or body]

Hi all,

Since I can't do $this = new Class(); within my class (it gives an
error), I was looking for ways to get the same result by other means.

I am actually working on an ORM and trying to implement lazy loading.

$book = $orm->getBook('id'); // returns an Orm object
$book->load();

// $book should now be a Book instead instead of an Orm instance

Of course, I oversimplified the problem.  $book = $orm->getBook('id');
doesn't return a Book instance right ahead because it is a chained
method (i.e. $orm->getBook()->where(...)->prefetch(...)->etc....
Therefore, it _has_ to return an Orm instance.

Now, why not simply add ->load() at the end of the chain? Because it
adds an extra step for developers that doesn't bring meaningful
information. Instead of doing $book = $orm->getBook('id');, it would
mean having to do $book = $orm->getBook('id')->load(); (which is
longer to type :p). That's why I wanted to implement "lazy loading".

$book = $dorm->getBook('id');
echo $book->title; // title should be trapped by __set() and it should
dynamically replace $book by an actual Book instance

I tried doing the following, but PHP doesn't allow it:

class A {
  public function transform() {
    $this = new B();
  }
}

class B {}

$var = new A();
$var->transform();

This is not currently supported by PHP and I was wondering if there
was anyway of getting around the problem, that doesn't involve
1) passing $var to the A class i.e:$var->var = $var;
2) looping $GLOBALS[]
3) using __call,__get and __set to proxy everything to the actual Book object

PS1: don't lecture me about how I'm doing this all wrong. I've looked
at the problem from every possible angle and this is the only
solution.
PS2: Another alternative would be to subclass the Orm object with
Book, (class Orm extends Book {}), overload all properties/methods so
we can catch when to load the object... but that would be an extreme
pain in the ass.
PS3: Another alternative would be to have a parameter that
enables/disables chaining.
$dorm->getBook('id', true); // chain (you now have to add ->load() at
the end of the chain)
$dorm->getBook('id', false); // dont chain, this returns a Book instance

The point of all this is to keep the most friendly interface !

Cheers,
Olivier

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic