When bundling the code in a PHAR, it is equivalent to compacting all the code in a single file. However unlike in a compiled language, the code does not change. Thus, when the PHAR loads external code, can lead to dependency conflicts.
To illustrate that issue with an example: we are building a console application myapp.phar which relies on the library
Symfony YAML 2.8.0 which execute a given PHP script.
# Usage of the application we are building
myapp.phar myscript.php
For the sake of the example, myapp.phar is using Composer and loads the YAML component right away when starting, i.e.
when running myapp.phar, the class Symfony\Yaml\Yaml from the PHAR is going to be loaded. Now what myapp.phar
is actually going to do is scan the whole file given, and do some reflection work on each classes found. I.e. for each
class $class found, it will do new \ReflectionClass($class).
Now if myscript.php is using the Symfony YAML 4.0.0 component with some new features added in 4.0.0 that are
non-existent in 2.8.0, when doing new \ReflectionClass('Symfony\Yaml\Yaml'), the class Symfony\Yaml\Yaml will be
loaded (yes, doing reflection on a class loads it!). BUT, it turns out the class Symfony\Yaml\Yaml is already
loaded: not the 4.0.0 from myscript.php but the one from the PHAR (2.8.0). So any information you will get will
be from the wrong class!
Is this really an issue? The answer is it depends. Here as a few real life example where this is an issue:
Box provides an integration with PHP-Scoper. To use it, enable the KevinGH\Box\Compactor\PhpScoper
compactor.
If you need an extra configuration for PHP-Scoper, you can create a scoper.inc.php file as
per the documentation. The only difference is that you can ignore the finders setting as the
files to scope are already collected by Box.
And that's it!
Warning: keep in mind however that scoping is a very brittle process due to the nature of PHP. As such you will likely need some adjustments in your code or the configuration.
As mentioned above, unless you have a very boring and predictable code (which is a good thing!), due to how dynamic PHP is, scoping will almost guaranteed never work on the first and will require adjustments. To help with the process, there is two recommendations:
--debug option in the compile command. It dumps the code added to the PHAR in a .box-dump
directory. This allows you to more easily inspect, alter and test the code shipped in the PHAR. This way, you can
make sure the code shipped is working before worrying about whether that code is going to work inside a PHAR.process command on a specific file to check the result and the effects of the configuration on itยซ Optimize your PHAR โข Docker support ยป
How can I help you explore Laravel packages today?