Created
October 12, 2015 03:25
-
-
Save superdav42/55f53b30ca5b5c724c6b to your computer and use it in GitHub Desktop.
Symlink Autoloader cache
This file contains 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 | |
namespace Symfony\Component\ClassLoader; | |
/** | |
* A caching class loader similar to ApcClassLoader | |
* Creates a symlink for each loaded file so it can be quickly loaded again later | |
*/ | |
class SymlinkClassLoader | |
{ | |
private $cachePath; | |
/** | |
* A class loader object that implements the findFile() method. | |
* | |
* @var object | |
*/ | |
protected $decorated; | |
/** | |
* Constructor. | |
* | |
* @param string $cachePath The path to store symlinks in | |
* @param object $decorated A class loader object that implements the findFile() method. | |
* | |
* @throws \RuntimeException | |
* @throws \InvalidArgumentException | |
* | |
* @api | |
*/ | |
public function __construct($cachePath, $decorated) | |
{ | |
if (!method_exists($decorated, 'findFile')) { | |
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); | |
} | |
$this->cachePath = $cachePath; | |
if(false === is_dir($cachePath)) { | |
mkdir($cachePath); | |
} | |
$this->decorated = $decorated; | |
} | |
/** | |
* Registers this instance as an autoloader. | |
* | |
* @param bool $prepend Whether to prepend the autoloader or not | |
*/ | |
public function register($prepend = false) | |
{ | |
spl_autoload_register(array($this, 'loadClass'), true, $prepend); | |
} | |
/** | |
* Unregisters this instance as an autoloader. | |
*/ | |
public function unregister() | |
{ | |
spl_autoload_unregister(array($this, 'loadClass')); | |
} | |
/** | |
* Loads the given class or interface. | |
* | |
* @param string $class The name of the class | |
* | |
* @return bool|null True, if loaded | |
*/ | |
public function loadClass($class) | |
{ | |
$path = $this->cachePath.DIRECTORY_SEPARATOR.$class.'.php'; | |
if(includeFile($path)) { | |
return true; | |
} else { | |
if ($file = $this->decorated->findFile($class)) { | |
includeFile($file); | |
symlink($file, $path); | |
return true; | |
} | |
} | |
} | |
/** | |
* Passes through all unknown calls onto the decorated object. | |
*/ | |
public function __call($method, $args) | |
{ | |
return call_user_func_array(array($this->decorated, $method), $args); | |
} | |
} | |
/** | |
* Scope isolated include. | |
* | |
* Prevents access to $this/self from included files. | |
*/ | |
function includeFile($file) | |
{ | |
if(file_exists($file)) { //ideally we find a way to avoid using file_exists everytime | |
include $file; | |
return true; | |
} | |
return false; | |
} | |
// USAGE in app.php etc | |
$loader = require_once __DIR__.'/../app/bootstrap.php.cache'; | |
// or $loader = require_once __DIR__.'/../app/autoload.php'; | |
$symlinkLoader = new SymlinkClassLoader(__DIR__.'/../app/cache/dev/symlinkCache', $loader); | |
$loader->unregister(); | |
$symlinkLoader->register(true); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment