Weave Code
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

Php Parser Laravel Package

nikic/php-parser

Parse PHP code into an Abstract Syntax Tree (AST) for static analysis, manipulation, and code generation. Supports PHP 5.x to 8.4, handles errors gracefully, and preserves formatting during AST-to-code conversion. Easily traverse, modify, and convert ASTs back to PHP, with JSON serialization support...

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require nikic/php-parser
    

    Use nikic/php-parser:^5.0 for PHP 7.4+ or nikic/php-parser:^4.0 for PHP 5.2-8.3 compatibility.

  2. First Use Case: Parse a PHP file into an AST and dump it:

    use PhpParser\ParserFactory;
    
    $parser = (new ParserFactory())->createForNewestSupportedVersion();
    $ast = $parser->parse(file_get_contents('MyClass.php'));
    print_r($ast);
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

  1. AST Traversal & Modification: Use NodeTraverser with custom NodeVisitor to modify nodes:

    $traverser = new NodeTraverser();
    $traverser->addVisitor(new class extends NodeVisitorAbstract {
        public function enterNode(Node $node) {
            if ($node instanceof Stmt_ClassMethod) {
                $node->returnType = new Name('void');
            }
        }
    });
    $ast = $traverser->traverse($ast);
    
  2. Code Generation: Use BuilderFactory to construct nodes programmatically:

    $builder = (new BuilderFactory())->create();
    $method = $builder->method('foo')
        ->makePublic()
        ->addParam($builder->param('bar'))
        ->addStmt($builder->expr($builder->funcCall('echo', ['bar'])));
    
  3. Name Resolution: Resolve fully qualified names in the AST:

    $resolver = new NameResolver();
    $resolver->resolve(new NodeFinder(), $ast);
    
  4. Pretty Printing: Convert AST back to PHP with formatting:

    $printer = new PrettyPrinter\Standard();
    $code = $printer->prettyPrintFile($ast);
    file_put_contents('output.php', $code);
    

Integration Tips

  • Laravel Service Provider: Bind the parser and printer as singletons:

    $this->app->singleton(ParserFactory::class, fn() => new ParserFactory());
    $this->app->singleton(PrettyPrinterAbstract::class, fn() => new PrettyPrinter\Standard());
    
  • Artisan Commands: Create a command to parse/modify files:

    class ParseCommand extends Command {
        protected $signature = 'parse {file}';
        public function handle() {
            $parser = app(ParserFactory::class)->createForNewestSupportedVersion();
            $ast = $parser->parse(file_get_contents($this->argument('file')));
            $this->info($ast[0]->getDocComment() ?? 'No docblock');
        }
    }
    
  • Event Listeners: Hook into Laravel events (e.g., Illuminate\Foundation\Bootstrap\LoadConfiguration) to parse config files dynamically.


Gotchas and Tips

Pitfalls

  1. PHP Version Mismatch:

    • Use createForOldestSupportedVersion() or createForNewestSupportedVersion() explicitly.
    • Example: Parsing PHP 5.6 code with a PHP 8.0 parser may fail or produce incorrect ASTs.
  2. Cyclic References:

    • Enable weakReferences in NodeConnectingVisitor to avoid memory leaks:
      $visitor = new NodeConnectingVisitor();
      $visitor->setWeakReferences(true);
      
  3. Formatting Preservation:

    • Use PrettyPrinter\Standard with preserveWhitespace: true for partial modifications:
      $printer = new PrettyPrinter\Standard(['preserveWhitespace' => true]);
      
  4. Attribute Handling:

    • Attributes on parameters/classes are parsed as attrGroups. Ensure compatibility with target PHP version (e.g., PHP 7.4+ for multi-line attributes).
  5. Error Recovery:

    • Parse invalid code with ParserFactory::PARSER_EARLY_STOP_ON_ERROR:
      $parser = (new ParserFactory())->create(
          ParserFactory::PARSER_EARLY_STOP_ON_ERROR
      );
      

Debugging

  • Node Dumping: Use NodeDumper for debugging:

    $dumper = new NodeDumper();
    $dumper->setDumpNodeAnnotations(true); // Show node positions
    echo $dumper->dump($ast);
    
  • Xdebug Overhead: Disable Xdebug during parsing for performance:

    if (extension_loaded('xdebug')) {
        ini_set('xdebug.mode', 'off');
    }
    

Extension Points

  1. Custom Pretty Printer: Extend PrettyPrinterAbstract to modify formatting:

    class CustomPrinter extends PrettyPrinterAbstract {
        public function pMethod(Stmt_ClassMethod $node) {
            return '/* custom */ ' . parent::pMethod($node);
        }
    }
    
  2. Custom Node Visitors: Implement NodeVisitor for complex transformations:

    class AddDocblockVisitor extends NodeVisitorAbstract {
        public function enterNode(Node $node) {
            if ($node instanceof Stmt_Class) {
                $node->setAttribute('docComment', '/** @deprecated */');
            }
        }
    }
    
  3. Lexer Hooks: Extend Lexer for custom token handling (e.g., custom PHPDoc tags):

    $lexer = new Lexer(['usedAttributes' => ['customTag']]);
    
  4. Constant Evaluation: Use Evaluator for runtime evaluation of constant expressions:

    $evaluator = new Evaluator();
    $value = $evaluator->evaluate($ast[0]->expr, []);
    

Laravel-Specific Tips

  • Blade Template Parsing: Parse Blade files by stripping @ directives first:

    $code = preg_replace('/@\w+\(.*?\)/', '', file_get_contents('view.blade.php'));
    
  • Migration File Analysis: Use the parser to validate migrations before execution:

    $parser = app(ParserFactory::class)->createForNewestSupportedVersion();
    try {
        $ast = $parser->parse(file_get_contents('database/migrations/...'));
        // Validate AST structure (e.g., no raw SQL in `up()`)
    } catch (Error $e) {
        throw new RuntimeException("Invalid migration syntax: " . $e->getMessage());
    }
    
  • Dynamic Configuration: Parse and merge config files at runtime:

    $parser = app(ParserFactory::class)->createForOldestSupportedVersion();
    $configAst = $parser->parse(file_get_contents('config/custom.php'));
    // Merge with default config using AST traversal
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata