Skip to content

Instantly share code, notes, and snippets.

@sjoorm
Created April 14, 2016 12:51
Show Gist options
  • Save sjoorm/e9ab09e60156278951611536953af28e to your computer and use it in GitHub Desktop.
Save sjoorm/e9ab09e60156278951611536953af28e to your computer and use it in GitHub Desktop.
Simple implementation of multi-root class loader for PHP
<?php
/**
* Created by PhpStorm.
* @author: Alexey Tishchenko
* @email: alexey@atishchenko.com
* @UpWork: https://www.upwork.com/freelancers/~01ad7ed1a6ade4e02e
* @date: 12.03.16
*/
namespace sjoorm\config;
/**
* Class Loader is a simple implementation of an autoloader functionality
*/
class Loader {
const EXTENSION = '.php';
/** @var static instance */
protected static $loader;
/** @var array basic namespace names */
protected $namespaces;
/** @var array root directories */
protected $roots;
/**
* Creates Loader class object
*/
public static function init() {
if(!static::$loader instanceof static) {
static::$loader = new static();
}
return static::$loader;
}
/**
* Adds classes root directory
* @param string $root classes root dir
* @return Loader self reference
*/
public function addRoot($root) {
$this->roots[] = $root;
return $this;
}
/**
* Adds classes basic namespace
* @param string $namespace classes basic namespace (not presented by a subdirectory)
* @return Loader self reference
*/
public function addNamespace($namespace) {
$this->namespaces[] = $namespace;
return $this;
}
/**
* Loader constructor
*/
public function __construct() {
$this->namespaces = [];
$this->roots = [];
spl_autoload_register([
$this,
'load',
]);
}
/**
* @internal
* Attempts to load specified class
* @param string $className class to be registered
*/
public function load($className) {
$classNameParts = explode('\\', $className);
foreach($this->namespaces as $namespace) {
$namespaceParts = explode('\\', $namespace);
$found = false;
foreach($namespaceParts as $index => $part) {
if($classNameParts[$index] === $part) {
unset($classNameParts[$index]);
$found = true;
}
}
if($found) {
break;
}
}
foreach($this->roots as $root) {
$file = $root . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $classNameParts) . self::EXTENSION;
if(is_readable($file)) {
require($file);
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment