<?php
/**
* @package genericarray
*/
/**
* Generic array loader. Singleton.
*/
final class ArrayOfGenericLoader {
private static $instance;
const PREFIX = 'ArrayOf';
public static function getInstance() {
if (!self::$instance) {
self::$instance = new ArrayOfGenericLoader();
}
return self::$instance;
}
public $cachedir;
private function __construct() {
$this->cachedir = dirname(__FILE__) . '/cache';
}
public function loadClass($classname) {
if (substr($classname, 0, strlen(self::PREFIX)) != self::PREFIX) return false;
if ($this->inCache($classname)) {
$this->loadFromCache($classname);
return true;
}
$this->createGeneric($classname);
return true;
}
private function inCache($classname) {
if (!file_exists($this->cachedir . '/check.' . $classname . '.php')) return false;
if (!file_exists($this->cachedir . '/' . $classname . '.php')) return false;
return require($this->cachedir . '/check.' . $classname . '.php');
}
private function loadFromCache($classname) {
require_once $this->cachedir . '/' . $classname . '.php';
}
private function createGeneric($classname) {
$genericClass = new ReflectionClass(self::PREFIX . 'GenericX');
$genericFile = $genericClass->getFileName();
$genericX = substr($classname, strlen(self::PREFIX));
$tokens = token_get_all(file_get_contents($genericFile));
$code = '';
foreach ($tokens as $token) {
if (is_array($token)) {
if ($token[0] == T_STRING) {
$token[1] = str_replace('GenericX', $genericX, $token[1]);
} else if ($token[0] == T_COMMENT || $token[0] == T_DOC_COMMENT) {
$token[1] = str_replace('GenericX', $genericX, $token[1]);
}
$code .= $token[1];
} else {
$code .= $token;
}
}
$checkCode = "<?php\n";
$checkCode .= "if (filemtime('" . addcslashes($genericFile, "'\\") . "') > filemtime(__FILE__)) {\n";
$checkCode .= " return false;\n";
$checkCode .= "}\n";
$checkCode .= "return true;\n";
file_put_contents($this->cachedir . '/check.' . $classname . '.php', $checkCode);
if (file_put_contents($this->cachedir . '/' . $classname . '.php', $code)) {
$this->loadFromCache($classname);
} else {
eval("?>$code");
}
}
}
?>
|