rector/rector-downgrade-php
rector/rector-downgrade-php provides Rector rules for downgrading PHP code, automatically rewriting modern syntax and features into older, compatible versions. Useful for backporting projects or libraries to legacy PHP runtimes with repeatable transformations.
Architecture fit
rector/rector-downgrade-php is build-time tooling, not a runtime dependency. It supplies Rector rule sets that rewrite code using newer PHP syntax and APIs (match, enums, readonly, nullsafe, named arguments, first-class callables, str_contains-style functions) into equivalent code targeting an older PHP floor. In a Laravel/PHP product this maps to one narrow scenario: we develop and test on a modern interpreter but must ship code that executes on an older one — most commonly a distributed CLI/phar, a Composer package consumed by downstream apps on mixed PHP versions, or a plugin targeting a legacy host. For a standard Laravel application deployed on a single, controlled PHP version, this package has effectively no role; a version-floor check in composer.json and CI is the correct, cheaper control.
Integration feasibility Feasible and low-ceremony if Rector is already in the toolchain. Integration is a config file plus a CI step:
rector/rector and this package to require-dev.DowngradePhp80, DowngradePhp74) in a dedicated rector-downgrade.php config.php-scoper and validate the scoped output after downgrading, since scoping rewrites and downgrading rewrites interact.If Rector is not already adopted, this becomes the entry point to a full AST-refactoring toolchain — a much larger decision than this package implies.
Technical risk The dominant risk is silent semantic drift, not breakage. Syntax downgrades are largely faithful; API and idiom downgrades are approximations. Concrete exposures:
str_contains/array_is_list-style polyfills alter edge-case behavior (type juggling, empty-needle handling).readonly and enum downgrades lose invariants the runtime enforced.Second risk: coverage confidence. With 44 stars and zero dependents, there is no observable population of users exercising edge cases. RectorPHP org backing gives it credibility and a maintenance path (it is reportedly used to produce Rector's own downgraded distribution), but the blast radius of a missed rule is a fatal error on the oldest supported PHP — discovered by end users, not by us.
Key questions
rector --dry-run?Stack fit
Best fit: an internal Composer package or artisan-distributed CLI shared across applications with heterogeneous PHP versions; a WordPress/legacy-host plugin; a phar-distributed developer tool. Poor fit: a first-party Laravel app on a pinned runtime, where composer.json platform constraints plus a CI matrix solve the problem with zero new tooling.
Migration path
Greenfield adoption, not a migration. Treat the downgraded artifact as a derived build output: authored source stays modern, the downgrade step is a build stage, and nothing downstream ever edits the generated tree. Encode this as composer build:downgrade so it is reproducible and never run manually.
Compatibility
Pin the package in lockstep with rector/rector — rule sets are coupled to Rector's core and to nikic/php-parser syntax support. Expect a required bump on each Rector major release. Verify the package supports our authored PHP version (the newest syntax we actually use) as well as our floor; new-syntax support often lands after a PHP GA.
Sequencing
Do not attempt org-wide rollout before the floor-version execution matrix exists — a passing downgrade run is not evidence of a working artifact.
Maintenance Low ongoing effort but non-zero: version pins, periodic re-runs as authored code adopts new syntax, and review of generated diffs. The real cost is the rule gap: every new PHP feature we use requires a corresponding rule to exist before we can adopt it in downgraded code paths. Budget a few hours per PHP minor release and a defined owner.
Support Community-only. Issues route to the RectorPHP org repository; no SLA, no vendor. Internal support burden depends entirely on our own floor-version test matrix — this package cannot be our safety net, our tests must be.
Scaling Technically trivial — per-file AST transforms, runs in seconds to low minutes, parallelizable, cacheable in CI. Organizational scaling is the constraint: every team whose code feeds the downgraded artifact must understand the constraints (no reflection-dependent behavior, no attribute-driven metadata on the floor version). That is a documentation and code-review problem, not an infrastructure one.
Failure modes
--dry-run.Ramp-up One engineer, roughly 1–2 days to become productive: Rector config semantics, the version-set mapping, and the build-artifact discipline. Team-wide awareness is the larger lift — a short design note stating "we author on PHP 8.3, we ship to 7.4, therefore these constructs are off-limits" prevents most incidents.
TPM recommendation: narrow, justified only by a concrete legacy-floor obligation and preferably only where Rector is already present. The opportunity score signals real latent utility for package/tool maintainers; the 1.16 overall score and zero dependents signal that this is not a foundation to build broadly on. Approve as a scoped build-stage utility with a floor-version execution matrix as a hard prerequisite; reject as a general-purpose compatibility strategy for the application portfolio.
How can I help you explore Laravel packages today?