# How code-review-graph Handles PHP and Laravel Framework-Specific Parsing

> Discover how code-review-graph parses PHP and Laravel with Tree-sitter and Composer mappings. Understand framework-specific code relationships for better analysis.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: deep-dive
- Published: 2026-07-26

---

**The `code-review-graph` repository processes PHP using Tree-sitter grammar and enriches Laravel applications with framework-specific edges by resolving Composer PSR-4 mappings, parsing Blade templates, and extracting route-to-controller relationships.**

The `code-review-graph` tool provides comprehensive **PHP and Laravel framework-specific parsing** capabilities that transform raw source code into navigable knowledge graphs. By combining Tree-sitter AST traversal with Composer autoloading logic and Laravel-specific heuristics, the parser captures everything from basic class dependencies to complex Eloquent model relationships.

## Core PHP Parsing Architecture

The foundation of PHP support resides in the `CodeParser` class within [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py). When processing PHP files, the parser loads a Tree-sitter grammar registered under the `"php"` key and walks the syntax tree to extract namespaces, imports, class definitions, and method calls.

### Composer PSR-4 Autoloading Resolution

To bridge the gap between PHP namespaces and file system paths, the implementation uses dedicated Composer helpers. The `_read_php_composer_psr4` function (defined at line 551) reads the repository's [`composer.json`](https://github.com/tirth8205/code-review-graph/blob/main/composer.json) and extracts the `"autoload"` and `"autoload-dev"` PSR-4 mappings, caching these for repeated lookups.

The `_resolve_php_composer_module` function (line 12684) consumes these cached mappings to translate fully-qualified class names into concrete file paths. This enables the parser to resolve `use App\Models\User` statements to their actual source files even when the namespace prefix maps to a subdirectory.

### Namespace and Import Extraction

The parser captures file-level namespace context through `_php_namespace_name` (line 10549), which extracts the declared namespace declaration. For import statements, `_php_import_bindings` (line 10558) builds a mapping from short class names to fully-qualified names by analyzing `use` declarations at the top of each file.

When resolving class references—including imported aliases and relative names—the system delegates to `_php_resolve_class_reference` (line 10616). This ensures that a reference to `new User()` correctly resolves to `App\Models\User` based on the file's explicit imports and declared namespace.

## Laravel Framework Extensions

Beyond standard PHP analysis, `code-review-graph` activates Laravel-specific processing when encountering [`.blade.php`](https://github.com/tirth8205/code-review-graph/blob/main/.blade.php) files or Laravel-specific AST patterns. This specialized layer adds framework semantics to the generic PHP walk.

### Blade Template Recognition

Laravel's Blade templating engine receives dedicated handling through the `_extract_php_laravel_edges` entry point (line 10403). This function recursively walks the PHP AST and delegates to framework-specific walkers that understand Laravel's architectural patterns.

The `_walk_php_laravel_sequence` function (line 10410) follows statement sequences that may contain route definitions or controller method calls, while `_walk_php_laravel_node` processes individual AST nodes to identify classes, methods, and framework-specific function calls.

### Route-to-Controller Resolution

For HTTP routing analysis, the parser identifies `Route::get`, `Route::post`, and similar static method calls through `_php_route_handler` (line 10667). This function creates **CALLS** edges connecting the route definition node to the target controller method, enabling the knowledge graph to represent the application's HTTP request dispatch flow.

### Eloquent Model Relationship Mapping

The system detects Eloquent model inheritance via `_php_class_extends_eloquent_model` (line 10637), which identifies classes extending `Model` and analyzes relationship methods such as `hasMany`, `belongsTo`, and `hasOne`. These generate **HAS_ONE** or **HAS_MANY** edges in the graph, linking related model classes to represent the application's database relationship structure.

### Laravel-Specific Method Call Resolution

For general Laravel method calls—including `Controller::method` invocations and facades—the parser uses `_php_laravel_caller` (line 10767) to resolve targets and create appropriate graph edges that reflect the framework's magic method resolution.

## Security and Repository Boundaries

When resolving Composer mappings, `code-review-graph` enforces strict repository boundaries through `_php_repository_boundary` (line 13084). This safety mechanism discards any mappings that point outside the repository root and ignores symlinked or absolute paths that would escape the codebase, preventing path traversal vulnerabilities and false positives from system-wide Composer dependencies.

## Practical Implementation Examples

Resolving a Composer-mapped class:

```python
from code_review_graph.parser import CodeParser

parser = CodeParser(repo_path)  # repo_path points to a Laravel project

edges = parser.parse_file(repo_path / "app/Models/User.php")

# edges now contain IMPORTS_FROM for any `use` statements and,

# if the file defines a model extending Eloquent, HAS_ONE/HAS_MANY edges to related models

```

Extracting Laravel routes:

```python
parser = CodeParser(repo_path)
edges = parser.parse_file(repo_path / "routes/web.php")

# The graph includes CALLS edges such as:

# Route::get('/users', 'UserController@index') → edge to UserController::index method

```

The comprehensive test suite in [`tests/test_php_laravel.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_php_laravel.py) validates PSR-4 resolution accuracy and Laravel-specific edge extraction behaviors.

## Summary

- `code-review-graph` uses Tree-sitter with a dedicated PHP grammar in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) for syntactic analysis
- Composer PSR-4 mappings are cached and resolved via `_read_php_composer_psr4` (line 551) and `_resolve_php_composer_module` (line 12684)
- PHP imports and namespaces are tracked through `_php_import_bindings` (line 10558) and `_php_namespace_name` (line 10549)
- Laravel analysis activates for [`.blade.php`](https://github.com/tirth8205/code-review-graph/blob/main/.blade.php) files via `_extract_php_laravel_edges` (line 10403)
- Route handlers create **CALLS** edges using `_php_route_handler` (line 10667)
- Eloquent relationships generate **HAS_ONE** and **HAS_MANY** edges via `_php_class_extends_eloquent_model` (line 10637)
- Repository security is enforced by `_php_repository_boundary` (line 13084) to prevent path traversal

## Frequently Asked Questions

### How does code-review-graph resolve PHP class names to file paths?

The parser reads the [`composer.json`](https://github.com/tirth8205/code-review-graph/blob/main/composer.json) PSR-4 autoloading configuration using `_read_php_composer_psr4`, caches these mappings, and resolves fully-qualified class names to file paths through `_resolve_php_composer_module`. This allows accurate resolution of imported classes regardless of namespace prefix depth.

### What Laravel-specific relationships does the graph capture?

The parser creates **CALLS** edges for route-to-controller mappings through `_php_route_handler`, **HAS_ONE** and **HAS_MANY** edges for Eloquent model relationships via `_php_class_extends_eloquent_model`, and handles Blade template dependencies through the `_extract_php_laravel_edges` pipeline.

### How does the parser handle PHP `use` statements and imports?

The `_php_import_bindings` function extracts `use` declarations to build a short-name to fully-qualified-name mapping, while `_php_resolve_class_reference` resolves class references—including imported aliases and relative names—to their canonical fully-qualified names based on file context.

### What security measures prevent the parser from accessing files outside the repository?

The `_php_repository_boundary` function (line 13084) validates all resolved paths against the repository root, discarding mappings that point outside the codebase and ignoring symlinks or absolute paths that would escape the repository boundary, ensuring safe analysis of untrusted codebases.