tree-sitter-php
tree-sitter-php provides the PHP grammar for the tree-sitter parsing system. It enables incremental parsing to build concrete syntax trees for PHP source code, facilitating advanced code analysis, linting, and editor features. The library is actively maintained, with version 0.24.1 being the latest, and receives frequent updates to support new PHP language features.
Warnings
- gotcha Tree-sitter grammars are C libraries and typically require compilation. While `tree-sitter-php` provides pre-compiled binary wheels for common platforms, environments without a suitable C compiler or for non-standard architectures might encounter installation failures, requiring manual compilation.
- breaking The PHP grammar is continuously updated to support new language features (e.g., PHP 8.1+, 8.4, 8.5). Older versions of the `tree-sitter-php` grammar might fail to correctly parse newer PHP syntax, leading to incomplete or incorrect syntax trees.
- gotcha Parsing `.php` files containing a mix of PHP and HTML can sometimes lead to issues or unexpected parsing behavior, especially when integrating with editor plugins that use multiple tree-sitter parsers (e.g., HTML and PHP). Historically, this led to a split into `php` and `php_only` parsers.
Install
-
pip install tree-sitter-php
Imports
- language
import tree_sitter_php
- Language, Parser
from tree_sitter import Language, Parser
Quickstart
from tree_sitter import Language, Parser
import tree_sitter_php
# Load the PHP grammar
PHP_LANGUAGE = Language(tree_sitter_php.language())
parser = Parser(PHP_LANGUAGE)
php_code = b'''
<?php
class MyClass {
public function __construct(private string $name) {}
public function greet(): string {
return "Hello, " . $this->name . "!";
}
}
$obj = new MyClass("World");
echo $obj->greet();
?>
'''
# Parse the code
tree = parser.parse(php_code)
# Get the root node of the syntax tree
root_node = tree.root_node
print(f"Root node type: {root_node.type}")
print(f"Number of children: {len(root_node.children)}")
# Example: Find a class_declaration node
for child in root_node.children:
if child.type == 'declaration_list': # often wrappers around class/function
for decl in child.children:
if decl.type == 'class_declaration':
print(f"Found class: {decl.child_by_field_name('name').text.decode('utf8')}")
break
# You can also use queries for more specific pattern matching
query = PHP_LANGUAGE.query("""
(class_declaration name: (name) @class-name)
(method_declaration name: (name) @method-name)
""")
captures = query.captures(root_node)
for node, name in captures:
print(f"Captured: {name.replace('-', '_')}: {node.text.decode('utf8')}")