PHPackages                             noccylabs/pluggable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. noccylabs/pluggable

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

noccylabs/pluggable
===================

Plugin manager for applications

0.2.4.3(11y ago)2211GPL-3.0PHP

Since May 7Pushed 11y ago1 watchersCompare

[ Source](https://github.com/noccy80/php-pluggable)[ Packagist](https://packagist.org/packages/noccylabs/pluggable)[ RSS](/packages/noccylabs-pluggable/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (15)Used By (0)

noccylabs/pluggable
===================

[](#noccylabspluggable)

*Note: This readme applies to the 0.2.x branch of Pluggable*

Pluggable is a plugin manager for PHP. It provides a bare, controllable framework for loading and unloading code stubs on demand directly from the filesystem or even from .zip or .phar files.

Installing
----------

[](#installing)

```
$ composer require noccylabs/pluggable:0.2.x-dev

```

Using
-----

[](#using)

Create an instance of `NoccyLabs\Pluggable\Manager\PluginManager`, and add the backends from which you would like to load plugins:

```
    // Find and load all plugins from virtual filesystem $vfs
    $plug = new PluginManager();
    $plug
        ->addBackend(new VirtFsBackend($vfs, null))
        ->findPlugins(true)
        ;

```

### Backends

[](#backends)

You can add more than one backend. The order in which they are added is relevant if a plugin is found in more than one location. For example, imagine the following scenario:

- Plugin `plugin.foo` is shipped with `fooapp.phar` and loaded using a `StaticBackend`.
- The file `~/.fooapp/plugins/plugin.foo.zip` also contains `plugin.foo` and is loaded via the `VirtFsBackend`.

When the plugin `plugin.foo` is loaded, it will be loaded from the VirtFs backend, as it is the last one encountered. This allows you to include static plugins that can be upgraded externally.

```
    $plug
        ->addBackend(new StaticBackend(..))
        ->addBackend(new VirtFsBackend(..))

```

### DirectoryBackend

[](#directorybackend)

Directorybackend loads plugins from a set of directories. This backend can only load directly from source, and not via phar, zip or any other archive.

```
    new DirectoryBackend(array(
        "/foo/bar",
        "/foo/biz",
        "/var/bar"
    ));

```

### VirtFsBackend

[](#virtfsbackend)

VirtFsBackend loads plugins from a VirtFs filesystem consisting of mapped directories as well as zip-files. For the VirtFs backend to work, a protocol must be assigned to the VirtFs object (default name "plugins"), to allow the plugins to be accessed via the virtfs wrapper.

```
    new VirtFsBackend($vfs, "/");

```

### StaticBackend

[](#staticbackend)

The StaticBackend returns a list of static pre-initialized plugins. Use this for embedded plugins f.ex. when making phar executables.

```
    new StaticBackend(array(
        "my.plugin.id.one" => 'My\Plugin\Class',
        "my.plugin.id.two" => 'My\Other\Plugin\Class'
    ));

```

### Finding plugins

[](#finding-plugins)

Passing `true` to `PluginManager#findPlugins()` will load all plugins found by the backend:

```
    $plug->findPlugins(true);

```

The above is also functionally identical to:

```
    $plug->findPlugins( function ($plugin) {
        return true;
    });

```

To select the plugins to load, do something like:

```
    // Read plugins loaded since last time
    $plugins_to_load = file("plugins.lst", FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);

    // Use a custom callback to see if the plugin is in the list
    $plug->findPlugins( function ($plugin) use ($plugins_to_load) {
        $plugin_id = $plugin->getPluginId();
        return in_array($plugin_id, $plugins_to_load);
    });

    // Write the list back out
    $loaded_plugins = $plug->getLoadedPluginIds();
    file_put_contents("plugins.lst", join("\n", $loaded_plugins));

```

Writing plugins
---------------

[](#writing-plugins)

Plugins should implement `NoccyLabs\Pluggable\Plugin\PluginInterface` or extend `NoccyLabs\Pluggable\Plugin\Plugin`. If you choose to use the interface, it is your responsibility to respond to the `PluginInterface#onActivate()` as well as `PluginInterface#isActivated()` to reflect the state. If you extend the plugin you can instead override the `Plugin#load()` method and leave the gears and wrenches to Pluggable.

Plugins need to have a manifest (unless loaded with the `StaticBackend`) in any of the supported languages json, yaml or sdl. Note that yaml and sdl might require additional libraries be installed for the parsing to work.

```
| Language  | Filename                 | Requirements                |
|===========|==========================|=============================|
| Json      | `plugin.json`            | php5-json                   |
| Yaml      | `plugin.yml`             | php5-yaml or symfony/yaml   |
| Ini       | `plugin.ini`             |                             |

```

The file should define the following values:

- **id** - the plugin id, f.ex. foovendor.myplugin
- **ns** - the namespace of the plugins root directory (psr-4)
- **class** - the class to load from the specified ns
- **name** - the plugin name

### Interfaces

[](#interfaces)

By calling `PluginManager#addInterfaceLoader()`, callbacks can be created for plugins implementing specific interfaces or extending specific classes. Internally it uses `instanceof` to compare the instance against the requested name.

```
    class MyPlugin extends Plugin implements ICanAddInterface
    { ... }

    $plug->addInterfaceLoader("ICanAddInterface", function ($plugin) {
        $sum = $plugin->addNumbers(5, 4);
    });

```

Or use it to set containers etc:

```
    $plug->addInterfaceLoader($container_interface, function ($plugin) use ($container) {
        $plugin->setContainer($container);
    });

```

### Generic loaders

[](#generic-loaders)

Generic loaders are available as well:

```
    $plug->addLoader(function ($plugin) {
        // ...
    });

```

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

14

Last Release

4304d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1434055?v=4)[Christopher Vagnetoft](/maintainers/noccy80)[@noccy80](https://github.com/noccy80)

---

Top Contributors

[![noccy80](https://avatars.githubusercontent.com/u/1434055?v=4)](https://github.com/noccy80 "noccy80 (44 commits)")

### Embed Badge

![Health badge](/badges/noccylabs-pluggable/health.svg)

```
[![Health](https://phpackages.com/badges/noccylabs-pluggable/health.svg)](https://phpackages.com/packages/noccylabs-pluggable)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

96374.6k23](/packages/friendsoftypo3-content-blocks)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[flarum/core

Delightfully simple forum software.

211.3M1.9k](/packages/flarum-core)[netgen/layouts-core

Netgen Layouts enables you to build and manage complex web pages in a simpler way and with less coding. This is the core of Netgen Layouts, its heart and soul.

3689.4k10](/packages/netgen-layouts-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
