通过sp_autoload_Register自动加载类的问题/可能会干扰特定于WP的自动加载器

时间:2013-03-06 作者:tfrommen

我正在开发一个插件,我在其中为自动加载类执行以下操作:

function TFSLAutoload($class) {
    $classfile = dirname(__FILE__).\'/includes/\'.strtolower($class).\'.php\';
    include $classfile;
} // function TFSLAutoload
spl_autoload_register(\'TFSLAutoload\');
在插件(类)中,我可以实例化类(例如,使用$myClassXYZ = new MyClassXYZ();) 以及使用静态功能(例如。,MyClassXYZ::my_static_func();) 不包括/不需要定义类的文件。简而言之,一切都按预期进行。

然而,当WP_DEBUG 设置为true时,我确实会收到以下警告:

Warning: include(/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/wp_atom_server.php): failed to open stream: No such file or directory in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31 
Warning: include(): Failed opening \'/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/wp_atom_server.php\' for inclusion (include_path=\'.:\') in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31 
Warning: include(/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/Recursive_ArrayAccess.php): failed to open stream: No such file or directory in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31 
Warning: include(): Failed opening \'/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/Recursive_ArrayAccess.php\' for inclusion (include_path=\'.:\') in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31
Warning: include(/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/WP_Session.php): failed to open stream: No such file or directory in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31 
Warning: include(): Failed opening \'/var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/includes/WP_Session.php\' for inclusion (include_path=\'.:\') in /var/www/vhosts/MY-DOMAIN.TLD/wp-content/plugins/tf-song-list/tf-song-list.php on line 31
然后,我更改了自动加载功能,首先检查文件是否存在:

function TFSLAutoload($class) {
    $classfile = dirname(__FILE__).\'/includes/\'.strtolower($class).\'.php\';
    if (file_exists($classfile)) include $classfile;
    else echo "File »$classfile« does not exist.".PHP_EOL;
} // function TFSLAutoload
spl_autoload_register(\'TFSLAutoload\');
现在,autoloader只加载我自己的插件类文件,因为它们是预定义文件夹中唯一的文件。

然而,如果上述三个WordPress类仍然通过我的Autolaorder类“发送”,那么WP是否(实际上)正确加载了它们?还是我的自动加载器与WP的内置自动加载器竞争?我如何检查?或者:我是否以错误的方式进行了整个自动加载?

为什么这三门课要送到我的自动加载器?它们是加载插件后唯一要加载的吗?

4 个回复
最合适的回答,由SO网友:fuxia 整理而成

WordPress中没有内置自动加载器。但是其他插件或主题可能已经注册了自动加载器,根据执行顺序,这些插件或主题的调用时间可能早于或晚于您的插件或主题。

<小时>Update 21. 08. 2014 这个答案不再是我的建议。如果需要,请使用自动装弹机。

确保被调用类由代码负责的唯一方法是检查file_exists() 并测试类名。

file_exists() 速度很慢,其结果由文件系统缓存,因此无论如何都不能依赖它。

我建议不要使用自动装弹机。改用插件特定的类加载器。

示例:

/**
 * Load a class from /php/ directory.
 *
 * There is no file_exists() check to improve performance.
 *
 * @param  string  $class         Class name
 * @param  boolean $create_object Return an object or TRUE
 * @return bool|$class
 */
function t5_es_load_class( $class, $create_object = FALSE )
{
    // create the path base just once
    static $base = FALSE;

    ! $base && $base = plugin_dir_path( __FILE__ ) . \'php\';
    ! class_exists( $class ) && require "$base/class.$class.php";

    return $create_object ? new $class : TRUE;
}
现在您可以使用此函数来只包含类…

t5_es_load_class( \'T5_Metabox_Base\' );
$metabox = new T5_Metabox_Base( \'preview\' );
…或创建对象…

$data               = t5_es_load_class( \'T5_Property_List\', TRUE );
$data->plugin_url   = plugin_dir_url( __FILE__ );
$data->plugin_path  = plugin_dir_path( __FILE__ );
更快、更可靠、更灵活。

SO网友:Ciantic

如果您的类有唯一的名称空间,它就可以工作。我使用此方案:

比方说,在名称空间中填充所有类myplugin (当然,您可能还有更多的名称空间,如myplugin\\otherstuff\\...

创建仅在此命名空间中加载类的自动加载程序,您可以使用它,将其放在插件文件的顶部:

define("MYPLUGIN_DIR", plugin_dir_path(__FILE__));

// Notice strlen(...) calls should be written as number for speed
spl_autoload_register(function ($className) {           
    // Make sure the class included is in this plugins namespace
    if (substr($className, 0, strlen("myplugin\\\\")) === "myplugin\\\\") {
        // Remove myplugin namespace from the className
        // Replace \\ with / which works as directory separator for further namespaces
        $classNameShort = str_replace("\\\\", "/", substr($className, strlen("myplugin\\\\")));
        include_once MYPLUGIN_DIR . "classes/$classNameShort.php";
    }
});
就是这样,如果每个插件都有不同的名称空间,那么它可以很好地用于多个插件(无论如何,您应该这样做)。

SO网友:D.A.H

您现在可以使用WordPress自动加载插件。它还支持您自己的自动加载方法。

请参见WordPress Plugin page 了解更多详细信息。

正确使用PHP \\uu自动加载可以显著减少WP站点加载时间。

您自己的自动加载函数示例有问题。您应该进行一些排序验证,以确保只加载自己的类,以避免出现问题。

请注意,如果加载类,建议使用require\\u once或i

SO网友:user44321

github上有一个简单的函数类,可以自动加载名称空间或不加载名称空间:Autoload classes in wordpress

结束

相关推荐

使用PHP切换在Cookie中设置的样式表和标题图像

我以前没有做过很多关于cookies或Wordpress的工作,所以我觉得我在我的探索中有点过于乐观了:p我为我的网站创建了两个主题,夜晚和白天。我希望用户能够从侧边栏中启用php的文本小部件中选择他们想要的主题,然后根据他们的选择设置cookie,更改为适当的样式表(style.css用于night,默认值,style1.css用于day),并加载新的标题图像。我这里有一些功能,http://somethingoriginal.net, 然而,在Chrome中,cookie似乎并没有像我所说的那样立即设