我理解如何注册自动加载器甚至如何创建自动加载器,这根本不是问题。然而,主要问题是 - 如何让两个自动装载机并排运行:
class project_one_folder_class extends project_two_folder_class{}
您会注意到子类属于一个伸出并调用位于不同项目中的父类的项目。
项目链接的方式项目的两个类总是被自动加载器看到,如何从未见过项目的类。
所以我想到的方法是编写两个自动加载器并注册它们,因为php会查看另一个。 php似乎只在一个而不是另一个中查找。
你怎么解决这个问题?修改
项目二是父项目,项目一项是项目。这是一个更加扩展的问题,然后是What was posted on this question。
为了更好地扩展这是我的班级。
class AisisCore_Loader_AutoLoader{
protected static $_instance;
public function get_instance(){
if(null == self::$_instance){
self::$_instance = new self();
}
return self::$_instance;
}
public function reset_instance(){
self::$_instance = null;
}
public function register_auto_loader(){
spl_autoload_register(array($this, 'load_class'));
spl_autoload_register(array($this, 'load_child_class'));
}
public function load_class($class){
$path = str_replace('_', '/', $class);
if(file_exists(get_template_directory() . '/' . $path . '.php')){
require_once(get_template_directory() . '/' . $path . '.php');
}
}
public function load_child_class($class){
$path = str_replace('_', '/', $class);
if(file_exists(get_stylesheet_directory() . '/' . $path . '.php')){
require_once(get_stylesheet_directory() . '/' . $path . '.php');
}
}
}
目前这个类将在父项目中加载任何内容。它甚至会在子项目中加载父项目对象。但是,如果找不到子类,则无法使用此类加载子对象。
那些熟悉WordPress的人会立即说,是的,因为你需要get_template_directory
时get_stylesheet_directory
然而 - 知道这一点 - 我想编写两个自动加载器,一个将加载子项目使用get_stylesheet_directory
的对象然后通过get_stylesheet_directory
加载父对象的对象,以便:
class project_one_folder_class extends project_two_folder_class{}
工作和加载,没有错误。
答案 0 :(得分:1)
当然,当第一个file_exists返回false时,您可以在同一个自动加载器中查找第二个路径。
您还可以为第二条路径注册第二个自动加载器。
PHP docs解决了这个问题:
如果必须有多个自动加载功能,
spl_autoload_register()
允许这样做。它有效地创建了一个自动加载功能队列,并按照它们的定义顺序遍历每个功能。相比之下,__autoload()
可能只定义一次。
答案 1 :(得分:1)
这有点粗糙,但实际上只需要一个只在多个目录中检查的自动加载器:
abstract class Hakre_Theme_AutoLoader
{
public static $directories;
public static function init()
{
// configure paths
self::$directories = array(
get_template_directory(), // current theme, parent in case of childtheme
get_stylesheet_directory(), // current theme, child in case of childtheme
);
// please double check if you really need to prepend
return spl_autoload_register('Hakre_Theme_AutoLoader::autoload', true, true);
}
public static function autoload($class)
{
$filename = str_replace('_', '/', $class) . '.php';
foreach (self::$directories as $directory) {
$path = $directory . '/' . $filename;
if (is_file($path)) {
require($path);
return; # leave because the class has been loaded
}
}
}
}
Hakre_Theme_AutoLoader::init();
## If you're unsure all worked out properly:
var_dump(Hakre_Theme_AutoLoader::$directories);
这实际上应该这样做,但我还没有测试过。请参阅var_dump
,您可以调试是否注册了正确的目录。不需要多次回调只是因为你想签入两个目录。
答案 2 :(得分:1)
分开自动加载过程!
PHP的工作原理如下:在某些时候,代码执行会偶然发现尚未加载的类引用。 $obj = new project_one_folder_class()
现在调用已注册的自动加载器函数,从首先添加的函数开始(除非稍后添加的函数使用“prepend”参数)。
第一个(以及所有后续的)自动加载函数获取应加载的类的名称。该功能现在有权决定
步骤1通常通过查看要加载的类名是否以某个前缀开头来解决。在您的情况下,负责加载以“project_one_”开头的类的自动加载器不应该尝试从其他类开始加载任何其他类。
如果自动装带器知道它必须执行自动加载,则执行步骤2。它现在将类名转换为相对路径和文件名,添加基目录,然后需要该文件。
要求定义扩展另一个类(或实现接口)的类的文件然后可以触发另一个自动加载的任何未知类的运行。在您的情况下,再次启动自动加载过程,类名为“project_two_folder_class”。请注意,将使用此第二个类名称再次调用“project_one_”类的第一个自动加载器,但它不能执行任何操作,因为它不知道如何加载这些类。这取决于知道“project_two_”类的自动加载器。
注册顺序对于不同的自动加载器无关紧要。如果是这样,自动装载机行为不端。
因为简单地将类名中的任何下划线字符转换为DIRECTORY_SEPARATOR以及命名空间中的反斜杠是一种常见模式,所以最后添加“.php”,然后尝试从定义的基本目录中加载此文件,这两个自动加载器的代码是相同的,并且问题被简化为只配置一个自动加载功能,这两种情况:应该存在哪个前缀,以及文件应该在哪个基本目录中,前提是类名可以转换为文件的相对路径。
每次检查文件是否存在于某个目录中都不是最佳性能。您最终会对文件进行大量检查,只需查看类名,您就无法加载这些文件。
顺便说一句:自动加载器功能不需要是单例。实际上,你的单例实现是破坏的,没用。使用new
实例化自动加载器,可能会将一些配置值传递给构造函数,并调用spl_autoload_register()
,您应该完成。
答案 3 :(得分:0)
您可以添加多个加载器,只需使用spl_autoload_register()注册每个函数。
程序风格:
spl_autoload_register('loader_function1'));
// your second class location
spl_autoload_register('loader_function2'));
或以OO风格
spl_autoload_register(array($this, 'loader_function1'));
spl_autoload_register(array($this, 'loader_function2'));
然而,基于您的问题:您可以通过使用更灵活的自动加载器来完成相同的任务 在这里看到我的答案在另一个问题: Class autoloader in wordpress plugin