note 69514 added to language.oop5.autoload
| From: | (chrisATw3style.co.uk) | 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