lazy_variables[$key])) { return $this->$key = call_user_func($this->lazy_variables[$key]); } return NULL; } protected function registerLazyVariable($var, $callback) { $this->lazy_variables[$var] = $callback; } } /** * The following is an example of how lazy variables can be nifty. Suppose that * we want to work with a database result set, but we don't want to execute the * query only until we abolsutely have to (in this case, when we want to * iterate over it). We can make an IteratorIterator-like class, LazyIterator, * that allows iterator over a database result set iterator (example uses * ArrayIterator). The LazyIterator::$iterator is the lazy variable. It is * only defined when it is first used. */ class Query { public function execute() { echo "Calling Query::execute()\n"; return new ArrayIterator(array( 'hello', 'world', )); } } class LazyIterator extends Lazy implements Iterator { protected $query; public function __construct(Query $query) { $this->query = $query; $this->registerLazyVariable('iterator', array($this, 'getInstance')); } protected function getInstance() { echo "Calling LazyIterator::getInstance()\n"; return $this->query->execute(); } public function next() { $this->iterator->next(); } public function key() { return $this->iterator->key(); } public function current() { return $this->iterator->current(); } public function valid() { return $this->iterator->valid(); } public function rewind() { $this->iterator->rewind(); } } $lazy_it = new LazyIterator(new Query); foreach($lazy_it as $key => $val) echo "{$val}\n"; echo "\n"; foreach($lazy_it as $key => $val) echo "{$val}\n";