humbug / php-scoper
Prefixes all PHP namespaces in a file or directory.
Requires
- php: ^8.2
- fidry/console: ^0.6.10
- fidry/filesystem: ^1.1
- jetbrains/phpstorm-stubs: ^2026.2
- nikic/php-parser: ^5.0
- symfony/console: ^6.4 || ^7.4
- symfony/filesystem: ^6.4 || ^7.4
- symfony/finder: ^6.4 || ^7.4
- symfony/polyfill-iconv: ^1.33
- symfony/polyfill-mbstring: ^1.33
- symfony/var-dumper: ^7.1
- thecodingmachine/safe: ^3.0
Requires (Dev)
- bamarni/composer-bin-plugin: ^1.1
- ergebnis/composer-normalize: ^2.28
- fidry/makefile: ^1.0
- humbug/box: ^4.6.2
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^10.0 || ^11.0
- symfony/yaml: ^6.4 || ^7.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 0.18.20
- 0.18.19
- 0.18.18
- 0.18.17
- 0.18.16
- 0.18.15
- 0.18.14
- 0.18.13
- 0.18.12
- 0.18.11
- 0.18.10
- 0.18.9
- 0.18.8
- 0.18.7
- 0.18.6
- 0.18.5
- 0.18.4
- 0.18.3
- 0.18.2
- 0.18.1
- 0.18.0
- 0.18.0-rc.0
- 0.17.7
- 0.17.6
- 0.17.5
- 0.17.4
- 0.17.3
- 0.17.2
- 0.17.1
- 0.17.0
- 0.16.2
- 0.16.1
- 0.16.0
- 0.15.0
- 0.14.1
- 0.14.0
- 0.13.10
- 0.13.9
- 0.13.8
- 0.13.7
- 0.13.6
- 0.13.5
- 0.13.4
- 0.13.3
- 0.13.2
- 0.13.1
- 0.13.0
- 0.12.4
- 0.12.3
- 0.12.2
- 0.12.1
- 0.12.0
- 0.11.4
- 0.11.3
- 0.11.2
- 0.11.1
- 0.11.0
- 0.10.3
- 0.10.2
- 0.10.1
- 0.10.0
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.1
- 0.8.0
- 0.7.0
- 0.6.1
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
This package is auto-updated.
Last update: 2026-10-08 22:15:42 UTC
README
PHP-Scoper moves any body of code, including all its dependencies such as vendor directories, to a new and distinct namespace.
Goal
PHP-Scoper's goal is to ensure that all the code of a project lies in a distinct PHP namespace. This is necessary, for example, when building PHARs that:
- bundle their own vendor dependencies; and
- load or execute code from arbitrary PHP projects with similar dependencies.
When a package, possibly in different versions, is found both in a PHAR and in the executed code, the one from the PHAR is used. Such PHARs therefore risk conflicts between their bundled dependencies and those of the project they interact with. Due to mismatched or unsupported package versions, the resulting issues can be very difficult to debug.
Table of Contents
- Installation
- Usage
- Configuration
- Building a scoped PHAR
- Recommendations
- Debugging
- Further Reading
- Limitations
- Architecture
- Contributing
- Credits
Usage
php-scoper add-prefix
This prefixes all the relevant namespaces of the code found in the current
working directory. The prefixed files are written to a build directory, and
can then be used to build your PHAR.
Warning: if you rely on Composer for autoloading, you must dump the autoloader again after prefixing the files.
For a more concrete example, refer to PHP-Scoper's build step in the Makefile. This is particularly relevant if you use Composer, as there are steps to consider both before and after running PHP-Scoper.
Building a Scoped PHAR
With Box
If you use Box to build your PHAR, you can rely on its PHP-Scoper integration. Box takes care of most of the process, so you should only need to adjust the PHP-Scoper configuration to your needs.
Without Box
Step 1: Configure build location and prep vendors
Assuming you do not need any development dependencies, run:
composer install --no-dev --prefer-dist
This saves time during scoping, as unnecessary files are not processed.
Step 2: Run PHP-Scoper
PHP-Scoper copies the code to a new location during prefixing, leaving your
original code untouched. The default location is ./build, which can be
changed with the --output-dir option. By default, PHP-Scoper also generates a
random prefix, which can be set explicitly with the --prefix option. When
automating builds, use the --force option to overwrite any existing code in
the output directory without a confirmation prompt.
The basic command, with the default options, run from your project's root directory is:
bin/php-scoper add-prefix
As no path argument is given, the entire current working directory is scoped
to ./build. Prefixing is limited to PHP files and scripts; other files are
copied unchanged, with the exception of certain Composer-related files, which
are also scoped.
If you depend on the Composer autoloader, the next step is to dump it so that everything works as expected:
composer dump-autoload --working-dir build --classmap-authoritative
Recommendations
There are three aspects to manage when dealing with isolated PHARs:
- The PHAR format: some functions are incompatible with it, such as
realpath(), which no longer works for files within the PHAR as their paths are virtual. - Code isolation: due to the dynamic nature of PHP, isolating your dependencies is never trivial. You should therefore have end-to-end tests to ensure your isolated code works correctly. You will also likely need to configure the excluded and exposed symbols, or patchers.
- The dependencies: which dependencies do you ship? Tightly controlled ones,
managed with a
composer.lock, or always the latest versions? The latter, although preferable, is by design more brittle, as any new release of a dependency may break something. Even if the changes are SemVer compliant, the code is isolated and shipped in a PHAR.
Consequently, you should have end-to-end tests for, at a minimum, your released PHAR.
As addressing all three aspects at once can be tedious, it is highly recommended to have separate tests for each step.
For example, you can test both your non-isolated PHAR and your isolated PHAR to identify which step causes an issue. If the isolated PHAR does not work, you can test the isolated code directly, outside the PHAR, to rule out the scoping process.
There are several ways to check whether the isolated code works correctly:
- When using PHP-Scoper directly, the files are dumped in a
builddirectory by default. Remember that the Composer autoloader must be dumped for the isolated code to work. - When using Box, the
--debugoption of thecompilecommand dumps the code shipped in the PHAR in the.boxdirectory. - When using a PHAR, whether built with Box or another tool, you can use
the
Phar::extractTo()method.
Debugging
A breakdown such as the one described in Recommendations helps identify where an issue originates. However, if you are unsure or are adjusting patchers, you can check the result for a single file without running the whole scoping process:
php-scoper inspect path/to/my-file.php
Contributing
Credits
The project was originally created by Bernhard Schussek (@webmozart) and has since moved under the Humbug umbrella.