我正在开发一个吉他和弦库。在库中的一些文件中,我有这样的内容:
require_once "lib/GuitarChord.php";
require_once "lib/Chord.php";
require_once "lib/Key.php";
require_once "lib/Tuning.php";
我怎样才能使这个库不需要知道其他库文件在哪里?
这样一个人可以在任何目录下拥有库文件?
为所有可能存在这些类的位置创建自动加载器
例如://AUTOLOADER
function class_autoloader($class) {
// presumes classes are in './classes'
$folders = array(
'./', './../', './../../'
);
$directories = array(
'classes','lib', ''
);
$dir = dirname(__FILE__);
$theClass = '/' . $folderedClass . '.php';
foreach($folders as $folder){
foreach($directories as $directory){
$theInclude = $dir.$folder.$directory.$theClass;
if (file_exists($theInclude) && include_once($theInclude)) {
return TRUE;
}
}
}
trigger_error("The class '$class' or the file '$theClass' failed to spl_autoload ", E_USER_WARNING);
return FALSE;
}
spl_autoload_register('class_autoloader');
然后,如果你想加载Chord
类,并且你知道它在你的lib
文件夹中,自动加载器会在你执行以下操作时为你完成工作:
new Chord();
您可以使用spl_autoload_register
附加许多不同的自动加载器回调
你应该检查一下名称空间和自动加载器
让我们假设你所有的类都在"GuitarChords"命名空间中-所以你可以创建类似于下面的自动加载函数(假设文件,你注册的自动加载器在"lib"的父目录下):
spl_autoload_register(function($class){
$namespace = explode('''', $class, 2);
if ($namespace[0] === 'GuitarChords' && isset($namespace[1])) {
include(__DIR__.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.$namespace[1].'.class.php');
}
});
我认为最好为每个库集/命名空间专门注册一个自动加载函数。遍历目录并使用include_once, file_exists等可能会产生一些讨厌的IO开销,这取决于系统的复杂性。
如果您不想在一个文件中包含所有类,则必须在某个地方包含文件夹名称。你可以把它放在用户只需要设置一次的地方:
$lib_folder = "lib";
require_once $lib_folder . "/GuitarChord.php";
require_once $lib_folder . "/Chord.php";
require_once $lib_folder . "/Key.php";
require_once $lib_folder . "/Tuning.php";
至于处理不同类型的数据库,你可以做另一个设置,如$db_type,用户可以设置为"MYSQL","FILE","XML"等。当你调用数据库时,使用switch语句来查看他们正在使用的数据库方法,并相应地更改调用。
Edit: PHP的__autoload特性也值得一看
您可以尝试Zend AutoLoader
如果您的库使用了所有或大部分包含的类,那么请考虑将与您的库相关的所有类放在同一个文件中。其他解决方案只涉及添加更多代码,在这种情况下,你可能应该坚持使用当前的方法。
如果您希望将这些文件分开用于开发目的,那么无论如何都可以继续这样做,但您仍然可以将其打包成一个文件以供生产使用,以便人们轻松包含。