Are you happy with your logging solution? Would you help us out by taking a 30-second survey? Click here

PHP-Parser

A PHP parser written in PHP

Subscribe to updates I use PHP-Parser


Statistics on PHP-Parser

Number of watchers on Github 5340
Number of open issues 24
Average time to close an issue 21 days
Main language PHP
Average time to merge a PR about 19 hours
Open pull requests 10+
Closed pull requests 70+
Last commit over 1 year ago
Repo Created over 8 years ago
Repo Last Updated over 1 year ago
Size 4.38 MB
Organization / Authornikic
Latest Releasev4.0.0
Contributors44
Page Updated
Do you use PHP-Parser? Leave a review!
View open issues (24)
View PHP-Parser activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating PHP-Parser for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

PHP Parser

Build Status Coverage Status

This is a PHP 5.2 to PHP 7.2 parser written in PHP. Its purpose is to simplify static code analysis and manipulation.

Documentation for version 4.x (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.2).

Documentation for version 3.x (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2).

Features

The main features provided by this library are:

  • Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST).
    • Invalid code can be parsed into a partial AST.
    • The AST contains accurate location information.
  • Dumping the AST in human-readable form.
  • Converting an AST back to PHP code.
    • Experimental: Formatting can be preserved for partially changed ASTs.
  • Infrastructure to traverse and modify ASTs.
  • Resolution of namespaced names.
  • Evaluation of constant expressions.
  • Builders to simplify AST construction for code generation.
  • Converting an AST into JSON and back.

Quick Start

Install the library using composer:

php composer.phar require nikic/php-parser

Parse some PHP code into an AST and dump the result in human-readable form:

<?php
use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory;

$code = <<<'CODE'
<?php

function test($foo)
{
    var_dump($foo);
}
CODE;

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
try {
    $ast = $parser->parse($code);
} catch (Error $error) {
    echo "Parse error: {$error->getMessage()}\n";
    return;
}

$dumper = new NodeDumper;
echo $dumper->dump($ast) . "\n";

This dumps an AST looking something like this:

array(
    0: Stmt_Function(
        byRef: false
        name: Identifier(
            name: test
        )
        params: array(
            0: Param(
                type: null
                byRef: false
                variadic: false
                var: Expr_Variable(
                    name: foo
                )
                default: null
            )
        )
        returnType: null
        stmts: array(
            0: Stmt_Expression(
                expr: Expr_FuncCall(
                    name: Name(
                        parts: array(
                            0: var_dump
                        )
                    )
                    args: array(
                        0: Arg(
                            value: Expr_Variable(
                                name: foo
                            )
                            byRef: false
                            unpack: false
                        )
                    )
                )
            )
        )
    )
)

Let's traverse the AST and perform some kind of modification. For example, drop all function bodies:

use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;

$traverser = new NodeTraverser();
$traverser->addVisitor(new class extends NodeVisitorAbstract {
    public function enterNode(Node $node) {
        if ($node instanceof Function_) {
            // Clean out the function body
            $node->stmts = [];
        }
    }
});

$ast = $traverser->traverse($ast);
echo $dumper->dump($ast) . "\n";

This gives us an AST where the Function_::$stmts are empty:

array(
    0: Stmt_Function(
        byRef: false
        name: Identifier(
            name: test
        )
        params: array(
            0: Param(
                type: null
                byRef: false
                variadic: false
                var: Expr_Variable(
                    name: foo
                )
                default: null
            )
        )
        returnType: null
        stmts: array(
        )
    )
)

Finally, we can convert the new AST back to PHP code:

use PhpParser\PrettyPrinter;

$prettyPrinter = new PrettyPrinter\Standard;
echo $prettyPrinter->prettyPrintFile($ast);

This gives us our original code, minus the var_dump() call inside the function:

<?php

function test($foo)
{
}

For a more comprehensive introduction, see the documentation.

Documentation

  1. Introduction
  2. Usage of basic components

