How can you create plugin systems so that they do not waste so many resources?

I am trying to create a basic plugin system similar to the one you often find in CMS, like WordPress. You have a folder of plugins that are attached to the main operation of the system through event notifications using the Observer or Event template.

The problem is that the system does not know what events the plug-in wants to act with - so the system must load each plug-in for each page request to find out if this plug-in is really needed at some point. It goes without saying that there are a lot of lost resources - in the case of WordPress, which adds up to several additional MB of memory for each request!

Are there any alternative ways to do this?

For example, is there a way to load it all once and then cache the results so that your system can use plugins with a lazy bootloader? In other words, does the system download a configuration file that defines all the events that the plug-in wants to connect and then saves them in APC or something for future requests?

If this also works poorly, there may be a special file structure that can be used to get reasonable assumptions about when some plugins are not needed to complete the request.

+8
performance php design-patterns plugins content-management-system
source share
3 answers

I have a plugin management tool, but I used it only with plugins with plugins, and with all enabled plugins it usually loads immediately. But for an event-based and lazy-loading API, I could imagine using small wrappers to manage plugins and resorting to automatic loading for actual extensions.

<?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"); ?> 

In this example, I would suggest that the plugin API is a simple list. In this example, feature-plugin-123.php script will do nothing but add to the array at boot time. Thus, even if you have a dozen function plugins, this will only result in an additional include_once everyone.

But the main application / or plugin API can instead simply create instances of the specified classes (either new $eventcb; for the original class names, or call_user_func_array for callbacks). In turn, this will lead to loading the actual task to the autoloader. So you have a dual system where one part manages the list and the other part real code.

I thus still imagine a simple config.php that simply lists plugins and settings like this:

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

Again, considering that these are just shells / data scripts, with a description of the plugin for manageability. You can also use the actual register_even() API and define an additional wrapper function in each. But a list of class names seems to be the easiest option.

The above management tool looks rusty and ugly: http://milki.include-once.org/genericplugins/
But it is not used if you just need a list (sql table) and configuration management. This overhead is only for beautifully printing plugin metadata and saving readable text to config.php .

Finally:

spl_autoload() on include_path and a simple register event-> classname, one shell script each, it just turns on all at once.

+3
source share

Wordpress and other CMS systems are very bad examples.

We must understand that modular almost always means heavier.

The best scheme I've ever worked with to solve this situation is a class-based plugin, with a strict naming convention using an autoloader.

So, before using the plugin, you need to instantiate or use static functions.

You can even call the plugin like:

 <?php $thePlugin::method(); ?> 

eg:

 <?php spl_autoload_register('systemAutoload'); function systemAutoload($class) { $parts = explode('_',$class); switch($parts[1]) { case "Plugin": include("/plugins/{$parts[2]}/{$parts[2]}.php"); break; } // ... } ?> 

Regarding events:

You must register this event statically so as not to bring it up dynamically.

A database would be a suitable place for this. You can have event tables and the install () and uninstall () methods in the plugin class to add specific events or bind methods to other events. This is one query to the database, and if you want to get more from it, add it to memcached or to a flat ini file.

Works well for me. Thus, I was able to get a heavy system that consumed 8 MB per request in order to drop to 1 MB, with exactly the same list of functions, without prior caching. Now we can add additional features and keep the system "clean"

Hope that helps

+2
source share

I would save the class name of the plugin along with its signed events in the configuration file, and then save the analyzed configuration file in APC, for example. Then, when the event is fired, the system can be too lazy to load the appropriate plugin classes as needed.

0
source share

All Articles