Composer revolutionized package management in the PHP world and while this has been one of the most important developments in PHP we’re not quite there yet.
After pulling in composer packages we are still tasked with wiring them up with our application. Some frameworks simplify this process by defining a standard format (e.g. module or bundle) and enabling the functionality is as trivial as adding it to the list of modules.
However, this has caused for packages to start creating bridges which wire up their package with popular frameworks. Downside of this is significantly more work for the package maintainer and there might not be a bridge for the framework you use.
To solve this, Puli came up with the idea to implement the concept of discovery in our applications to standardize our approach in integrating packages.
[Psst, my colleague Nico wrote something about Service Discovery]
Puli allows packages to provide an object or resources (files) based on a certain tag. Let’s say you need an EventManager in your application, you can start off by choosing an existing standardized EventManager interface (e.g.
Foo\Bar\EventManagerInterface). Next thing you do is pull in an EventManager package (using composer) that implements this interface (e.g.
acme/event-manager) which is configured to provide an EventManager for the tag
Foo\Bar\EventManagerInterface using a
puli.json file. Now all you need to do to use this package is ask Puli for anything that provides for the tag
Foo\Bar\EventManagerInterface and Puli will provide an instance of an EventManager from the
enrise/event-manager package. The same can be done for HttpClient (Guzzle, React, etc.) or loggers.
The great thing about this is that these packages are easily interchangeable as long as they stay compatible with the interface. All you need to do is composer require a different package and Puli does the rest.
Another example is translations, say you’re running a CMS and that CMS uses Puli to discover translation files. Adding another translation will be as simple as ‘composer require foo-cms/translation-nl’, this package can provide for the ‘foo-cms/translation’ tag and when the CMS asks Puli for all the translations, Puli happily returns a list of translation files which the package provides for that tag.
There’s more to Puli than explained above, for more information and some code samples you can checkout their documentation or watch a talk by the maintainer of Puli.
Puli is, at the time of writing, still in BETA and not widely adopted but it’s very promising and the maintainer is actively working on getting Puli adopted by all major frameworks. We, at team Sashimi, are keeping an eye on this project and hope this project will soon become part of our standard toolbox.