As I mentioned in the introduction, PHP 5.3 includes the “get_called_class()” function, which allows you to replicate most of the functionality of Late Static Bindings without having to explicitly use the keyword “static.” Simply put, the function permits you to determine at runtime which class was called from a given static method. In case you haven’t read the previous article of the series, where I discussed how to use this function in the construction of a flexible hierarchy of Singleton registry classes, below I listed the definitions of these registries, starting with the abstract parent. Here it is: (RegistryAbstract.php)
abstract class RegistryAbstract { protected static $_instances = array();
// get Singleton instance of the registry public static function getInstance() { $class = get_called_class(); if (!isset(self::$_instances[$class])) { self::$_instances[$class] = new $class; } return self::$_instances[$class]; }
// implemented by registry subclasses abstract public function set($key, $value);
// implemented by registry subclasses abstract public function get($key);
// implemented by registry subclasses abstract public function clear(); } As its name suggests, the above “RegistryAbstract” class defines the structure and partial functionality of generic registries, a process that’s very easy to follow. Prior to PHP 5.3, its “getInstance()” Singleton method would always attempt to return an instance of this abstract class, therefore raising a fatal error. However, with the introduction of the “get_called_class()” function, this issue can be solved with minor hassles. To understand how useful this function really is, pay attention to the definition of the following class. It is a simple array-based registry derived from the previous abstract parent: (ArrayRegistry.php)
<?php
class ArrayRegistry extends RegistryAbstract { private $_data = array();
// save data to the registry public function set($key, $value) { $this->_data[$key] = $value; return $this; }
// get data from the registry public function get($key) { return isset($this->_data[$key]) ? $this->_data[$key] : null; }
// clear the registry public function clear() { $this->_data = array(); } } To be frank, the definition of this concrete registry is nothing spectacular, with the sole exception of a small subtlety: its inherited “getInstance()” method is still functional! But, to understand this more clearly, please take a look at the following script. It uses an instance of this registry class to fetch and save some fictional data to a private array: <?php
// include source classes require_once 'RegistryAbstract.php'; require_once 'ArrayRegistry.php';
try { // grab the Singleton instance of the ArrayRegistry class $arrayRegistry = ArrayRegistry::getInstance(); // save some users to the registry $arrayRegistry->set('user1', 'Julie Smith')->set('user2', 'Mary Wilson'); // get the second user from the registry echo $arrayRegistry->get('user2'); /* displays the following Mary Wilson */ }
catch (Exception $e) { echo $e->getMessage(); exit(); } There you have it. As the above script shows, grabbing the Singleton instance of the previous array registry class is a breeze due to the use of the “get_called_class()” function behind the scenes. Logically, deriving only one concrete registry from an abstract parent is a pretty pointless process that doesn’t fully exploit the benefits of Inheritance; nevertheless, you may want to use the earlier example as a starting point and create multiple registry classes. In doing so, you’ll realize how powerful the “get_called_class()” function can be when creating hierarchies of classes that share at least one static method. All right, having recreated a situation where LSB can be applied successfully, it’s time to explore other possible uses of this feature. So far, I showed how to work LSB from inside a static method, and the definition of the previous “getInstance()” method is a good example of this. It’s possible, though, to take advantage of this feature when working in the object scope as well. In the upcoming section I’m going to build a simple abstract factory class where the constructors of its concrete factories will employ LSB to create some predefined (X)HTML widgets. Now, click on the link below and keep reading.
blog comments powered by Disqus |
|
|
|
|
|
|
|