Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created December 7, 2012 16:43
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindplay-dk/4234540 to your computer and use it in GitHub Desktop.
Save mindplay-dk/4234540 to your computer and use it in GitHub Desktop.
GAutoloader

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.

<?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);
}
}
<?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'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment