Created
April 30, 2016 21:44
-
-
Save WinterSilence/0ecf669c4cfffdad5050c3d14f68b17c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A general-purpose implementation that includes the optional functionality | |
* of allowing multiple base directories for a single namespace prefix. | |
*/ | |
class Psr4Autoloader | |
{ | |
const EXTENSION = '.php'; | |
/** | |
* An associative array where the key is a namespace prefix and the value | |
* is an array of base directories for classes in that namespace. | |
* | |
* @var array | |
*/ | |
protected $prefixes = []; | |
/** | |
* Register loader with SPL autoloader stack. | |
* | |
* @param bool $prepend If true, will prepend the autoloader on | |
* the autoload queue instead of appending it. | |
* @return $this | |
*/ | |
public function register($prepend = false) | |
{ | |
spl_autoload_register([$this, 'loadClass'], true, $prepend); | |
return $this; | |
} | |
/** | |
* Unregister loader with SPL autoloader stack. | |
* | |
* @return void | |
*/ | |
public function unregister() | |
{ | |
spl_autoload_unregister([$this, 'loadClass']); | |
} | |
/** | |
* Adds a base directory for a namespace prefix. | |
* | |
* @param string $prefix The namespace prefix. | |
* @param string $baseDir A base directory for class files in the namespace. | |
* @param bool $prepend If true, prepend the base directory to the stack. | |
* instead of appending it, this causes it to be searched first rather than | |
* last. | |
* @return this | |
*/ | |
public function addPrefix($prefix, $baseDir, $prepend = false) | |
{ | |
// Normalize namespace prefix. | |
$prefix = trim($prefix, '\\') . '\\'; | |
// Normalize the base directory with a trailing separator. | |
$baseDir = realpath($baseDir) . DIRECTORY_SEPARATOR; | |
// Initialize the namespace prefix array. | |
if (!isset($this->prefixes[$prefix])) { | |
$this->prefixes[$prefix] = []; | |
} | |
// Retain the base directory for the namespace prefix. | |
if ($prepend) { | |
array_unshift($this->prefixes[$prefix], $baseDir); | |
} else { | |
array_push($this->prefixes[$prefix], $baseDir); | |
} | |
return $this; | |
} | |
/** | |
* Loads the class file for a given class name. | |
* | |
* @param string $class The fully-qualified class name. | |
* @return bool | |
*/ | |
public function loadClass($class) | |
{ | |
if (strpos($class, '\\') !== false) { | |
foreach ($this->prefixes as $namespace => $baseDirs) { | |
if (strpos($class, $namespace) === 0) { | |
$path = substr($class, strlen($namespace)); | |
$path = str_replace('\\', DIRECTORY_SEPARATOR, $path) . self::EXTENSION; | |
foreach ($baseDirs as $baseDir) { | |
$file = $baseDir . $path; | |
// If the mapped file exists, require it | |
if ($this->requireFile($file)) { | |
return $file; | |
} | |
} | |
} | |
} | |
} | |
// Never found a mapped file | |
return false; | |
} | |
/** | |
* If a file exists, require it from the file system. | |
* | |
* @param string $file The file to require. | |
* @return bool | |
*/ | |
protected function requireFile($file) | |
{ | |
if (file_exists($file)) { | |
require $file; | |
return true; | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment