ajthinking/php-file-manipulator
Manipulate PHP files programmatically with a clean, fluent API. Read, modify, and rewrite classes, methods, properties, and namespaces without fragile regex, making code generation and refactoring safe and predictable.
nikic/php-parser with Laravel-aware queries (LaravelFile::models(), controllers(), serviceProviders(), custom commands_root / controllers_root). Any roadmap item that needs to ask questions of the codebase — architecture linting, dependency audits, generated docs, upgrade/codemod tooling, scaffolding commands, "which controllers bypass this policy" style governance reports — is a build-vs-buy call this package lets you settle cheaply instead of hand-rolling AST traversal.php: ^8.1 for the first time and supports Laravel 10–13. That makes it a constraint input to your platform roadmap: adopting it means PHP 8.1+ is non-negotiable, and Laravel 13 is already covered (relevant if statamic/cms 6 is in your stack).nikic/php-parser ^4.11, which cannot coexist with php-parser 5 — Pest 3 and newer included. If Composer is refusing to resolve the package, that's the cause, and it's a concrete argument for scheduling the 1.x → 2.x move rather than deferring it.->throw() had silently matched nothing since. That's a bus-factor / maintenance-health signal worth logging even as you adopt.Adopt when:
statamic/cms is the largest consumer and this release was explicitly validated against Statamic 5 (Laravel 12) and Statamic 6 (Laravel 13). If you run Statamic 4 or 3.4, note they pin ^1.0.3 and are unaffected by this release — you gain nothing here.Look elsewhere when:
^8.1 upper bound is deliberate: PHP 9 removes dynamic properties, which the AST node-identity mechanism relies on. Composer will decline the install rather than let you ship a package that fatals — good behaviour, but it means the package has a known, unaddressed expiry. If your platform plan reaches PHP 9, budget for a fork or replacement.Caveat to carry into any adoption: a class map pointed at a removed php-parser node for the whole of 2.0.0, and ->throw() matched nothing without erroring. Silent wrong answers are the failure mode here. Whatever you build, add a regression test asserting your queries return non-empty on known-good input — don't trust an empty result set.
To executives: Archetype is a small open-source Laravel package that lets our own tooling read and query our codebase's structure — models, controllers, service providers — without us writing and maintaining a parser. This release is maintenance-only: no API changes, nothing that can break existing usage, and it fixes several defects introduced in 2.0.0 while adding CI coverage across twelve PHP/Laravel combinations, macOS, and PHPStan. It is now verified against Statamic, its largest consumer. Cost is a Composer dependency; the alternative is bespoke tooling we own forever. The one strategic caveat: it will not run on PHP 9 without upstream work, so if we adopt it we should track that.
To engineering: Drop-in upgrade if you're on PHP 8.1+; from 1.x it's worth doing because 1.x pins php-parser 4 and blocks Pest 3 and anything else needing php-parser 5. No changes to our code. Fixes we care about: ->throw() maps correctly again after being silently dead since 2.0.0, and getReflection() now catches Throwable so an un-autoloadable parent class skips one file instead of killing the whole query — that affected models(), controllers(), and serviceProviders(), which is most of what we'd use. Also clears PHP 8.4 deprecations and fixes a config default where commands_root and controllers_root both pointed at the controllers directory. Known limit: PHP 9 removes dynamic properties, which the node-identity mechanism depends on; the Composer constraint blocks that install intentionally. Given the 2.0.0 regression went unnoticed, treat empty query results as suspect until we've got our own assertions in place.
How can I help you explore Laravel packages today?