这是我为您尝试的自动加载。
我稍微修改了Emil Condrea's Answer。
首先,我将向您展示我的类的文件结构:
正如您在上面看到的,这些类被设置为单独的文件等以显示。
现在采用 Emil 的 答案并稍作改动:
(如果文件名类似于上面文件结构中的“Class.php”)
function getClasses($path) {
$files = array();
$dir_iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
foreach ($dir_iterator as $item) {
$pathname = $item->getPathName();
$filename = $item->getFileName();
if ($item->isDir()) {
getClasses($item);
} else {
$files[$filename] = $pathname;
}
}
return $files;
}
将保证返回文件数组,如以下 [FILE_NAME] => [PATH_NAME]:
Array
(
[Error.php] => /home2/DERP/public_html/something.com/watch/model/Site/Error.php
[Form.php] => /home2/DERP/public_html/something.com/watch/model/Site/Form.php
[Site.php] => /home2/DERP/public_html/something.com/watch/model/Site/Site.php
[Db.php] => /home2/DERP/public_html/something.com/watch/model/Database/Db.php
[Db_pdo.php] => /home2/DERP/public_html/something.com/watch/model/Database/Db_pdo.php
[Session.php] => /home2/DERP/public_html/something.com/watch/model/Security/Session.php
[Auth.php] => /home2/DERP/public_html/something.com/watch/model/Security/Auth.php
[Input.php] => /home2/DERP/public_html/something.com/watch/model/Security/Input.php
[Postcode.php] => /home2/DERP/public_html/something.com/watch/model/Postcode.php
[Rep.php] => /home2/DERP/public_html/something.com/watch/model/User/Rep.php
[User.php] => /home2/DERP/public_html/something.com/watch/model/User/User.php
[Notifications.php] => /home2/DERP/public_html/something.com/watch/model/User/Notifications.php
[Log.php] => /home2/DERP/public_html/something.com/watch/model/Log/Log.php
[Hook.php] => /home2/DERP/public_html/something.com/watch/model/Hook.php
)
现在它会被类似下面的东西调用:
getClasses(realpath(dirname(__FILE__)) . '/model')
允许我们运行__autoload(),如下所示:
$model_classes = getClasses(realpath(dirname(__FILE__)) . '/model');
function __autoload($class_name) {
global $model_classes;
$filename = ucfirst($class_name) . '.php';
$model = $filename;
if (!isset($model_classes[$model])) {
// dead
return false;
} else {
// include first file (model)
include($model_classes[$model]);
}
}
现在
显然你不应该使用global,但对我来说,它似乎比在__autoload() 函数中每次都运行getClasses() 函数更好。
如果其他人有什么要补充的,请随意!我只是尝试了我自己的小方法,它可以正常工作!
注意:
我之前使用的是
file_exists(),我认为上述方法是;快很多。
更新
就在前几天晚上,我有一个脑电波,然后想;
"为什么不扫描应用程序根目录并获取所有 php 文件,然后运行一个函数来检查所述文件是否真的包含一个类以使其尽可能通用.."
所以我做了一些研究,从 php 中找到了这个漂亮的小函数:token_get_all()
现在经过一番挖掘,我找到了这个答案:Determine class in file...
经过一些修改,getClasses() 函数现在看起来像这样:
function getClasses($path) {
$files = array();
$dir_iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
foreach ($dir_iterator as $item) {
$pathname = $item->getPathName();
$filename = $item->getFileName();
if ($item->isDir()) {
get_classes($item);
} else {
if (substr($filename, -4) === '.php') {
if (get_php_classes(file_get_contents($pathname))) {
$files[$filename] = $pathname;
}
}
}
}
return $files;
}
加上上述问题的这个新功能:
function get_php_classes($php_code) {
$tokens = token_get_all($php_code);
$class_token = false;
foreach ($tokens as $token) {
if (is_array($token)) {
if ($token[0] == T_CLASS) {
$class_token = true;
} else if ($class_token && $token[0] == T_STRING) {
$classes[] = $token[1];
// $class_token = false;
}
}
}
return $class_token;
}
现在,您可以简单地运行 $classes = getClasses(ROOTPATH) 并遍历它们。
DOWNFALL:每个类都必须有唯一的类名和/或文件名。除非有人可以帮忙修改以允许。