Created
June 25, 2011 15:59
-
-
Save juzna/1046613 to your computer and use it in GitHub Desktop.
Lazy-loading for PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Address { | |
public $street; | |
public $town; | |
} | |
class Customer { | |
public $id; | |
public $name; | |
public $address; | |
} | |
class Payment { | |
public $amount; | |
public $customer; | |
} | |
$db = getDatabase(); | |
$payment = $db->load('Payment', 123); | |
/* | |
$payment containts: | |
amount = 100; | |
customer = class Customer { | |
id = 5; | |
name = uninitialized; | |
address = uninitialized; | |
} | |
} | |
*/ | |
echo $payment->customer->name; // DB layer will load customer info | |
// or | |
echo $payment->customer->address->town; // DB layer will load customer & address info | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Example of possible lazy-loading in PHP | |
* Added new special value called "uninitialized". When a property with this value is being read from object, | |
* __initialize($propertyName) magic method is invoked to lazy-load the value. | |
*/ | |
class Foo { | |
private $bar = uninitialized; | |
private $lol = "lol"; | |
public $pub = uninitialized; | |
public $blank = uninitialized; | |
function getBar() { | |
echo "Getter method bar, "; | |
return $this->bar; | |
} | |
function getLol() { | |
echo "Getter method lol, "; | |
return $this->lol; | |
} | |
function getPub() { | |
echo "Getter method pub, "; | |
return $this->pub; | |
} | |
function __get($name) { | |
echo "Magic getter $name, "; | |
return $this->$name; | |
} | |
function __initialize($name) { | |
if($name !== 'blank') { | |
echo "Initializing $name, "; | |
$this->$name = "I'm $name"; | |
} | |
else { | |
echo "Trying to initialize blank, "; | |
} | |
} | |
function clean() { | |
$this->bar = $this->lol = $this->pub = uninitialized; | |
} | |
} | |
// __initialize will be called only once, on first access | |
$foo = new Foo; | |
var_dump($foo->getBar()); // Getter method bar, Initializing bar, string(7) "I'm bar" | |
var_dump($foo->getBar()); // Getter method bar, string(7) "I'm bar" | |
// magic __get is called first, and inside it's initialized | |
$foo = new Foo; | |
var_dump($foo->bar); // Magic getter bar, Initializing bar, string(7) "I'm bar" | |
var_dump($foo->bar); // Magic getter bar, string(7) "I'm bar" | |
$foo->clean(); | |
var_dump($foo->bar); // Magic getter bar, Initializing bar, string(7) "I'm bar" | |
var_dump($foo->bar); // Magic getter bar, string(7) "I'm bar" | |
// lazy-loading of public properties | |
$foo = new Foo; | |
var_dump($foo->pub); // Initializing pub, string(7) "I'm pub" | |
// normal value remains as expected | |
$foo = new Foo; | |
var_dump($foo->getLol()); // Getter method lol, string(3) "lol" | |
// variable which cannot be initialized | |
$foo = new Foo; | |
var_dump($foo->blank); // Trying to initialize blank, undefined | |
var_dump($foo->blank); // Trying to initialize blank, undefined |
@juzna Hmm, makes sense. Still don't like it. Better make real support for proxy objects...
One approach of lazyload: https://gist.github.com/1049509
I belive there is much more magic in @md2perpe's example. And it also add
some domain logic which must be present in all objects.
Jan Dolecek
[email protected]
…On Mon, Jun 27, 2011 at 7:56 PM, md2perpe < ***@***.***>wrote:
One approach of lazyload: https://gist.github.com/1049509
##
Reply to this email directly or view it on GitHub:
https://gist.github.com/1046613
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The real reason why I want
uninitialized
to be assign-able could be seen in example.php of this Gist. You may have a class Customer, which has just normal properties (not with a lazy keyword as proposed by @hosiplan, nor with predefineduninitialized
value). You cannew
that class and all properties will havenull
s, as normally. Nothing changes here.First time a new type of value would be used is when you load a
$payment
from database. DB layer will create instance of Customer class, assign proper id to it's $id property anduninitialized
to all other properties. Then, when you access such a property for the first time, DB layer can lazy-load the whole customer instance.You, as a programmer, don't have to ever use this special value. It will just be used for you by the DB layer, which might be easier with this support in PHP lang.