Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpstan Php Parser Laravel Package

phpstan/phpstan-php-parser

PHPStan extension for nikic/php-parser that adds precise type inference for AST nodes and visitors, improving static analysis of code that parses, traverses, or manipulates PHP source.

View on GitHub
Deep Wiki
Context7

Getting Started

Install as a dev dependency alongside an existing PHPStan setup:

composer require --dev phpstan/phpstan-php-parser

Register the extension in phpstan.neon (or phpstan.neon.dist):

includes:
    - vendor/phpstan/phpstan-php-parser/extension.neon

First thing to inspect after install: vendor/phpstan/phpstan-php-parser/extension.neon. That file lists every service it registers (stub files and dynamic return type extensions) — it tells you exactly which calls will get smarter analysis in your codebase.

The first use case that pays off is analyzing custom PHP-Parser visitors and Rector rules. Without this extension, PHPStan sees Node and Node[] almost everywhere and you get endless method_exists is not defined on PhpParser\Node complaints. With it loaded, node-typed properties, getType() calls, and NodeFinder return values resolve to the concrete subclasses you actually expect.

Skeleton sanity check before you build anything big:

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;

if ($node instanceof MethodCall) {
    // PHPStan now knows $node->var and $node->name
    /** @var Node\Identifier|Node\Expr $name */
    $name = $node->name;
}

Implementation Patterns

Instanceof narrowing in visitors. The primary value-add. Inside enterNode(Node $node), write your instanceof chain normally; the extension's stubs give PHPStan accurate property types on the narrowed class — MethodCall::$name, ClassMethod::$stmts, FunctionLike::$params, etc. No more docblock noise.

NodeFinder generics. When the extension is active, NodeFinder::findInstanceOf() and findFirstInstanceOf() return the narrowed generic type you pass in:

/** @var MethodCall[] $calls */
$calls = (new NodeFinder())->findInstanceOf($ast, MethodCall::class);

Skip the extension and PHPStan degrades to Node[], forcing a manual @var or assert() in every call site.

Custom Rule classes. In PHPStan rules that walk ASTs from php-parser, use native language narrowing for parameters and local variables; the extension carries it through chained calls like $class->getMethod(...)->stmts.

Analyzing your own node subclasses. If you extend PhpParser\Node\Expr and register custom node handlers, the extension gives you correct parent-class property types but cannot know your subclass's specific properties. Pair with @property docblocks on your subclass.

Combining with Rector. If your project also uses rector/rector, both packages depend on nikic/php-parser; keep the versions aligned (see Gotchas). The extension's stubs are additive, so no conflict in analysis behavior — the version pin is the only real risk.

Test-time usage. In PHPUnit tests that build AST fixtures, add @var assertions against narrowed types and let phpstan analyse tests/ validate the fixture shapes. Useful when you write a visitor and want to confirm the fixture actually contains the nodes you expect.

Gotchas and Tips

Archived since 2021-12-29 — treat as frozen. No fixes will land, and nikic/php-parser has moved past 4.x. Its stubs describe PHP-Parser v4 node shapes; if your project depends on php-parser 4.10+ or any 5.x branch, some properties (ClassMethod::$flags, Expr\Closure::$attrGroups, etc.) will not be as precisely typed as you'd hope. Modern PHPStan (1.9+) ships internal php-parser stubs that partially overlap, so double-check whether you actually need this package at all before adding it.

nikic/php-parser version conflicts are the #1 failure mode. PHPStan itself bundles a specific php-parser range, and Rector bundles another. composer why nikic/php-parser before installing. If Composer wants to downgrade php-parser or Rector, back out — you'll break analysis of php-parser-using code elsewhere.

Silent activation failures. The extension only kicks in for files it's told to analyze. If narrowing isn't working:

  1. Confirm extension.neon is actually included — run vendor/bin/phpstan analyse --debug and grep for the package name.
  2. Clear the result cache: vendor/bin/phpstan clear-result-cache.
  3. Check your excludePaths / paths — the file must be in scope.

getAttribute() returns mixed, always. No extension can help here; the attribute key space is user-defined. Always cast or narrow manually:

$loc = $node->getAttribute('startLine');
assert(is_int($loc));

Dynamic node types via factories aren't inferred. If you have a helper that returns a Node built from user config, PHPStan still sees Node. Add explicit return-type docblocks (@return Expr\BinaryOp) to your factory — the extension doesn't rewrite return types of your code.

No extension points for the extension itself. It's a fixed bundle of stubs + dynamic return types. If you need a narrower type (e.g. NodeFinder on a specific generic), the correct approach is to write your own PhpStan\Type\DynamicMethodReturnTypeExtension in a project-local extension rather than patching this one — you can't safely fork an archived package.

Bleeding-edge config is sometimes required. Older PHPStan releases needed:

includes:
    - phar://phpstan.phar/conf/bleedingEdge.neon

This no longer matters on current PHPStan, but if you're pinned to pre-1.0, include it or narrowing silently regresses.

Debugging tip. When PHPStan reports a type you believe is wrong ("Method PhpParser\Node\Stmt\Class_::getMethods() not found"), check whether you're hitting a stub-defined property vs. a real one — run vendor/bin/phpstan dump-parameters then vendor/bin/phpstan describe-type 'PhpParser\Node\Stmt\Class_' on PHPStan 1.10+ to see what the extension actually contributed.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console