agentleFS
Phaedra-SolutionsPhaedra-Solutions/cursor-rules/skills/upgrade-php/SKILL.md

upgrade-php

Skill4 starsChanged 10 days agoMITView on GitHub

Upgrade a project's PHP version one minor release at a time (for example 8.1 → 8.2 → 8.3 → 8.4) with Rector's PHP sets (withPhpSets), PHPStan at a fixed level with a baseline, Composer platform and dependency updates, deprecation notices treated as errors, and every runtime pin (composer.json, Docker, CI, hosting) updated together; verify with tests and a smoke test. Use when asked to upgrade PHP, when legacy/php-legacy applies (8.2 EOL 31 Dec 2026), or when a framework upgrade needs a newer PHP.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Hop one minor version: update require.php (for example "^8.3"), config.platform.php, Docker, CI and hosting together.

    line 49
  2. Distinctive:

    Never skip minor versions in one hop, and never upgrade PHP and a framework major in the same change.

    line 71
  3. Very specific:

    Never silence deprecations with error_reporting or @ to make the upgrade pass.

    line 72
  4. Very specific:

    Never apply Rector to vendor/.

    line 73
  5. Very specific:

    Never auto-commit, push or deploy.

    line 74

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Upgrade PHP

When to use

  • The user asks to upgrade PHP, or the project runs PHP 8.2 or older (see legacy/php-legacy).
  • A dependency (Laravel 13 needs 8.3+) requires a newer PHP.

Before you start

  • List every place that pins PHP: require.php and config.platform.php in composer.json, Dockerfiles (FROM php:…), CI (php-version:), hosting/PaaS settings, and PHPStan/Psalm phpVersion.
  • List extensions in use (php -m, ext-* in composer.json) and check they exist for the target (PECL extensions lag).
  • Working tree clean; new branch (chore/php-8.4).
  • Ask the user:
    • the target: 8.4 (security support to Dec 2028) or 8.5 (to Dec 2029); default 8.4 for existing apps;
    • whether to stop for review after each minor hop;
    • whether network installs are approved (core/supply-chain cooldown applies).

Steps

  1. Baseline on the current version: composer install, PHPStan, tests, and the app starting. Record failures. If PHPStan isn't set up, add it at a level the code passes and generate a baseline (vendor/bin/phpstan analyse --generate-baseline), so new errors stand out.
  2. Surface deprecations on the current version: run the tests with error_reporting=E_ALL and deprecations converted to failures (PHPUnit failOnDeprecation="true" or convertDeprecationsToExceptions), and fix them first.
  3. Add Rector (composer require --dev rector/rector) with a config that targets the next minor only:

    // rector.php
    use Rector\Config\RectorConfig;
    
    return RectorConfig::configure()
        ->withPaths([__DIR__ . '/src', __DIR__ . '/app', __DIR__ . '/tests'])
        ->withPhpSets(php83: true);   // the hop's target: php82, php83, php84, php85
    vendor/bin/rector process --dry-run
    vendor/bin/rector process

    Review the diff; Rector's PHP sets modernize syntax but don't fix every runtime change.

  4. Hop one minor version: update require.php (for example "^8.3"), config.platform.php, Docker, CI and hosting together; run composer update --with-all-dependencies for packages that need newer versions (one package group at a time); install missing extensions.
  5. Fix runtime changes from the PHP migration guide for that version (backward-incompatible changes and deprecations). Examples: 8.2 dynamic properties deprecated (#[\AllowDynamicProperties] only as a temporary bridge); 8.3 typed class constants and json_validate; 8.4 implicitly nullable parameter types deprecated (?Type $x = null), new Deprecated attribute; 8.5 removals listed in its migration guide.
  6. Verify (next section), show the diff and results, and wait for approval before the next hop. Commit only when asked (git-commit skill).
  7. At the target, raise the PHPStan level gradually as a separate change, and switch to languages/php.

Verify

php -v                                   # the hop's target, on every runner
composer validate --strict
composer install --no-interaction
vendor/bin/rector process --dry-run      # nothing left for this target
vendor/bin/phpstan analyse
vendor/bin/phpunit                       # or: vendor/bin/pest / php artisan test
composer audit
grep -rnE "\"php\":|php-version|FROM php:" composer.json Dockerfile* .github/ 2>/dev/null   # no old pins left

Then start the app on the target PHP: no deprecation or warning output in logs during a smoke test of key routes, CLI commands and queue workers.

Safety

  • Never skip minor versions in one hop, and never upgrade PHP and a framework major in the same change.
  • Never silence deprecations with error_reporting or @ to make the upgrade pass; never grow the PHPStan baseline to hide new errors.
  • Never apply Rector to vendor/; review every Rector change.
  • Never auto-commit, push or deploy; don't hand-edit composer.lock.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.