-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started
This guide takes you from an empty tools directory to a report you can explain to a developer or a technical manager. PHP Upgrade Preflight analyzes an upgrade; it does not perform one.
Current release line: v0.3.x. The latest published release recorded by the repository is v0.3.3. It produces canonical JSON schema 0.8 and requires PHP
^8.0on the machine that runs the analyzer.
You give the analyzer an existing Composer project, a desired package or PHP target, and optional target-platform facts. It copies the project metadata to temporary workspaces, asks Composer what can resolve, scans selected PHP source, and writes an evidence-backed report without changing the target tree.
The report is planning input. It is not proof that the application boots, passes tests, is secure, or is ready to deploy.
Check the analyzer host:
php --version
composer --versionphp --version
composer --versionThe analyzer host needs PHP 8.0 or newer and Composer 2. A target project may use an older PHP version because the analyzer can be installed in a separate tools directory.
These are different questions:
| Question | Example | Answered by |
|---|---|---|
| Can the analyzer package run here? | Can the Laravel adapter be installed into this Laravel 10 application? | Host PHP and host Laravel package constraints |
| What deployment platform should Composer model? | Can this project resolve for PHP 8.3 with ext-curl? |
--target-php, extension assumptions, or a platform profile |
| Will the upgraded application work? | Does checkout still complete after the upgrade? | Your own tests and runtime validation, not this analyzer |
The Laravel adapter is project-locally installable with Laravel 8–13, subject to Laravel's own PHP floor. Laravel 7 should be analyzed from an external PHP 8 tools directory. An external analyzer can model a newer PHP target even if its own host uses another supported PHP 8 version.
Use this layout when the target runs PHP 7, has tight dependency constraints, or must remain byte-for-byte unchanged.
Linux or macOS:
mkdir -p "$HOME/php-upgrade-tools"
cd "$HOME/php-upgrade-tools"
composer require php-upgrade-preflight/cli:^0.3 php-upgrade-preflight/laravel:^0.3
vendor/bin/upgrade-intel --helpWindows PowerShell:
New-Item -ItemType Directory -Force "$env:USERPROFILE\php-upgrade-tools" | Out-Null
Set-Location "$env:USERPROFILE\php-upgrade-tools"
composer require php-upgrade-preflight/cli:^0.3 php-upgrade-preflight/laravel:^0.3
vendor\bin\upgrade-intel.bat --helpInstall every framework adapter beside the CLI. Nothing has to be installed into the target project.
Use this only when the application's dependency graph accepts the analyzer packages and changing composer.json and composer.lock during installation is acceptable.
composer require --dev php-upgrade-preflight/cli:^0.3 php-upgrade-preflight/laravel:^0.3
vendor/bin/upgrade-intel --helpcomposer require --dev php-upgrade-preflight/cli:^0.3 php-upgrade-preflight/laravel:^0.3
vendor\bin\upgrade-intel.bat --helpProject-local installation changes the project before analysis. The analyzer's read-only promise begins after installation; it cannot make the composer require step immutable.
The published packages are ordinary Composer packages. There is no supported PHAR or versioned runtime container image. The repository Docker files are development and verification tooling.
The analyzed path must contain a valid composer.json. A composer.lock provides much stronger current-state evidence.
Create the report directory outside the project. The parent directory must already exist.
mkdir -p /work/upgrade-reportsNew-Item -ItemType Directory -Force C:\work\upgrade-reports | Out-NullDo not write the report under the analyzed project. The command rejects that destination to preserve the read-only input contract.
In a terminal, start the interactive wizard:
vendor/bin/upgrade-intel wizardvendor\bin\upgrade-intel.bat wizardIt shows available project evidence, asks whether to model PHP, packages, or both, and requires an explicit Composer analysis mode. For package targets, the default reads only composer.json. You may instead request a local-cache-only metadata check or configured project repositories; the latter can use network access and credentials. A package that is explicitly absent or has no matching discovered version must be corrected. Offline, timeout, and metadata failures are shown as unverified rather than falsely labeled nonexistent.
The default report format is readable Markdown. The wizard always keeps the report on stdout and can also save the same bytes to a validated path outside the project. It shows the equivalent flag-based analyze command before confirmation. Use that explicit command in CI or any redirected/non-TTY session. Enter cancel, quit, or q to stop before analysis.
Linux or macOS:
vendor/bin/upgrade-intel analyze \
--path=/work/legacy-app \
--from-php=7.4 \
--target-php=8.2 \
--format=json \
--output=/work/upgrade-reports/php-82.jsonWindows PowerShell:
vendor\bin\upgrade-intel.bat analyze `
--path=C:\work\legacy-app `
--from-php=7.4 `
--target-php=8.2 `
--format=json `
--output=C:\work\upgrade-reports\php-82.jsonAll standalone CLI values use --name=value. --path C:\work\legacy-app is not accepted. Only flags such as --debug omit =value.
The Laravel adapter must be installed beside the CLI.
vendor/bin/upgrade-intel analyze \
--path=/work/legacy-app \
--from-php=8.1 \
--target=laravel/framework:^11.0 \
--target-php=8.2 \
--framework=laravel \
--format=json \
--output=/work/upgrade-reports/laravel-11.jsonvendor\bin\upgrade-intel.bat analyze `
--path=C:\work\legacy-app `
--from-php=8.1 `
--target=laravel/framework:^11.0 `
--target-php=8.2 `
--framework=laravel `
--format=json `
--output=C:\work\upgrade-reports\laravel-11.jsonWithout --framework, installed adapters may activate by detecting the project. Supplying --framework=laravel is clearer in automation and fails early with exit code 2 if the adapter is missing.
The shell exit code answers, “Did the command produce a valid report?” It does not answer, “Can the upgrade resolve?”
| Exit code | Meaning |
|---|---|
0 |
Help was shown or a complete canonical report was produced |
1 |
An internal or operational failure prevented report production |
2 |
The invocation, target, path, format, framework, profile, or destination was invalid |
130 |
The interactive wizard was cancelled before analysis |
A solver-blocked upgrade is successful analysis output, so it returns 0.
The report field resolution.status answers the direct final-target Composer question:
resolution.status |
Meaning |
|---|---|
feasible |
A determining final-target scenario succeeded without package changes |
feasible_with_changes |
A determining final-target scenario succeeded with candidate lock changes |
blocked |
Reproducible Composer blockers prevent the requested final target |
unknown |
Operational or evidence limits prevented a reliable conclusion |
Example shell logic for JSON output:
vendor/bin/upgrade-intel analyze --path=/work/app --target-php=8.2 --format=json --output=/work/reports/app.json
command_code=$?
if [ "$command_code" -ne 0 ]; then
echo "No valid report was produced; command exit code: $command_code" >&2
exit "$command_code"
fi
jq -r '.resolution.status' /work/reports/app.jsonvendor\bin\upgrade-intel.bat analyze --path=C:\work\app --target-php=8.2 --format=json --output=C:\work\reports\app.json
$commandCode = $LASTEXITCODE
if ($commandCode -ne 0) {
throw "No valid report was produced; command exit code: $commandCode"
}
$report = Get-Content -Raw C:\work\reports\app.json | ConvertFrom-Json
$report.resolution.statusFor Laravel, also read transition.framework_guidance[].status and staged_resolution.execution_state plus staged_resolution.status. Guidance coverage, direct feasibility, and adjacent-stage feasibility are independent and may legitimately disagree.
The repository demo models Laravel 10→13 using local path repositories. It does not contact Packagist and does not modify its target.
From a tools directory on Linux or macOS:
COMPOSER_ROOT_VERSION=1.0.0 vendor/bin/upgrade-intel analyze \
--path=/path/to/php-upgrade-preflight/examples/five-minute-demo/target \
--from-php=8.1 \
--target=laravel/framework:^13.0 \
--target-php=8.3 \
--without-extension=ext-preflight-stage \
--composer-mode=restricted \
--framework=laravel \
--format=json \
--output=/tmp/php-upgrade-preflight-demo.jsonPowerShell:
$env:COMPOSER_ROOT_VERSION = '1.0.0'
vendor\bin\upgrade-intel.bat analyze `
--path=C:\src\php-upgrade-preflight\examples\five-minute-demo\target `
--from-php=8.1 `
--target=laravel/framework:^13.0 `
--target-php=8.3 `
--without-extension=ext-preflight-stage `
--composer-mode=restricted `
--framework=laravel `
--format=json `
--output="$env:TEMP\php-upgrade-preflight-demo.json"
Remove-Item Env:COMPOSER_ROOT_VERSIONExpected interpretation:
- process exit code:
0, because a valid report was written; - direct
resolution.status:blocked; - aggregate
staged_resolution.status:blocked; - 10→11 and 11→12 stages:
feasible_with_changes; - 12→13 stage:
blockedby the deliberately absentext-preflight-stage; - Laravel guidance: supported for all three hops.
This is the clearest example of why an exit code is not an upgrade verdict.
Use JSON for automation, storage, comparisons, and evidence traversal:
--format=json --output=/work/reports/app.jsonUse Markdown for a review meeting or ticket attachment:
--format=markdown --output=/work/reports/app.mdJSON is canonical. Markdown is a human-readable projection of the same report, not a second analysis.
PHP itself can print the direct status when jq is unavailable:
php -r '$r=json_decode(file_get_contents($argv[1]), true, 512, JSON_THROW_ON_ERROR); echo $r["resolution"]["status"], PHP_EOL;' /work/reports/app.jsonPowerShell has a built-in JSON reader:
$report = Get-Content -Raw C:\work\reports\app.json | ConvertFrom-Json
$report.metadata.schema_version
$report.resolution.status
$report.uncertaintiesAlways confirm metadata.schema_version before an automated consumer assumes field names or enums. v0.3.x writes schema 0.8.
- A developer records the exact current PHP with
--from-phpand desired deployment PHP with--target-php. - The platform owner supplies verified extension assumptions or a target-platform profile.
- CI runs JSON output and checks the process exit code first.
- A developer reads direct resolution, staged resolution, blockers, source impact, and uncertainties.
- A technical manager uses risk, effort, confidence, and unresolved uncertainty for planning.
- The team performs the real upgrade in a separate branch.
- The application is installed and tested on the target runtime.
- The analyzer is rerun after each meaningful remediation or stage.
- The analyzer host runs PHP 8.0+ and Composer 2.
- The target path is correct and contains
composer.json. - The report directory exists outside the target.
- At least one package target, target PHP, or target-platform profile is supplied.
- Every standalone option uses
--name=value. - The Laravel adapter is installed if Laravel guidance is requested.
- Exit code and report statuses are interpreted separately.
-
uncertaintiesis reviewed before decisions are made. -
--debugis off for any report that will be shared.
- CLI Reference documents every standalone option.
- Artisan Command covers project-hosted Laravel use.
- Safety and Trust Boundaries explains credentials, restricted mode, paths, and untrusted projects.
- Troubleshooting and FAQ maps common symptoms to fixes.
- Reading the Report explains schema 0.8 for developers and managers.
PHP Upgrade Preflight — common product and monorepo Wiki · Common repository
- Home
- Key Concepts
- Package Map
- Class and Service Index
- Getting Started
- CLI Reference
- Artisan Command
- Reading the Report
- Safety and Trust Boundaries
- Troubleshooting and FAQ
- Architecture Overview
- Core Package Guide
- Core Analysis Pipeline
- Core Service Reference
- Determinism and Evidence
- Report Schema
- CLI Package Internals
- Laravel Package Internals
- Test Adapters
- Writing a Framework Adapter
- Laravel Adapter Internals
- Contributing
- Roadmap and Status
- Tools Reference
- Quality and Release Tooling
- Release Wiki Strategy