यहां एक वर्ग है जिसे मैंने कुछ समय पहले इसी उद्देश्य के लिए लिखा था। उस समय मैं अभी भी सीखने के चरण में था, इसलिए बेवकूफ विचार शामिल हो सकते हैं; यह फिर भी काम किया।
मूल विचार यह है कि यह एक बार स्रोत निर्देशिका स्कैन करता है, और अपनी स्रोत फ़ाइलों में सरणी मैपिंग कक्षाएं बनाता है। कक्षा एक ऑटोलोडर के रूप में पंजीकृत है, और जब लागू किया जाता है, इसमें आवश्यक फ़ाइल शामिल होती है। यदि नहीं मिला, तो यह फ्लाई पर सरणी को पुनर्निर्माण करने का प्रयास करता है।
/* register ClassLoader as class loader */
spl_autoload_register(array(ClassLoader::getInstance(), 'loadClass'));
class ClassLoader {
private static $SAVE_FILE = 'ClassLoader.save.php';
/* singleton */
private static $instance;
/* stores a className -> filePath map */
private $classList;
/* tells whether working from saved file */
private $refreshed;
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new ClassLoader();
}
return self::$instance;
}
private function __construct() {
$this->initClassList();
}
public function loadClass($className) {
if (!array_key_exists($className, $this->classList) && !$this->refreshed) {
$this->refreshClassList();
}
require_once($this->classList[$className]);
}
private function initClassList() {
if (file_exists(INCLUDES_DIR . self::$SAVE_FILE)) {
require_once(INCLUDES_DIR . self::$SAVE_FILE);
$this->refreshed = FALSE;
} else {
$this->refreshClassList();
}
}
private function refreshClassList() {
$this->classList = $this->scanDirectory(INCLUDES_DIR);
$this->refreshed = TRUE;
$this->saveClassList();
}
private function saveClassList() {
$handle = fopen(INCLUDES_DIR . self::$SAVE_FILE, 'w');
fwrite($handle, "<?php\r\n");
foreach($this->classList as $class => $path) {
$line = '$this->classList' . "['" . $class . "'] = '" . $path . "';\r\n";
fwrite($handle, $line);
}
fwrite($handle, '?>');
fclose($handle);
}
private function scanDirectory ($directory) {
// strip closing '/'
if (substr($directory, -1) == '/') {
$directory = substr($directory, 0, -1);
}
if (!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) {
return array();
}
$dirH = opendir($directory);
$scanRes = array();
while(($file = readdir($dirH)) !== FALSE) {
// skip pointers
if (strcmp($file , '.') == 0 || strcmp($file , '..') == 0) {
continue;
}
$path = $directory . '/' . $file;
if (!is_readable($path)) {
continue;
}
// recursion
if (is_dir($path)) {
$scanRes = array_merge($scanRes, $this->scanDirectory($path));
} elseif (is_file($path)) {
$className = explode('.', $file);
if (strcmp($className[1], 'class') == 0 && strcmp($className[2], 'php') == 0) {
$scanRes[$className[0]] = $path;
}
}
}
return $scanRes;
}
}
मुझे इस विधि को बहुत अच्छी तरह से काम करने के लिए मिला है। मैंने उपयोग की एक और विधि फ़ोल्डर मैप में स्थिर पैकेज का उपयोग करना है, जो रूट-निर्देशिकाओं को इंगित करता है जिसके अंतर्गत उपर्युक्त विधि लागू होती है। महान स्पष्टीकरण लिंक के लिए –
+1 जो __autoload को बहुत अच्छी तरह से समझाता है: http://blog.straylightrun.net/2009/05/06/autoload-magic/ –