如何设计插件系统,以免浪费这么多资源?

Xeo*_*oss 8 php performance plugins design-patterns content-management-system

我正在尝试构建一个基本的插件系统,就像你经常在像WordPress这样的CMS中找到的那种.您有一个插件文件夹,它通过使用ObserverEvent设计模式的事件通知与主系统的操作相关联.

问题是系统不可能知道插件想要对哪些事件采取行动 - 因此系统必须为每个页面请求加载每个插件,以确定是否在某个时刻实际需要该插件.毋庸置疑,那里浪费了大量资源 - 在WordPress的情况下,每个请求会增加几个额外的MB内存!

有其他方法可以做到这一点吗?

例如,有没有办法加载所有这一次,然后缓存结果,以便您的系统知道如何延迟加载插件?换句话说,系统加载一个配置文件,该文件指定插件希望绑定的所有事件,然后将其保存在APC中,以便将来保存?

如果这也表现不佳,那么可能有一个特殊的文件结构可用于做出有关何时不需要某些插件来完成请求的有根据的猜测.

mar*_*rio 3

我确实有一个插件管理工具,但我只将它与主要的程序插件一起使用,并且所有包含的内容通常会立即加载。但对于基于事件和延迟加载的 API,我可以想象使用浅层包装器进行插件管理,并采用自动加载来实现实际扩展。

<?php
  /**
   * api: whatever
   * version: 0.1
   * title: plugin example
   * description: ...
   * config: <var name="cfg[pretty]" type="boolean" ...>
   * depends: otherplugin
   */

 $plugins["title_event"] = "TitleEventClass";
 $plugins["secondary"] = array("Class2", "callback");
?>
Run Code Online (Sandbox Code Playgroud)

在此示例中,我假设插件 API 是一个简单的列表。这个示例feature-plugin-123.php脚本除了在加载时添加到数组之外什么也不做。因此,即使您有十几个功能插件,include_once每个插件也只会产生额外的费用。

但主应用程序/或插件 API 可以只实例化所提到的类(new $eventcb;对于原始类名或call_user_func_array回调)。反过来,它将实际任务卸载到自动加载器。因此,您拥有一个双系统,其中一部分管理列表,另一部分定位真正的代码。

因此,我仍然想象一个简单的config.php,只列出插件和设置,如下所示:

<?php
include_once("user/feature-plugin-123.php");
include_once("user/otherplugin2.php");
include_once("user/wrapper-for-htmlpurifier.php");
$cfg["pretty"] = 1;
Run Code Online (Sandbox Code Playgroud)

再次记住,这些只是包装器/数据脚本,带有可管理性的插件描述。人们还可以使用实际的register_even()API 并在每个 API 中定义一个附加的包装函数。但列出类名似乎是最简单的选择。

前面提到的管理工具有点生锈和丑陋:http://milki.include-once.org/genericplugins/
但如果你只需要一个列表(sql 表)而没有设置管理,那么它是不需要的。该开销仅用于漂亮打印插件元数据并保持人类可读的config.php.

综上所述:

spl_autoload()在 include_path 上,以及一个简单的事件->类名注册表,每个包装脚本一个,只需一次包含所有内容。