Skip to content

Instantly share code, notes, and snippets.

@juzna
Created June 25, 2011 15:59
Show Gist options
  • Save juzna/1046613 to your computer and use it in GitHub Desktop.
Save juzna/1046613 to your computer and use it in GitHub Desktop.
Lazy-loading for PHP
<?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
<?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
Copy link
Author

juzna commented Jun 26, 2011

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 predefined uninitialized value). You can new that class and all properties will have nulls, 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 and uninitialized 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.

@fprochazka
Copy link

@juzna Hmm, makes sense. Still don't like it. Better make real support for proxy objects...

@md2perpe
Copy link

One approach of lazyload: https://gist.github.com/1049509

@juzna
Copy link
Author

juzna commented Jun 27, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment