public
Last active

GAutoloader

  • Download Gist
GAutoloader.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
<?php
 
/**
* Simple autoloader mapping namespaces to paths.
*
* @property array $namespaces hash where namespace => absolute root-path
* @property array $classes hash where fully qualified class-name => absolute path
*/
class GAutoloader
{
/**
* @var array hash where namespace => absolute root-path
*/
private $_ns = array();
/**
* @var array hash where fully qualified class-name => absolute path
*/
private $_map = array();
/**
* @var string|null absolute default root-path for classes with no mapping; or null, if no default
*/
public $root = null;
/**
* Maps a namespace to a path.
*
* @param string $namespace fully qualified namespace
* @param string $path absolute root-path
* @return self
*/
public function addNamespace($namespace, $path)
{
if (is_dir($path) === false) {
throw new Exception("path not found: $path");
}
$this->_ns[$namespace] = $path;
return $this;
}
/**
* Maps a class-name to an absolute path.
*
* @param string $classname fully qualified class-name
* @param string $path absolute path to PHP class-file
* @return self
*/
public function addClass($classname, $path)
{
$this->_map[$classname] = $path;
return $this;
}
/**
* Map a class-name to a path using registered namespace and class paths.
*
* @param string $name fully qualified class-name
* @return string|null unchecked path to PHP class file; or null, if no root is configured
*/
public function map($name)
{
if (isset($this->_map[$name])) {
return $this->_map[$name]; // class-name is registered
}
 
$part = $name;
while ($offset = strrpos($part, '\\')) {
$part = substr($part, 0, $offset);
if (isset($this->_ns[$part])) {
return $this->_ns[$part] . DIRECTORY_SEPARATOR . strtr(substr($name, 1+strlen($part)), '\\', DIRECTORY_SEPARATOR) . '.php';
}
}
return ($this->root !== null)
? $this->root . DIRECTORY_SEPARATOR . strtr($name, '\\', DIRECTORY_SEPARATOR) . '.php'
: null;
}
/**
* Callback for SPL autoloader
*
* @return bool true if the class was autoloaded, otherwise false
* @see spl_autoload_register()
*/
public function load($name)
{
$path = $this->map($name);
if (($path===null) || (file_exists($path)===false)) {
return false;
}
@include_once($path);
return class_exists($name, false);
}
}
readme.md
Markdown

See discussion here:

http://www.yiiframework.com/forum/index.php/topic/10527-getting-yii-to-play-nice-with-php-5-3-namespaces/page__p__51702__hl__autoload+name+pace#entry51702

This autoloader only autoloads namespaces and classes that have been registered with it explicitly, and gives control back to the normal Yii autoloader otherwise.

To register namespaces, use Yii::getAutoloader()->addNamespace('foo\bar', '/path/to/foo/bar') and/or Yii::getAutoloader()->addClass('foo\bar\Baz', '/path/to/foo/bar/Baz.php').

Overlapping namespace registrations are permitted - the most specific path will be preferred. That is, when you autoload foo\bar\Baz, the path of the foo\bar namespace will be preferred, even if a path for foo is also registered. This enables you to e.g. override vendor-libraries that ship packaged with other vendor-libraries.

yii.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<?php
 
require(YII_PATH . DIRECTORY_SEPARATOR . 'YiiBase.php');
require(YII_PATH . DIRECTORY_SEPARATOR . 'GAutoloader.php');
 
class Yii extends YiiBase
{
private static $autoloader=null;
/**
* @return GAutoloader
*/
public static function getAutoloader()
{
if (self::$autoloader===null) {
self::$autoloader = new GAutoloader();
}
return self::$autoloader;
}
public static function autoload($className)
{
if (self::getAutoloader()->load($className)) {
return true;
}
return parent::autoload($className);
}
}
 
spl_autoload_unregister(array('YiiBase','autoload'));
 
spl_autoload_register(array('Yii','autoload'));

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.