Pas*_*TIN 17
您可能需要查看PEAR约会的类名,这对于自动加载非常有用.
基本上,它声明:
PEAR类层次结构也反映在类名中,层次结构的每个级别用单个下划线分隔.
这意味着找到要包含在classe名称中的文件HTML_Upload_Error只需要用'/'替换'_'; 给你HTML/Upload/Error.php
有关更多说明和几个示例,您可以查看文章:
BTW:这个约定被很多大型框架/库使用;-)
例如,Zend Framework使用这个约定 - 它真的很有帮助!
Zed*_*Zed 10
这是我前一段时间为了类似目的写的课程.那个时候我还处于学习阶段,所以可能会有愚蠢的想法; 尽管如此.
它的基本思想是扫描源目录一次,并创建一个数组映射类到其源文件.该类被注册为自动加载器,并在调用时包含所需的文件.如果未找到,它会尝试动态重建阵列.
/* 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;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,您必须显式添加每个目录。这可以在递归遍历目录的脚本中以编程方式完成,也可以指定一个列表。
也许最有效的方法是指定要搜索的目录和子目录列表,并使用 ini_set() 将它们添加到“include_path”中。