Component documentation:

  • Walking the AST
    • Node visitors
    • Modifying the AST from a visitor
    • Short-circuiting traversals
    • Interleaved visitors
    • Simple node finding API
    • Parent and sibling references
  • Name resolution
    • Name resolver options
    • Name resolution context
  • Pretty printing
    • Converting AST back to PHP code
    • Customizing formatting
    • Formatting-preserving code transformations
  • AST builders
    • Fluent builders for AST nodes
  • Lexer
    • Lexer options
    • Token and file positions for nodes
    • Custom attributes
  • Error handling
    • Column information for errors
    • Error recovery (parsing of syntactically incorrect code)
  • Constant expression evaluation
    • Evaluating constant/property/etc initializers
    • Handling errors and unsupported expressions
  • JSON representation
    • JSON encoding and decoding of ASTs
  • Performance
    • Disabling XDebug
    • Reusing objects
    • Garbage collection impact
  • Frequently asked questions
    • Parent and sibling references
PHP-Parser open issues Ask a question     (View All Issues)
  • almost 3 years PhpParser\Error thrown when using self-executing anonymous functions
  • about 3 years Usefulness of attributes
  • about 3 years Aborting Traversal (like a break statement in a loop)
  • about 3 years Empty lines will get ignored
  • about 3 years Code Generator Generator
  • about 3 years prettyPrintFile comment bug
  • over 3 years Convert to/from php-ast nodes
  • over 3 years FYI: two things that I've done with/to PhpParser that might be useful permanent features
  • over 3 years Comments are assigned multiple times
  • almost 4 years Pass current indent through pretty printer methods instead of using noIndentToken
  • about 4 years Use service container to get instance for new node
  • about 4 years How to print null?
  • over 4 years Inline comments with # getting associated with the wrong source-code element?
  • over 6 years Even more fluid code generation
  • almost 7 years Optionally add nodes for whitespace
  • over 7 years Introducing PHPParser_Node_Stmt_Block
PHP-Parser open pull requests (View All Pulls)
  • [WIP] Scrutinizer CI
  • Made improvements to pretty printing
  • Better Travis configuration
  • Remove new-line after PHP closing tag
  • Move token byref vars into object
  • Some fixes from PHPStan
  • Clean up PHP-Parser
  • Easy way to fiddle with the traverser.
  • Add pretty printer interface
  • Create ParserBuilder class and build-parsers binary
PHP-Parser questions on Stackoverflow (View All Questions)
  • Any decent PHP parser written in PHP?
  • Finding the type of an object using PHP-Parser
  • Php-parser printer with max line length functionality
  • PHP parser for cachegrind files?
  • Best PHP parser for invalid format xml
  • youtube bbcode php parser
  • Catching PHP Parser error when using include
  • Laravel 5 composer install fails (psysh, php-parser, ext-tokenizer errors)
  • PDF Form submit - Request Payload PHP parser
  • Client-side PHP parser sought: split comments over several lines
  • How to add custom text on Markdown' Parsedown PHP parser
  • I need to generate urlencoded string in Python that is valid for PHP parser
  • Enabling both a PHP parser and an Include statement
  • Output PHP Parser Script Variables to PHP form via Sessions
  • PHP Parser Using simplexml_load_string()
  • How can we solve this composer installation issue with php-parser
  • Parse a PHP string with PHP parser
  • How to use the PHP parser only?
  • PHP Parser - Copy next line(?)
  • PHP - Parser file with a indenting
  • PHP parser: braces around variables
  • How to make the PHP parser detect/read the HTML tags in the string?
  • PHP parser with button "Show more"
  • CSS thru PHP Parser vs. PHP as CSS source
  • how to connect to php parser in netbeans platform
  • How to add external xml file to php parser
  • how to use dom php parser
  • RSS affiliate iTunes php parser
  • PHP Parser - Find String in HTML
  • MagpieRSS PHP parser error
PHP-Parser list of languages used
PHP-Parser latest release notes
v4.0.0 PHP-Parser 4.0.0

This is a new major version of the PHP-Parser library. The biggest new feature in this release is an experimental pretty-printing mode, which preserves formatting for parts of the code which have not been modified. As such, it should now be much easier to use PHP-Parser for automated code refactorings. See the pretty printer documentation for information on how to use this functionality

The following changelog lists all significant changes relative to PHP-Parser 3.1. For more information on backwards incompatible changes, please see the upgrading guide.

