Most of the time, we use Composer to install tools developed in PHP, like any other library or framework. While this is the simplest method, it has a significant drawback in that you will automatically inherit the dependencies of these tools.
This drawback can quickly become a blocking problem if you require a multitude of tools since the risk of conflicts between dependencies will be higher. The problem is the same if you install these tools in your projects or your
HOMEdirectory (at the global level).
To continue using Composer without this constraint, you could distribute the tool not as a library, but as a binary: a PHAR. But merely adding the binary to your current project next to the other files will not allow you to distribute it without your dependencies.
You will need two separate projects: a “source” project to work on the tool and a “binary” project to distribute it to your users without the need for additional dependencies.
Here is an illustration of the workflow under this kind of architecture.
To make things a bit more straightforward, I’ve created a Docker image to use it without installing anything else than Docker.
Let’s create a new Symfony project.
Not everything is necessary when developing a CLI application. Even though Symfony skeleton is already extremely lightweight, we will simplify the configuration of our new project.
Your project is now (almost) ready to be compiled.
Before going any further, it is crucial to know that the execution context within a PHAR is different from the one we are used to handling. A PHAR is a read-only archive where it is not possible to write any file. Therefore, it is mandatory to follow the steps described in the humbug/box documentation for Symfony:
- remove the assets installation in the
- put the application in prod mode with the
composer dump-env prodcommand
- refresh and warm the application cache before compiling
To configure the compilation, you have to write a JSON file which is far from being verbose. The humbug/box documentation explains the available configuration parameters. I will let you take a look.
You can now compile your project! 🚀
As it is necessary to chain several commands, I usually fill them in a
Makefile that will be used from my local environment and in my CI/CD processes.
Next time we will see how to automate the generation and distribution.
Thanks for reading!