- Notifications
You must be signed in to change notification settings - Fork76
🔨 Prefixes all PHP namespaces in a file/directory to isolate the code bundled in PHARs.
License
humbug/php-scoper
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
PHP-Scoper is a tool which essentially moves any body of code, including alldependencies such as vendor directories, to a new and distinct namespace.
PHP-Scoper's goal is to make sure that all code for a project lies in adistinct PHP namespace. This is necessary, for example, when building PHARs that:
- Bundle their own vendor dependencies; and
- Load/execute code from arbitrary PHP projects with similar dependencies
When a package (of possibly different versions) exists, and is found in both a PHARand the executed code, the one from the PHAR will be used. This means thesePHARs run the risk of raising conflicts between their bundled vendors and thevendors of the project they are interacting with, leading to issues that arepotentially very difficult to debug due to dissimilar or unsupported package versions.
- Installation
- Usage
- Configuration
- Building a scoped PHAR
- Recommendations
- Debugging
- Further Reading
- Limitations
- Contributing
- Credits
php-scoper add-prefix
This will prefix all relevant namespaces in code found in the current workingdirectory. The prefixed files will be accessible in abuild
folder. You canthen use the prefixed code to build your PHAR.
Warning: After prefixing the files, if you are relying on Composerfor the auto-loading, dumping the autoloader again is required.
For a more concrete example, you can take a look at PHP-Scoper's buildstep inMakefile, especially if you are using Composer asthere are steps both before and after running PHP-Scoper to consider.
Refer to TBD for an in-depth look at scoping and building a PHAR taken fromPHP-Scoper's makefile.
If you are usingBox to build your PHAR, you can use the existingPHP-Scoper integration. Box will take care ofmost of the things for you so you should only have to adjust the PHP-Scoperconfiguration to your needs.
Assuming you do not need any development dependencies, run:
composer install --no-dev --prefer-dist
This will allow you to save time in the scoping process by notprocessing unnecessary files.
PHP-Scoper copies code to a new location during prefixing, leaving your originalcode untouched. The default location is./build
. You can change the defaultlocation using the--output-dir
option. By default, it also generates a randomprefix string. You can set a specific prefix string using the--prefix
option.If automating builds, you can set the--force
option to overwrite any codeexisting in the output directory without being asked to confirm.
Onto the basic command assuming default options from your project's rootdirectory:
bin/php-scoper add-prefix
As there are no path arguments, the current working directory will be scoped to./build
in its entirety. Of course, actual prefixing is limited to PHP files,or PHP scripts. Other files are copied unchanged, though we also need to scopecertain Composer related files.
Speaking of scoping Composer related files... The next step is to dump theComposer autoloader if we depend on it, so everything works as expected:
composer dump-autoload --working-dir build --classmap-authoritative
There is 3 things to manage when dealing with isolated PHARs:
- The PHAR format: there is some incompatibilities such as
realpath()
whichwill no longer work for the files within the PHAR since the paths are notvirtual. - Isolating the code: due to the dynamic nature of PHP, isolating yourdependencies will never be a trivial task and as a result you should havesome end-to-end test to ensure your isolated code is working properly. Youwill also likely need to configure the excluded and exposed symbols orpatchers.
- The dependencies: which dependencies are you shipping? Fine controlled onesmanaged with a
composer.lock
or you always ship your application withup-to-date dependencies? The latter, although more ideal, will by designresult in more brittleness as any new release from a dependency may breaksomething (although the changes may be SemVer compliant, we are dealing withPHARs and isolated code)
As a result, youshould have end-to-end tests for your (at the minimum) yourreleased PHAR.
Since dealing with the 3 issues mentioned above at once can be tedious, it ishighly recommended having several tests for each step.
For example, you can have a test for both your non-isolated PHAR and yourisolated PHAR, this way you will know which step is causing an issue. If theisolated PHAR is not working, you can try to test the isolated code directlyoutside the PHAR to make sure the scoping process is not the issue.
To check if the isolated code is working correctly, you have a number of solutions:
- When using PHP-Scoper directly, by default PHP-Scoper dump the files in a
build
directory. Do not forget thatyou need to dump the Composer autoloader for the isolated code to work!. - When usingBox, you can use its
--debug
option from thecompile
command in order to have the code shipped in the PHAR dumped in the.box
directory. - When using a PHAR (created byBox or any other PHAR building tool),you can use the
Phar::extractTo()
method.
Having a good breakdown like described inRecommendations will helpto know where the issue is coming from. However, if you have a doubt or you are fiddlingwith patchers and want to check the result for a specific file without doing the wholescoping process, you can always check the result for that single individual file:
php-scoper inspect path/to/my-file.php
Project originally created by:Bernhard Schussek (@webmozart) which hasnow been moved under theHumbug umbrella.
About
🔨 Prefixes all PHP namespaces in a file/directory to isolate the code bundled in PHARs.