As I said before, LSB uses the keyword “static” to resolve at runtime conflicts that may occur in static contexts, like the one that you saw in the preceding section. To make the pertinent registry classes behave correctly, it’s necessary to tweak their definitions. So first, here’s how the base “RegistryAbstract” looks when we use late static bindings within its “getInstance()” method: (RegistryAbstract.php)
abstract class RegistryAbstract { protected static $_instances = array();
// get Singleton instance of the registry public static function getInstance() { // the static call to 'getClass()' is resolved at runtime $class = static::getClass(); if (!isset(self::$_instances[$class])) { self::$_instances[$class] = new $class; } return self::$_instances[$class]; }
// throw an exception as this class can't be instantiated protected static function getClass() { throw new RegistryException('This class is abstract and cannot be instantiated!'); }
// 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(); }
(RegistryException.php) RegistryException.php)
<?php
class RegistryException extends Exception{} As you may have noticed, the “getClass()” method is now called using the expression “static::getClass()” instead of the typical “self::getClass(),” which implies that the method will always be executed in the scope of the calling class. In other words, if the method is invoked by the abstract parent, it will raise an exception, which is the expected behavior; but when called inside the concrete array registry class, it will behave like this: (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; }
// get called class public static function getClass() { return __CLASS__; }
// clear the registry public function clear() { $this->_data = array(); } } Here’s the amended version of “getClass().” Now, when called from inside the previous “ArrayRegistry” class, the “getInstance()” method will effectively return an instance of this concrete registry, thanks to the functionality provided by late static bindings. The implementation of this Singleton method could be simplified by using another handy function included with PHP 5.3, named “get_called_class(),” but the details of this process will be discussed in an upcoming tutorial of this series. In the meantime, feel free to edit the source code of the previous registry classes. This process will arm you with a more solid background in working with LSB. Final thoughts In this first part of the series, I provided you with a concrete example that demonstrated how to use the feature called Late Static Bindings introduced in PHP 5.3.0. As you saw, it allows to solve problems that may arise when working with a static hierarchy of classes. It’s fair to say, however, that the aforementioned example in its current state looks rather incomplete, since it doesn’t include a script that shows how to put the registry classes defined so far to work together. Since I plan to create such a script in the next tutorial, I recommend you don’t miss it!
blog comments powered by Disqus |
|
|
|
|
|
|
|