note 69514 added to language.oop5.autoload

From: Date: Fri, 08 Sep 2006 13:23:45 +0000
Subject: note 69514 added to language.oop5.autoload
Groups: php.notes 
Request: Send a blank email to php-notes+get-116904@lists.php.net to get a copy of this message
I'm sure this is needed by more than me. My objective was to allow __autoload() to be easily extended in complex systems/frameworks where specific libraries etc may need loading differently but you don't want to hard-code little adjustments into your working __autoload() to allow this to happen. Using a ServiceLocator object with some static methods and properties to allow loosely coupled locators to be attached to it you can swap/change and add to the functionality of your __autoload() at runtime. The core stuff: <?php /** * Defines the methods any actual locators must implement * @package ServiceLocator * @author Chris Corbyn */ interface Locator { /** * Inform of whether or not the given class can be found * @param string class * @return bool */ public function canLocate($class); /** * Get the path to the class * @param string class * @return string */ public function getPath($class); } /** * The main service locator. * Uses loosely coupled locators in order to operate * @package ServiceLocator * @author Chris Corbyn */ class ServiceLocator { /** * Contains any attached service locators * @var array Locator */ protected static $locators = array(); /** * Attach a new type of locator * @param object Locator * @param string key */ public static function attachLocator(Locator $locator, $key) { self::$locators[$key] = $locator; } /** * Remove a locator that's been added * @param string key * @return bool */ public static function dropLocator($key) { if (self::isActiveLocator($key)) { unset(self::$locators[$key]); return true; } else return false; } /** * Check if a locator is currently loaded * @param string key * @return bool */ public static function isActiveLocator($key) { return array_key_exists($key, self::$locators); } /** * Load in the required service by asking all service locators * @param string class */ public function load($class) { foreach (self::$locators as $key => $obj) { if ($obj->canLocate($class)) { require_once $obj->getPath($class); if (class_exists($class)) return; } } } } /** * PHPs default __autload * Grabs an instance of ServiceLocator then runs it * @package ServiceLocator * @author Chris Corbyn * @param string class */ function __autoload($class) { $locator = new ServiceLocator(); $locator->load($class); } ?> An example Use Case: <?php require 'ServiceLocator.php'; //Define some sort of service locator to attach... class PearLocator implements Locator { protected $base = '.'; public function __construct($directory='.') { $this->base = (string) $directory; } public function canLocate($class) { $path = $this->getPath($class); if (file_exists($path)) return true; else return false; } public function getPath($class) { return $this->base . '/' . str_replace('_', '/', $class) . '.php'; } } // ... attach it ... ServiceLocator::attachLocator(new PearLocator(), 'PEAR'); // ... and code away.... $foo = new Foo_Test(); ?> ---- Server IP: 85.116.0.130 Probable Submitter: 213.205.138.154 ---- Manual Page -- http://www.php.net/manual/en/language.oop5.autoload.php Edit -- https://master.php.net/note/edit/69514 Del: integrated -- https://master.php.net/note/delete/69514/integrated Del: useless -- https://master.php.net/note/delete/69514/useless Del: bad code -- https://master.php.net/note/delete/69514/bad+code Del: spam -- https://master.php.net/note/delete/69514/spam Del: non-english -- https://master.php.net/note/delete/69514/non-english Del: in docs -- https://master.php.net/note/delete/69514/in+docs Del: other reasons-- https://master.php.net/note/delete/69514 Reject -- https://master.php.net/note/reject/69514 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#116904) next »