nikic/php-parser
A PHP parser written in PHP that converts PHP 7/8 code into an abstract syntax tree, with tools for dumping, traversing, modifying, and regenerating code, plus name resolution and builders for static analysis and code generation.
Architecture fit. nikic/php-parser is a pure-PHP compiler front end: it turns PHP source into an AST, supports traversal/modification, and can pretty-print back to PHP. For a Laravel/PHP product, it is not a runtime framework component and should not sit in the HTTP request path. Its highest-leverage fit is developer tooling: custom Artisan audit/codemod commands, CI static analysis, architecture enforcement, code generation, and automated Laravel/PHP upgrade rules. It is also the foundation class used by tools such as Rector and PHPStan-style analyzers. It has no Laravel service provider, config, or auto-discovery, so it should be treated as a Composer library inside internal tooling rather than a Laravel package. It is a poor fit for evaluating or executing user-supplied PHP, and it cannot parse Blade templates directly without compiling/extracting PHP segments first.
Integration feasibility. Integration is Composer-native and low-friction: composer require --dev nikic/php-parser. Version 5.x requires PHP >= 7.4 and parses PHP 7.0–8.4, with limited PHP 5.x support; v5.9 adds PHP 8.6 partial function application. That aligns with Laravel 10/11/12-era PHP requirements. A spike can use ParserFactory::createForNewestSupportedVersion(), NodeTraverser, a custom NodeVisitor, and PrettyPrinter\Standard. The formatting-preserving pretty printer is the critical capability for safe codemods; JSON AST export enables caching and pipeline separation. No database, queue, or container binding is required. If the need is only analysis, wrapping PHPStan/Rector may be cheaper than building traversal infrastructure from scratch.
Technical risk. Main risks are major-version AST API churn (v4 to v5), lag behind new PHP syntax releases, edge cases in formatting-preserving rewrites, and false confidence from partial ASTs produced by error recovery. Performance and memory can degrade on large monorepos if parsing naively. Composer conflicts can arise when other dev tools pin a different parser major. Security risk is low for parsing only, but the constant-expression evaluator and any “evaluate/execute” extension must be treated carefully; the v5.8 change removing pipe-operator evaluation from constant expressions is a reminder that convenience evaluation can create arbitrary-call surfaces. License is BSD-3-Clause, compatible with Laravel’s MIT ecosystem. Upstream maintainer concentration is a moderate but manageable risk given 17k+ stars and broad adoption.
Key questions.
php-parser, or adopt Rector/PHPStan as the higher-level abstraction?Stack fit. Use nikic/php-parser as a dev dependency in a dedicated tooling package or tools/ Composer project, not in the application’s production dependency set. Expose capabilities through Artisan commands for developer use and CI jobs for enforcement. Keep custom visitors, rule definitions, and pretty-printer configuration in one owned module. For Laravel upgrade automation, pair the parser with Rector rule sets rather than hand-rolling every traversal. For read-only architecture checks, integrate with PHPStan custom rules where possible. Use Laravel’s scheduler only for periodic audits, not for per-request parsing.
Migration path. Start read-only: parse representative files, emit findings, and establish a baseline with no writes. Then introduce one formatting-preserving codemod behind a dry-run flag with diff output. Expand to automated PRs only after golden-file tests and php -l validation pass. If currently on v4, plan a v5 migration using UPGRADE-5.0: update ParserFactory usage, Name access patterns, removed deprecated APIs, and run the full rule test suite against both PHP and Laravel version matrices. Pin the parser major version and upgrade deliberately.
Compatibility. Confirm the parser version supports every PHP syntax feature in the target Laravel versions. Blade files must be compiled or statically extracted before parsing; do not assume raw .blade.php files are valid PHP. Ensure custom rules do not rewrite vendor code, generated code, or files excluded by the project’s coding standards. Check for Composer conflicts with PHPStan, Rector, Psalm, or other dev tools that may constrain the parser major. Maintain a PHP-version CI matrix because parser behavior and pretty-printer output can differ by target version.
Sequencing.
Maintenance. The library is actively maintained with frequent releases and strong documentation, but it is infrastructure: someone must own parser upgrades, custom visitors, golden-file tests, and PHP-version tracking. Budget recurring effort for each new PHP release and each parser major. Avoid broad custom AST logic where a maintained Rector/PHPStan rule can do the job. Pin versions in CI and review changelogs for pretty-printer and formatting-preservation changes.
Support. Upstream support is community/GitHub-based under BSD-3-Clause, with no commercial SLA. Internal support must cover rule authoring, failure triage, and upgrade playbooks. If the organization already supports Rector or PHPStan, route most user questions through those abstractions. Track security advisories via Composer audit and maintain a known-good parser version per Laravel/PHP matrix.
Scaling. Parsing is roughly linear per file but memory-intensive on large codebases. Process files in batches, exclude vendor/, storage/, node_modules/, and generated artifacts, and disable Xdebug in CI. For monorepos, parse only changed files using git diff and cache JSON ASTs for repeated analysis. Parallelize across CI jobs or queued workers. Measure both wall time and peak memory before enabling auto-PRs at scale.
Failure modes. Watch for parse errors on newly released PHP syntax, partial ASTs from error recovery causing false positives, pretty-printer reformatting unrelated code, broken output from incorrect node mutations, memory exhaustion on very large files, and Composer conflicts between parser majors. Mitigate with dry-run diffs, golden-file fixtures, post-rewrite php -l, PR review, version pinning, isolated tooling Composer projects, and a kill switch that disables automated writes. Treat any “evaluate constant expressions” feature as a security-sensitive path.
Ramp-up. PHP engineers can learn the node model and visitor pattern in one to two weeks; formatting-preserving transformations and precedence-sensitive pretty-printing take longer. Rector/PHPStan abstractions reduce ramp-up for common cases. Provide internal examples for one read-only rule and one codemod, document supported node types, and pair on the first production rule. As TPM, define success metrics early: rules shipped, upgrade hours saved, false-positive rate, PR acceptance rate, and mean time to support a new PHP release.
How can I help you explore Laravel packages today?