Ship scoped production dependencies installed with composer
Opened this issue · 0 comments
This plugin is currently using composer only to install development dependencies, which should present no problem.
If at some point we want to install production dependencies and ship them with the plugin, we'll have to explore some tool like https://github.com/humbug/php-scoper, to avoid collisions with other dependencies from other plugins.
TL;DR
Composer is the de-facto official package manager for PHP.
On top of allowing the installation of production and development dependencies, it also provides autoloading capabilities for all the symbols in those packages.
Autoloading is a mechanism that other programming languages resolve differently. In PHP, you have to explicitly require the file containing a class in order to be able to use that class somewhere else.
// src/Hypothesis/MyClass.php
class MyClass
{
// ...
}
---
// src/Hypothesis/OtherClass.php
use MyClass; // This is similar to Java imports, but does not bring the other class into this file's scope
class OtherClass
{
public function foo()
{
// This will throw unless we do `require __DIR__ . '/MyClass.php';` somewhere before this line
new MyClass();
}
}
Since this can become cumbersome as a codebase grows, as you need both the use
statement and also the explicit require
of the file, PHP provides a function that gets automatically invoked when an unknown class is used, to give you a last opportunity to require it before failing.
Composer builds some utilities on top of that, which allow package maintainers to provide some config that will make class files to be properly autoloaded, without forcing applications to know the dependency's file structure.
It also lets applications themselves to take advantage of this mechanism.
With this explained, there's one problem if you try to make use of this in a WordPress plugin. This is that the autoloading triggers only if the symbol/class does not exist in memory, but if some other plugin has already required the same class but from a different version of the plugin, your plugin will end-up using that same version and potentially fail if there are incompatibilities.
That's where PHP-Scoper might make sense, as it allows to "rename" the classes for all the dependencies you ship, ensuring there won't be name collisions if other plugins, or WordPress itself, are also using composer to install the same dependency.
This problem does not usually occur when an app is fully managed with composer, as you end up with a flat dependency tree, but WordPress and its plugin system predates composer.