I'm a web developer, freelancer, author, speaker, entrepreneur, technical reviewer and blogger based in the North East, living in a village just outside of Chester-le-Street.

My blog

PHP: Lazy Loading in the registry context

Fairly recently, Ian told me about a framework he had read about, one of the benefits of the framework was that it made use of lazy loading so that files were included and classes were instantiated only when they were required.  I realise that there are a number of ways that most of this could probably be done with PHPs autoload feature, however I've a different approach to implementing it within the context of the registry pattern.

/**
 * Get an object from the registry
 * - facilitates lazy loading, if we haven't used the object yet and it is part of the setup, then require and instantiate it!
 * @param String $key
 * @return Object
 */
public function getObject( $key )
{
	if( in_array( $key, array_keys( $this->objects ) ) )
	{
		return $this->objects[$key];
	}
	elseif( in_array( $key, array_keys( $this->objectSetup ) ) )
	{
		if( ! is_null( $this->objectSetup[ $key ]['abstract'] ) )
		{
			require_once( FRAMEWORK_PATH . 'registry/aspects/' . $this->objectSetup[ $key ]['folder'] . '/' . $this->objectSetup[ $key ]['abstract'] .'.abstract.php' );
		}
		require_once( FRAMEWORK_PATH . 'registry/aspects/' . $this->objectSetup[ $key ]['folder'] . '/' . $this->objectSetup[ $key ]['file'] . '.class.php' );
		$o = new $this->objectSetup[ $key ]['class']( $this );
		$this->storeObject( $o, $key );
		return $o;
	}
	else
	{
		
	}
	
}

Because certain registry objects make use of abstract classes, or make use of keys which differ from its file name, the registry requires to be aware of what objects it could be asked to return, so that if it isn't already instantiated, it can include the appropriate files, instantiate it, and store it. This is done by passing an array of data to the registry to make it aware of these things.

$defaultRegistryObjects = array();
$db = array( 'abstract' => 'database', 'folder' => 'database', 'file' => 'mysql.database', 'class' => 'MySQLDatabase', 'key' => 'db' );
$defaultRegistryObjects['db'] = $db;
$template = array( 'abstract' => null, 'folder' => 'template', 'file' => 'template', 'class' => 'Template', 'key' => 'template' );
$defaultRegistryObjects['template'] = $template;
$urlp = array( 'abstract' => null, 'folder' => 'urlprocessor', 'file' => 'urlprocessor', 'class' => 'URLProcessor', 'key' => 'urlprocessor' );
$defaultRegistryObjects['urlprocessor'] = $urlp;
$scope = array( 'abstract' => 'scope', 'folder' => 'scope', 'file' => 'primary', 'class' => 'Primaryscope', 'key' => 'scope' );
$defaultRegistryObjects['scope'] = $scope;
$ctb = array( 'abstract' => null, 'folder' => 'contenttreebuilder', 'file' => 'contenttreebuilder', 'class' => 'ContentTreeBuilder', 'key' => 'contenttreebuilder' );
$defaultRegistryObjects['contenttreebuilder'] = $ctb;
$fm = array( 'abstract' => null, 'folder' => 'menu', 'file' => 'frontmenu', 'class' => 'Frontmenu', 'key' => 'frontmenu' );
$defaultRegistryObjects['frontmenu'] = $fm;

require_once( FRAMEWORK_PATH . 'registry/registry.class.php' );
$this->registry = new IckleRegistry( $defaultRegistryObjects );

How, objects which previously were always included and instantiated - taking processing time and using memory regardless of if they are used, or where within the execution cycle they are used, they are only included and instantiated as and when required.

Posted by Michael on 15th Feb 2011 at 12:12

Comments

As I understand, the method 'createAndStoreObject' is obsolete with 'lazy'-loading feature? We just need a 'getObject' and 'storeObject' methods? It would be great to see an example of abstract class usage.

Posted by AlexiuS on 30th January 2012 at 19:07

Add a comment