leovie/php-method-modifier
A small PHP utility for programmatically modifying method modifiers, making it easy to adjust method visibility and related characteristics at runtime. Useful for metaprogramming, testing, and code-generation workflows.
What the package is. leovie/php-method-modifier is a source-code manipulation library: it reads a PHP file, locates a named method, and rewrites that method's source. It is a build-time / offline utility, not a runtime dependency. Nothing about this package belongs in a request path, and no part of the v2.0.0 release changes that framing.
What changed in v2.0.0 — and what didn't. The release is two dependency PRs and nothing else:
infection/infection ^0.25.3 → ^0.26.6 (dev-only, mutation testing — zero production footprint);The material consequences of the Symfony 6 move: the package's effective PHP floor rises to 8.0 (Symfony 6 components require PHP ≥ 8.0), and Symfony 6 was a BC-heavy release (dropped deprecated APIs, added native parameter/return types, changed exception hierarchies). Because the bump was forced by proxy rather than by a designed API change, the v1 → v2 public surface may have shifted in ways the release notes do not disclose — there is no CHANGELOG entry describing the API delta, only two dependabot/maintainer PR links.
Critically, none of this touches the core rewriting engine. The nikic/php-parser (or equivalent) constraint is not mentioned, no new PHP syntax support is claimed, and there is no evidence the transformer was modernized for PHP 8.1 enums, 8.2 readonly/DNF, 8.3 typed class constants, or 8.4 property hooks. A Symfony console/filesystem bump does not make a 2022-era source rewriter understand 2024-era syntax. The v2.0.0 release raises the runtime floor without raising the parsing ceiling — the single most important risk in the original assessment is untouched.
Two milder signals worth recording: (a) the maintainer merged a human-authored PR (@LeoVie on the Symfony upgrade), so the repo is not fully cold; (b) infection/infection in the dev dependencies implies a mutation-testing CI setup, which is above the bar for a 0-star package. Neither substitutes for adopters. Dependents remain effectively zero, and v2.0.0 does not change the fact that we would be the first production consumer.
Architecture fit. Unchanged, and narrow. Legitimate fits: scaffolding/codegen (generated boilerplate methods, DTO accessors in an internal generator), automated refactoring/codemods during a migration, controlled patching of vendored or legacy code where forking is unacceptable. Not a fit: runtime instrumentation, AOP-style behavior injection, dynamic proxying, or anything re-parsing source per request. If the goal is "change behavior," use a decorator, interface, or framework hook. If the goal is "change source once, deterministically, in CI," this remains a plausible candidate — but only on v2.0.0, and only after the spike below.
Integration feasibility. Mechanically easy, marginally easier than assessed last time because the PHP 8.0 floor is now explicit rather than inferred: Composer-installable, BSD-3-Clause (permissive, commercial-safe with attribution), small single-purpose API. The blocker was never effort — it was confidence, and v2.0.0 does not add confidence in the part that matters. It adds a compatibility constraint: we cannot adopt v2 on any repo pinned below PHP 8.0, and any repo still on v1 would need a major-version hop with an undocumented API delta.
Technical risk — still high, with the same four areas now updated:
nikic/php-parser; it now includes the Symfony major. If the constraint is ^6.0, Composer resolves to 6.4 LTS and we are fine through 2027. If it is 6.0.*, we are pinning to a Symfony line that is end-of-life — a security-patch dead end baked into a dev tool. This is a five-minute check with outsized consequences and must be answered before adoption.Key questions — updated for v2.0.0:
^6.0 (resolves to 6.4 LTS, acceptable) or 6.0.* (EOL, blocking)?nikic/php-parser major is required, and does the tool parse PHP 8.2/8.3/8.4 syntax correctly? This is the go/no-go question.php-parser, Rector, or php-cs-fixer without rewriting call sites?Stack fit. Unchanged: require-dev only, in a tooling/codegen repo, never in a runtime composer.json. It sits in the Rector / PHP-CS-Fixer / Psalm tier — developer machines and CI only. Note the new floor: the tooling repo itself must be on PHP ≥ 8.0 to install v2.
Migration path. Still a spike, not an integration — but the spike is now scoped to v2.0.0 specifically, and it must include an explicit v1→v2 API diff:
MethodRewriter::rewrite($file, $method, $body)). Unchanged in rationale and now more valuable: it insulates us from both an upstream fork decision and a future v2 → v3 bump.nikic/php-parser — comparable abstraction cost, maintained foundation.Compatibility. Pin PHP, Symfony, and parser versions explicitly in CI. The fixture matrix is now doing double duty: it must cover (a) every PHP minor we support, so a parser upgrade that breaks modern syntax fails the build, and (b) a v1-vs-v2 equivalence check on unchanged inputs. If we adopt, adopt v2 — v1 is a dead end with a lower PHP floor and no path forward.
Sequencing. API diff → spike on v2.0.0 → internal wrapper → CI fixture matrix (PHP minors + v1/v2 equivalence) → fork & pin (Symfony + parser) → only then wire into any recurring pipeline. Do not land this in a release-blocking path in the quarter it is introduced.
Maintenance. Largely unchanged: assume we own it. What v2.0.0 modifies is the scope of ownership — we are now also tracking a Symfony major, not just a parser major. Budget for: (a) an annual compatibility audit against new PHP releases, (b) Symfony and parser security-patch tracking, (c) an internal fork we can patch. The codebase is small, so the audit is hours not weeks — but it is recurring, and the number of moving parts just went from one to two. Assign a named owner before the first commit.
Support. Still no vendor, no SLA, no community; the escalation path is "read the source." The v2.0.0 release notes are a case study in why this matters: a major version bump with no API changelog. If we need to know what broke, we diff it ourselves. Tolerable for a dev-only tool whose failure stops a build; intolerable for anything touching shipped artifacts without review. Mitigation unchanged: internal runbook, fixture corpus as living documentation, documented fallback to raw php-parser.
Scaling. Unchanged and effectively irrelevant — file I/O and parsing during CI, linear in files touched, seconds to minutes, never in a latency budget. The real constraint remains the number of distinct transformations we ask it to perform; each one is untested surface against an unmaintained parser, and v2.0.0 added no new tested surface.
Failure modes to design against:
composer update silently moving Symfony or the parser. Detect with lockfile pinning and reproducible CI.6.0.*, we are shipping a dev dependency that will never receive a security patch. Detect by reading composer.json once, today.Ramp-up. Unchanged for engineers: roughly half a day to productive use on the narrow API, plus a short detour to absorb the v1→v2 delta. The scarcer skill is judgment about when source rewriting is the right tool at all — that belongs with a senior engineer or architect. TPM decision, restated and largely unchanged: is the recurring codegen use case valuable enough to justify owning a forked, thinly-maintained dependency with two transitive pins? v2.0.0 does not answer that question — it only confirms the maintainer is willing to bump infrastructure while leaving the parser and the public API story undocumented. Default remains no unless the spike demonstrates concrete, repeated need; if it does, adopt v2 behind a wrapper, on a fork, with a named owner and an exit ramp.
How can I help you explore Laravel packages today?