{"id":13462144,"url":"https://github.com/humbug/php-scoper","last_synced_at":"2026-03-02T13:14:29.430Z","repository":{"id":39864971,"uuid":"44384447","full_name":"humbug/php-scoper","owner":"humbug","description":"🔨 Prefixes all PHP namespaces in a file/directory to isolate the code bundled in PHARs.","archived":false,"fork":false,"pushed_at":"2026-02-23T21:25:11.000Z","size":4149,"stargazers_count":792,"open_issues_count":29,"forks_count":76,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-02-24T02:12:48.924Z","etag":null,"topics":["archive","command-line","phar","phar-prefixer","php","php-console"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/humbug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yaml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["theofidry"]}},"created_at":"2015-10-16T12:43:34.000Z","updated_at":"2026-02-23T21:25:14.000Z","dependencies_parsed_at":"2023-02-10T04:30:27.619Z","dependency_job_id":"4aa4c3a9-5273-4aec-944e-9ecb6416e69d","html_url":"https://github.com/humbug/php-scoper","commit_stats":{"total_commits":821,"total_committers":42,"mean_commits":"19.547619047619047","dds":0.5347137637028014,"last_synced_commit":"79b2b4e0fbc1d1ef6ae99c4e078137b42bd43d19"},"previous_names":[],"tags_count":73,"template":false,"template_full_name":null,"purl":"pkg:github/humbug/php-scoper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fphp-scoper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fphp-scoper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fphp-scoper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fphp-scoper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/humbug","download_url":"https://codeload.github.com/humbug/php-scoper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fphp-scoper/sbom","scorecard":{"id":473302,"data":{"date":"2025-08-11","repo":{"name":"github.com/humbug/php-scoper","commit":"bb4581d84a9d2b41d723a0e03c7c17638d8c07a3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.5,"checks":[{"name":"Maintained","score":3,"reason":"3 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":2,"reason":"Found 5/22 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: php-scoper.phar.asc: https://github.com/humbug/php-scoper/releases/tag/0.18.17","Info: signed release artifact: php-scoper.phar.asc: https://github.com/humbug/php-scoper/releases/tag/0.18.16","Info: signed release artifact: php-scoper.phar.asc: https://github.com/humbug/php-scoper/releases/tag/0.18.15","Info: signed release artifact: php-scoper.phar.asc: https://github.com/humbug/php-scoper/releases/tag/0.18.14","Info: signed release artifact: php-scoper.phar.asc: https://github.com/humbug/php-scoper/releases/tag/0.18.13","Warn: release artifact 0.18.17 does not have provenance: https://api.github.com/repos/humbug/php-scoper/releases/201304567","Warn: release artifact 0.18.16 does not have provenance: https://api.github.com/repos/humbug/php-scoper/releases/194307651","Warn: release artifact 0.18.15 does not have provenance: https://api.github.com/repos/humbug/php-scoper/releases/173056103","Warn: release artifact 0.18.14 does not have provenance: https://api.github.com/repos/humbug/php-scoper/releases/160719004","Warn: release artifact 0.18.13 does not have provenance: https://api.github.com/repos/humbug/php-scoper/releases/159883098"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is not required on branch 'main'","Info: status check found to merge onto on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T14:33:27.866Z","repository_id":39864971,"created_at":"2025-08-19T14:33:27.866Z","updated_at":"2025-08-19T14:33:27.866Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30003793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T12:19:43.414Z","status":"ssl_error","status_checked_at":"2026-03-02T12:19:02.215Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["archive","command-line","phar","phar-prefixer","php","php-console"],"created_at":"2024-07-31T12:00:40.013Z","updated_at":"2026-03-02T13:14:29.413Z","avatar_url":"https://github.com/humbug.png","language":"PHP","readme":"# PHP-Scoper\n\n[![Package version](https://img.shields.io/packagist/v/humbug/php-scoper.svg?style=flat-square)](https://packagist.org/packages/humbug/php-scoper)\n[![Build Status](https://github.com/humbug/php-scoper/workflows/Build/badge.svg)](https://github.com/humbug/php-scoper/actions)\n[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/humbug/php-scoper.svg?branch=main\u0026style=flat-square)](https://scrutinizer-ci.com/g/humbug/php-scoper/?branch=main)\n[![Code Coverage](https://scrutinizer-ci.com/g/humbug/php-scoper/badges/coverage.png?b=main)](https://scrutinizer-ci.com/g/humbug/php-scoper/?branch=main)\n[![Slack](https://img.shields.io/badge/slack-%23humbug-red.svg?style=flat-square)](https://symfony.com/slack-invite)\n[![License](https://img.shields.io/badge/license-MIT-red.svg?style=flat-square)](LICENSE)\n\nPHP-Scoper is a tool which essentially moves any body of code, including all\ndependencies such as vendor directories, to a new and distinct namespace.\n\n\n## Goal\n\nPHP-Scoper's goal is to make sure that all code for a project lies in a \ndistinct PHP namespace. This is necessary, for example, when building PHARs that:\n\n- Bundle their own vendor dependencies; and \n- Load/execute code from arbitrary PHP projects with similar dependencies\n\nWhen a package (of possibly different versions) exists, and is found in both a PHAR\nand the executed code, the one from the PHAR will be used. This means these\nPHARs run the risk of raising conflicts between their bundled vendors and the\nvendors of the project they are interacting with, leading to issues that are \npotentially very difficult to debug due to dissimilar or unsupported package versions.\n\n\n## Table of Contents\n\n- [Installation](docs/installation.md#installation)\n    - [Phive](docs/installation.md#phive)\n    - [Composer](docs/installation.md#composer)\n    - [Docker](docs/installation.md#docker)\n    - [GitHub](docs/installation.md#github)\n- [Usage](#usage)\n- [Configuration](docs/configuration.md#configuration)\n    - [Prefix](docs/configuration.md#prefix)\n    - [PHP Version](docs/configuration.md#php-version)\n    - [Output directory](docs/configuration.md#output-directory)\n    - [Finders and paths](docs/configuration.md#finders-and-paths)\n    - [Patchers](docs/configuration.md#patchers)\n    - [Excluded files](docs/configuration.md#excluded-files)\n    - [Excluded Symbols](docs/configuration.md#excluded-symbols)\n    - [Excluding namespaces](docs/configuration.md#excluding-namespaces)\n    - [Exposed Symbols](docs/configuration.md#exposed-symbols)\n        - [Exposing namespaces](docs/configuration.md#exposing-namespaces)\n        - [Exposing classes](docs/configuration.md#exposing-classes)\n        - [Exposing functions](docs/configuration.md#exposing-functions)\n        - [Exposing constants](docs/configuration.md#exposing-constants)\n- [Building a scoped PHAR](#building-a-scoped-phar)\n    - [With Box](#with-box)\n    - [Without Box](#without-box)\n        - [Step 1: Configure build location and prep vendors](#step-1-configure-build-location-and-prep-vendors)\n        - [Step 2: Run PHP-Scoper](#step-2-run-php-scoper)\n- [Recommendations](#recommendations)\n- [Debugging](#debugging)\n- [Further Reading](docs/further-reading.md#further-reading)\n    - [How to deal with unknown third-party symbols](docs/further-reading.md#how-to-deal-with-unknown-third-party-symbols)\n    - [Autoload aliases](docs/further-reading.md#autoload-aliases)\n        - [Class aliases](docs/further-reading.md#class-aliases)\n        - [Function aliases](docs/further-reading.md#function-aliases)\n    - [Laravel support](docs/further-reading.md#laravel-support)\n    - [Symfony support](docs/further-reading.md#symfony-support)\n    - [Wordpress support](docs/further-reading.md#wordpress-support)\n- [Limitations](docs/limitations.md#limitations)\n    - [Dynamic symbols](docs/limitations.md#dynamic-symbols)\n    - [Date symbols](docs/limitations.md#date-symbols)\n    - [Heredoc values](docs/limitations.md#heredoc-values)\n    - [Callables](docs/limitations.md#callables)\n    - [String values](docs/limitations.md#string-values)\n    - [Native functions and constants shadowing](docs/limitations.md#native-functions-and-constants-shadowing)\n    - [Composer Autoloader](docs/limitations.md#composer-autoloader)\n    - [Composer Plugins](docs/limitations.md#composer-plugins)\n    - [PSR-0 Partial support](docs/limitations.md#psr-0-partial-support)\n    - [Files autoloading](docs/limitations.md#files-autoloading)\n    - [Exposing/Excluding traits](docs/limitations.md#exposingexcluding-traits)\n    - [Exposing/Excluding enums](docs/limitations.md#exposingexcluding-enums)\n- [Contributing](#contributing)\n- [Credits](#credits)\n\n\n## Usage\n\n```bash\nphp-scoper add-prefix\n```\n\nThis will prefix all relevant namespaces in code found in the current working\ndirectory. The prefixed files will be accessible in a `build` folder. You can\nthen use the prefixed code to build your PHAR.\n\n**Warning**: After prefixing the files, if you are relying on Composer\nfor the auto-loading, dumping the autoloader again is required.\n\nFor a more concrete example, you can take a look at PHP-Scoper's build\nstep in [Makefile](Makefile), especially if you are using Composer as\nthere are steps both before and after running PHP-Scoper to consider.\n\nRefer to TBD for an in-depth look at scoping and building a PHAR taken from\nPHP-Scoper's makefile.\n\n\n## Building a Scoped PHAR\n\n### With Box\n\nIf you are using [Box][box] to build your PHAR, you can use the existing\n[PHP-Scoper integration][php-scoper-integration]. Box will take care of\nmost of the things for you so you should only have to adjust the PHP-Scoper\nconfiguration to your needs.\n\n\n### Without Box\n\n#### Step 1: Configure build location and prep vendors\n\nAssuming you do not need any development dependencies, run:\n\n```bash\ncomposer install --no-dev --prefer-dist\n```\n\nThis will allow you to save time in the scoping process by not\nprocessing unnecessary files.\n\n\n#### Step 2: Run PHP-Scoper\n\nPHP-Scoper copies code to a new location during prefixing, leaving your original\ncode untouched. The default location is `./build`. You can change the default\nlocation using the `--output-dir` option. By default, it also generates a random\nprefix string. You can set a specific prefix string using the `--prefix` option.\nIf automating builds, you can set the `--force` option to overwrite any code\nexisting in the output directory without being asked to confirm.\n\nOnto the basic command assuming default options from your project's root\ndirectory:\n\n```bash\nbin/php-scoper add-prefix\n```\n\nAs there are no path arguments, the current working directory will be scoped to\n`./build` in its entirety. Of course, actual prefixing is limited to PHP files,\nor PHP scripts. Other files are copied unchanged, though we also need to scope\ncertain Composer related files.\n\nSpeaking of scoping Composer related files... The next step is to dump the\nComposer autoloader if we depend on it, so everything works as expected:\n\n```bash\ncomposer dump-autoload --working-dir build --classmap-authoritative\n```\n\n\n## Recommendations\n\nThere is 3 things to manage when dealing with isolated PHARs:\n\n- The PHAR format: there is some incompatibilities such as `realpath()` which\n  will no longer work for the files within the PHAR since the paths are not\n  virtual.\n- Isolating the code: due to the dynamic nature of PHP, isolating your\n  dependencies will never be a trivial task and as a result you should have\n  some end-to-end test to ensure your isolated code is working properly. You\n  will also likely need to configure the excluded and exposed symbols or\n  [patchers][patchers].\n- The dependencies: which dependencies are you shipping? Fine controlled ones \n  managed with a `composer.lock` or you always ship your application with\n  up-to-date dependencies? The latter, although more ideal, will by design\n  result in more brittleness as any new release from a dependency may break\n  something (although the changes may be SemVer compliant, we are dealing with\n  PHARs and isolated code)\n\nAs a result, you _should_ have end-to-end tests for your (at the minimum) your \nreleased PHAR.\n\nSince dealing with the 3 issues mentioned above at once can be tedious, it is\nhighly recommended having several tests for each step.\n\nFor example, you can have a test for both your non-isolated PHAR and your \nisolated PHAR, this way you will know which step is causing an issue. If the \nisolated PHAR is not working, you can try to test the isolated code directly \noutside the PHAR to make sure the scoping process is not the issue.\n\nTo check if the isolated code is working correctly, you have a number of solutions:\n\n- When using PHP-Scoper directly, by default PHP-Scoper dump the files in a \n  `build` directory. Do not forget that\n  [you need to dump the Composer autoloader for the isolated code to work!](#step-2-run-php-scoper).\n- When using [Box][box], you can use its `--debug` option from the `compile` \n  command in order to have the code shipped in the PHAR dumped in the `.box` \n  directory.\n- When using a PHAR (created by [Box][box] or any other PHAR building tool), \n  you can use the [`Phar::extractTo()`][phar-extract-to] method.\n\n\n## Debugging\n\nHaving a good breakdown like described in [Recommendations](#recommendations) will help\nto know where the issue is coming from. However, if you have a doubt or you are fiddling\nwith patchers and want to check the result for a specific file without doing the whole\nscoping process, you can always check the result for that single individual file:\n\n```shell\nphp-scoper inspect path/to/my-file.php\n```\n\n\n## Contributing\n\n[Contribution Guide](CONTRIBUTING.md)\n\n\n## Credits\n\nProject originally created by: [Bernhard Schussek] ([@webmozart]) which has\nnow been moved under the\n[Humbug umbrella][humbug].\n\n\n[@webmozart]: https://twitter.com/webmozart\n[Bernhard Schussek]: https://webmozart.io/\n[box]: https://github.com/box-project/box\n[humbug]: https://github.com/humbug\n[patchers]: docs/configuration.md#patchers\n[php-scoper-integration]: https://github.com/box-project/box/blob/main/doc/code-isolation.md#phar-code-isolation\n[phar-extract-to]: https://secure.php.net/manual/en/phar.extractto.php\n","funding_links":["https://github.com/sponsors/theofidry"],"categories":["Uncategorized","PHP","类库"],"sub_categories":["Uncategorized","未归类"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumbug%2Fphp-scoper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhumbug%2Fphp-scoper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumbug%2Fphp-scoper/lists"}