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

Simple Php Doc Parser Laravel Package

symplify/simple-php-doc-parser

Simple PHP Doc Parser by Symplify is a lightweight library for reading PHP docblocks. It extracts comments, tags, and annotations from classes, methods, and properties through a simple API, making PHPDoc data easy to use in static analysis, code generation, and documentation tools.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package alongside its underlying parser:

composer require symplify/simple-php-doc-parser

Because the package is essentially a thin, service-oriented façade over phpstan/phpdoc-parser, the first place to look is the wrapper class itself (Symplify\SimplePhpDocParser\PhpDocParser) — not the upstream AST. The wrapper hides the boilerplate of instantiating PHPStan's Lexer, ConstExprParser, TypeParser, and PhpDocParser manually, and exposes a single method that turns a raw docblock string into a PhpDocNode.

The most common first use case is extracting type information from a docblock for a custom tool, rule, or generator. A minimal run:

use Symplify\SimplePhpDocParser\PhpDocParser;

$parser = new PhpDocParser(/* dependencies if not using DI */);

$docBlock = <<<DOC
/**
 * @param string \$name
 * @param int \$age
 * @return bool
 */
DOC;

$phpDocNode = $parser->parseDocBlock($docBlock);

From there you traverse $phpDocNode->children to find ParamTagValueNode, ReturnTagValueNode, VarTagValueNode, etc. Note that the wrapper accepts docblocks including the /** ... */ delimiters when using parseDocBlock(), while other entry points (parseStringToNode(), parseDocBlockToNode()) trim differently — pick one and be consistent.

If you are inside a Symfony application or a Symplify-based tool (Rector, ECS, PHPStan extensions), the package registers itself as a service; you can inject PhpDocParser directly and skip manual construction entirely.

Implementation Patterns

Extract signatures for generators / custom rules. The dominant pattern is: read a reflection docblock (ReflectionMethod::getDocComment()), feed it to the parser, pull out typed tag nodes, and act on them. This is what makes it useful in a Rector rule, a PHPStan extension, or a code generator.

$phpDocNode = $parser->parseDocBlock($reflectionMethod->getDocComment());
foreach ($phpDocNode->getParamTagValues() as $param) {
    // $param->parameterName, $param->type, $param->description
}

The upstream PhpDocNode already exposes convenience getters like getParamTagValues(), getReturnTagValue(), getVarTagValues(), getMethodTagValues(), getPropertyTagValues() — use these instead of walking children by hand.

Magic property / method discovery. A very practical use is extracting @property and @method declarations from a class that relies on __call/__get. This is common in ORM entities, Laravel facades, and legacy proxy patterns. Parse the class docblock once, cache the result keyed by class name + file mtime, and expose the members to your analysis.

Visitor-based transformations. The package ships with a PhpDocNodeVisitor and a traverser. If you need to rewrite docblocks (e.g., normalize types, drop deprecated tags), implement a visitor rather than string-regexing the docblock — it keeps positions and node structure intact.

Integration with static analysis. Inside a Rector rule, you get the parser via constructor injection; inside a PHPStan rule, use the PhpDocParser service from the container. This is where the "service integration" flavor pays off — you don't manage parser state per file.

Caching. Always memoize parse results. Parsing the same docblock repeatedly in a hot path (a rule applied to thousands of files) is measurable overhead. Key on sha1($docBlock) or on file + line, whichever is more stable in your context.

Gotchas and Tips

  • Docblock must be syntactically valid. Malformed input — unbalanced braces, unquoted defaults with spaces, stray @ — throws from the underlying parser. Wrap calls in a try/catch when processing third-party code you don't control, and fail gracefully (return null, log, skip).
  • The wrapper passes through to PHPStan's AST, not a simplified model. If you were hoping for arrays and scalars, you'll get PhpDocNode trees. Be prepared for $node->type to be an IdentifierTypeNode, GenericTypeNode, UnionTypeNode, or a ConstTypeNode — union and intersection types are not plain strings.
  • Version coupling with phpstan/phpdoc-parser. Because the package wraps a specific major range of the upstream parser, upgrading one may force the other. Pin phpstan/phpdoc-parser in your composer.json if you also use it directly, and check the wrapper's composer.json before bumping.
  • Position offsets are per-string, not per-file. $node->getStartLine() is relative to the docblock string you passed in, not the source file. Add the docblock's actual start line yourself if you're reporting diagnostics.
  • Delimiter handling varies by entry point. parseDocBlock() expects the /** */ envelope; parseStringToNode() expects the inner content without comment markers. Mixing them silently produces empty nodes instead of an obvious error — a frequent source of "why is my result empty?" confusion.
  • Trailing whitespace and tab-indented docblocks are fine; unterminated docblocks are not. If you slice a comment out of a file with regex, make sure you captured the closing */.
  • Extension point is the visitor pattern, not string replacement. If you need to rewrite docblocks, use the provided traverser/visitor — regexing a docblock will break on generic types like array<string, list<int>>.
  • No docblock autoloading. This is a parser, not a reflection facade. You still supply the raw string (via Reflection or file reading); there is no parseClass(SomeClass::class) method.
  • Debugging: when a parse throws or returns nothing, dump the raw docblock first (var_dump($raw)), then test it in isolation against https://phpstan.org/…-style playgrounds of the underlying parser. The wrapper rarely adds failure modes of its own; the error almost always comes from the upstream parser on bad input.
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