* @link https://github.com/eriknyk/phpalchemy * @copyright Copyright 2012 Erik Amaru Ortiz * @license http://www.opensource.org/licenses/mit-license.php MIT License */ class Autoloader { /** * Holds singleton object * * @var ClassLoader */ protected static $instance = null; protected $includePaths = array(); protected $includeClassPaths = array(); protected $relativeIncludePaths = array(); /** * Creates a new SplClassLoader and installs the class on the SPL autoload stack * * @param string $ns The namespace to use. */ public function __construct() { defined('DS') || define('DS', DIRECTORY_SEPARATOR); spl_autoload_register(array($this, 'loadClass')); } public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self; } return self::$instance; } /** * Gets the base include path for all class files in the namespace of this class loader. * * @return string $includePath */ public function getIncludePaths() { return $this->includePaths; } /** * register a determinated namespace and its include path to find it. * * @param string $namespace namespace of a class given * @param string $includePath path where the class exists * @param string $excludeNsPart contais a part of class to exclude from classname passed by SPL hanlder */ public function register($namespace, $includePath) { $this->includePaths[$namespace] = rtrim($includePath, DS) . DS; } public function registerClass($classname, $includeFile) { $includeFile = strpos($includeFile, '.php') !== false ? $includeFile : $includeFile . '.php'; $classname = strtolower($classname); if (! file_exists($includeFile)) { throw new Exception("Error, Autoloader can't register a non exists file: " . $includeFile); } if (strpos($classname, '*') !== false) { $tmp = str_replace('*', '(.+)', $classname); $this->relativeIncludePaths[$tmp] = $includeFile; return; } if (array_key_exists($classname, $this->includeClassPaths)) { throw new Exception("Error, class '%s' is already registered in Autoloader."); } $this->includeClassPaths[$classname] = strpos($includeFile, '.php') !== false ? $includeFile : $includeFile . '.php'; } /** * Uninstalls this class loader from the SPL autoloader stack. */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } /** * Loads the given class or interface. * * @param string $className The name of the class to load. * @return void */ protected function loadClass($class) { $className = strtolower($class); if (array_key_exists($className, $this->includeClassPaths)) { require_once $this->includeClassPaths[$className]; return true; } else { foreach ($this->relativeIncludePaths as $relClassname => $includeFile) { if ($r = preg_match('/'.$relClassname.'/', $className, $match)) { require_once $includeFile; return true; } } } $filename = str_replace('_', DS, $class) . '.php'; foreach ($this->includePaths as $namespace => $includePath) { //var_dump($includePath . $filename); if (file_exists($includePath . $filename)) { require_once $includePath . $filename; return true; } } return false; } }