Added

  • Added experimental support for format-preserving pretty-printing. In this mode formatting will be preserved for parts of the code which have not been modified.
  • Added replaceNodes option to NameResolver, defaulting to true. If this option is disabled, resolved names will be added as resolvedName attributes, instead of replacing the original names.
  • Added NodeFinder class, which can be used to find nodes based on a callback or class name. This is a utility to avoid custom node visitor implementations for simple search operations.
  • Added ClassMethod::isMagic() method.
  • Added BuilderFactory methods: val() method for creating an AST for a simple value, concat() for creating concatenation trees, args() for preparing function arguments.
  • Added NameContext class, which encapsulates the NameResolver logic independently of the actual AST traversal. This facilitates use in other context, such as class names in doc comments. Additionally it provides an API for getting the shortest representation of a name.
  • Added Node::setAttributes() method.
  • Added JsonDecoder. This allows conversion JSON back into an AST.
  • Added Name methods toLowerString() and isSpecialClassName().
  • Added Identifier and VarLikeIdentifier nodes, which are used in place of simple strings in many places.
  • Added getComments(), getStartLine(), getEndLine(), getStartTokenPos(), getEndTokenPos(), getStartFilePos() and getEndFilePos() methods to Node. These provide a more obvious access point for the already existing attributes of the same name.
  • Added ConstExprEvaluator to evaluate constant expressions to PHP values.
  • Added Expr\BinaryOp::getOperatorSigil(), returning + for Expr\BinaryOp\Plus, etc.
  • Added start token offsets to comments.

Changed

  • Many subnodes that previously held simple strings now use Identifier (or VarLikeIdentifier) nodes. Please see the UPGRADE-4.0 file for an exhaustive list of affected nodes and some notes on possible impact.
  • Expression statements (expr;) are now represented using a Stmt\Expression node. Previously these statements were directly represented as their constituent expression.
  • The name subnode of Param has been renamed to var and now contains a Variable rather than a plain string.
  • The name subnode of StaticVar has been renamed to var and now contains a Variable rather than a plain string.
  • The var subnode of ClosureUse now contains a Variable rather than a plain string.
  • The var subnode of Catch now contains a Variable rather than a plain string.
  • The alias subnode of UseUse is now null if no explicit alias is given. As such, use Foo\Bar and use Foo\Bar as Bar are now represented differently. The getAlias() method can be used to get the effective alias, even if it is not explicitly given.

Removed

  • Support for running on PHP 5 and HHVM has been removed. You can however still parse code of old PHP versions (such as PHP 5.2), while running on PHP 7.
  • Removed type subnode on Class, ClassMethod and Property nodes. Use flags instead.
  • The ClassConst::isStatic() method has been removed. Constants cannot have a static modifier.
  • The NodeTraverser no longer accepts false as a return value from a leaveNode() method. NodeTraverser::REMOVE_NODE should be returned instead.
  • The Node::setLine() method has been removed. If you really need to, you can use setAttribute() instead.
  • The misspelled Class_::VISIBILITY_MODIFER_MASK constant has been dropped in favor of Class_::VISIBILITY_MODIFIER_MASK.
  • The XML serializer has been removed. As such, the classes Serializer\XML, and Unserializer\XML, as well as the interfaces Serializer and Unserializer no longer exist.
  • The BuilderAbstract class has been removed. It's functionality is moved into BuilderHelpers. However, this is an internal class and should not be used directly.
  • The Autoloader class has been removed. It is now required to use the Composer autoloader.
v3.1.5 PHP-Parser 3.1.5

Fixed

  • Fixed duplicate comment assignment in switch statements. (#469)
  • Improve compatibility with PHP-Scoper. (#477)
v4.0.0beta1 PHP-Parser 4.0.0 Beta 1

This is the first and likely last beta release for a new major version of the PHP-Parser library. The biggest new feature in this version is an experimental pretty-printing mode, which preserves formatting for parts of the code which have not been modified.

For more information on BC breaks in this release see the upgrading guide.

The following changelog only lists the changes from the previous alpha release. A complete changelog is also available.

Fixed

  • In formatting-preserving pretty printer: Fixed indentation when inserting into lists. (#466)

Added

  • In formatting-preserving pretty printer: Improved formatting of elements inserted into multi-line arrays.

Removed

  • The Autoloader class has been removed. It is now required to use the Composer autoloader.
Other projects in PHP