rag-code-mcp

PHP Code Analyzer

Code analyzer for extracting symbols, structure, and relationships from PHP files. Includes full support for the Laravel framework. Indexes code for semantic search in Qdrant.

Status: โœ… PRODUCTION READY


๐ŸŽฏ What This Analyzer Does

The PHP analyzer parses .php files and extracts:

  1. Symbols - classes, methods, functions, interfaces, traits, constants
  2. Relationships - inheritance, implementations, Eloquent relations
  3. Metadata - PHPDoc, visibility, types, Laravel-specific
  4. Framework - Eloquent models, Controllers, Routes (Laravel)

๐Ÿ“Š Data Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   .php Files    โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚   PHP Analyzer   โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚   CodeChunks    โ”‚
โ”‚  (source code)  โ”‚     โ”‚  (VKCOM parser)  โ”‚     โ”‚  (structured)   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                          โ”‚
                        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”‚
                        โ”‚ Laravel Analyzer โ”‚โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
                        โ”‚ (Eloquent, etc.) โ”‚              โ”‚
                        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ–ผ
                                                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                                 โ”‚     Qdrant      โ”‚
                                                 โ”‚  (vector store) โ”‚
                                                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ” What We Index

1. Classes (type: "class")

<?php
namespace App\Models;

/**
 * Represents a user in the system.
 */
class User extends Model implements Authenticatable
{
    use SoftDeletes, Notifiable;
    
    protected $fillable = ['name', 'email'];
    protected $casts = ['email_verified_at' => 'datetime'];
}

Extracted information: | Field | Value | Description | |โ€”โ€”-|โ€”โ€”-|โ€”โ€”โ€”โ€”-| | name | "User" | Class name | | namespace | "App\\Models" | Namespace | | full_name | "App\\Models\\User" | Fully qualified name | | extends | "Model" | Parent class | | implements | ["Authenticatable"] | Implemented interfaces | | traits | ["SoftDeletes", "Notifiable"] | Used traits | | is_abstract | false | If abstract | | is_final | false | If final | | docstring | "Represents a user..." | PHPDoc |

2. Methods (type: "method")

/**
 * Returns the user's orders.
 * 
 * @param int $limit Maximum number of orders
 * @return Collection<Order>
 */
public function getOrders(int $limit = 10): Collection
{
    return $this->orders()->limit($limit)->get();
}

Extracted information: | Field | Value | Description | |โ€”โ€”-|โ€”โ€”-|โ€”โ€”โ€”โ€”-| | name | "getOrders" | Method name | | visibility | "public" | Visibility | | is_static | false | If static | | is_abstract | false | If abstract | | parameters | [{name: "limit", type: "int", default: "10"}] | Parameters | | return_type | "Collection" | Return type | | phpdoc.params | [{name: "limit", type: "int", desc: "..."}] | PHPDoc params | | phpdoc.return | {type: "Collection<Order>", desc: ""} | PHPDoc return |

3. Interfaces (type: "interface")

interface PaymentGateway extends Gateway
{
    public function charge(float $amount): bool;
    public function refund(string $transactionId): bool;
}

4. Traits (type: "trait")

trait Auditable
{
    public function getCreatedBy(): ?User { ... }
    public function logActivity(string $action): void { ... }
}

5. Global Functions (type: "function")

/**
 * Helper for price formatting.
 */
function format_price(float $amount, string $currency = 'USD'): string
{
    return number_format($amount, 2) . ' ' . $currency;
}

๐Ÿ”— Laravel Framework Support

Eloquent Models

class Order extends Model
{
    protected $fillable = ['user_id', 'total', 'status'];
    protected $casts = ['total' => 'decimal:2'];
    
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
    
    public function items(): HasMany
    {
        return $this->hasMany(OrderItem::class);
    }
    
    public function scopeCompleted($query)
    {
        return $query->where('status', 'completed');
    }
    
    public function getTotalFormattedAttribute(): string
    {
        return number_format($this->total, 2) . ' USD';
    }
}

Extracted Laravel metadata:

{
  "is_eloquent_model": true,
  "fillable": ["user_id", "total", "status"],
  "casts": {"total": "decimal:2"},
  "relations": [
    {"name": "user", "type": "belongsTo", "related": "User"},
    {"name": "items", "type": "hasMany", "related": "OrderItem"}
  ],
  "scopes": ["completed"],
  "accessors": ["total_formatted"]
}

Controllers

class OrderController extends Controller
{
    public function index(): View { ... }
    public function store(OrderRequest $request): RedirectResponse { ... }
    public function show(Order $order): View { ... }
}

Controller metadata:

{
  "is_controller": true,
  "is_resource_controller": true,
  "actions": ["index", "store", "show"],
  "http_methods": {
    "index": "GET",
    "store": "POST",
    "show": "GET"
  }
}

Routes

Route::get('/orders', [OrderController::class, 'index'])->name('orders.index');
Route::resource('users', UserController::class);

๐Ÿ—๏ธ File Structure

php/
โ”œโ”€โ”€ types.go              # PHP types: ClassInfo, MethodInfo, etc.
โ”œโ”€โ”€ analyzer.go           # PathAnalyzer implementation (21KB)
โ”œโ”€โ”€ api_analyzer.go       # APIAnalyzer for documentation
โ”œโ”€โ”€ phpdoc.go             # PHPDoc parser
โ”œโ”€โ”€ analyzer_test.go      # 10 CodeAnalyzer tests
โ”œโ”€โ”€ api_analyzer_test.go  # 4 APIAnalyzer tests
โ”œโ”€โ”€ parser_test.go        # 5 parser tests
โ”œโ”€โ”€ README.md             # This documentation
โ””โ”€โ”€ laravel/              # Laravel module
    โ”œโ”€โ”€ types.go          # Laravel-specific types
    โ”œโ”€โ”€ analyzer.go       # Laravel coordinator
    โ”œโ”€โ”€ adapter.go        # PathAnalyzer adapter
    โ”œโ”€โ”€ eloquent.go       # Eloquent Models analyzer
    โ”œโ”€โ”€ controller.go     # Controllers analyzer
    โ”œโ”€โ”€ routes.go         # Routes analyzer
    โ””โ”€โ”€ README.md         # Laravel documentation

๐Ÿ’ป Usage

import "github.com/doITmagic/rag-code-mcp/internal/ragcode/analyzers/php/laravel"

// For Laravel projects (recommended)
analyzer := laravel.NewAdapter()

// Analyze directories/files
chunks, err := analyzer.AnalyzePaths([]string{"./app"})

for _, chunk := range chunks {
    fmt.Printf("[%s] %s\n", chunk.Type, chunk.Name)
    if relations, ok := chunk.Metadata["relations"]; ok {
        fmt.Printf("  Relations: %v\n", relations)
    }
}

๐Ÿ”Œ Integration

Language Manager

The PHP/Laravel analyzer is automatically selected for:

Workspace Detection

File/Directory Project Type
artisan Laravel
composer.json PHP
app/Models/ Laravel
routes/web.php Laravel

๐Ÿ“‹ CodeChunk Types

Type Description Example
class PHP class class User extends Model
method Class method public function save()
function Global function function helper()
interface Interface interface Payable
trait Trait trait Auditable
const Class constant const STATUS_ACTIVE = 1
property Property protected $fillable

๐Ÿท๏ธ Complete Metadata

Class Metadata

{
  "namespace": "App\\Models",
  "extends": "Model",
  "implements": ["Authenticatable"],
  "traits": ["SoftDeletes"],
  "is_abstract": false,
  "is_final": false,
  "is_eloquent_model": true,
  "fillable": ["name", "email"],
  "relations": [...]
}

Method Metadata

{
  "class_name": "UserController",
  "visibility": "public",
  "is_static": false,
  "is_abstract": false,
  "is_final": false,
  "parameters": [...],
  "return_type": "View",
  "phpdoc": {
    "description": "...",
    "params": [...],
    "return": {...}
  }
}

๐Ÿงช Testing

# All PHP tests (19 tests)
go test ./internal/ragcode/analyzers/php/...

# Laravel only (21 tests)
go test ./internal/ragcode/analyzers/php/laravel/...

# With coverage
go test -cover ./internal/ragcode/analyzers/php/...

Results:


๐Ÿ“ฆ Dependencies


โš ๏ธ Limitations

Limitation Description
No Runtime Static analysis, doesnโ€™t execute code
Single-file Each file is analyzed independently
No Autoload Doesnโ€™t resolve Composer autoload

๐Ÿ”ฎ Future Improvements


Implemented Features

Laravel-Specific Features โœ…

  1. Eloquent Models (COMPLETE):
    • โœ… Model detection (extends Model)
    • โœ… Property extraction: $fillable, $guarded, $casts, $table, $primaryKey
    • โœ… All Relations: hasOne, hasMany, belongsTo, belongsToMany, hasManyThrough, morphTo, morphMany, morphToMany, morphedByMany
    • โœ… Foreign key & local key extraction
    • โœ… Fully-qualified name resolution with imports
    • โœ… Scopes: scopeMethodName() detection
    • โœ… Accessors/Mutators: getXxxAttribute(), setXxxAttribute()
    • โœ… SoftDeletes trait detection
  2. Controllers (COMPLETE):
    • โœ… Controller detection (extends Controller)
    • โœ… Resource controller identification (7 RESTful actions)
    • โœ… API controller detection
    • โœ… HTTP method inference from action names
    • โœ… Parameter extraction
  3. Routes (COMPLETE):
    • โœ… Route file parsing (routes/web.php, routes/api.php)
    • โœ… Route::get(), Route::post(), etc.
    • โœ… Route::match() support
    • โœ… Route::resource() expansion
    • โœ… Controller@action binding
    • โœ… Array syntax [Controller::class, 'action']

Core PHP Features โœ…

  1. Namespace Support
    • Multi-namespace per-file
    • Fully qualified names
  2. Class Analysis
    • Class declarations with extends/implements
    • Method extraction (visibility, static, abstract, final)
    • Property extraction (visibility, static, readonly, typed)
    • Class constants (visibility, value extraction)
    • Parameter and return type support
    • PHPDoc extraction (description, @param, @return)
  3. Interface Support
    • Interface declarations
    • Method signatures
    • Multiple interface extends
    • PHPDoc documentation
  4. Trait Support
    • Trait declarations
    • Methods and properties
    • PHPDoc documentation
  5. Function Analysis
    • Global functions
    • Namespaced functions
    • Parameters and return types
    • PHPDoc documentation
  6. PHPDoc Parsing
    • Description extraction
    • @param tags (type, name, description)
    • @return tags (type, description)
    • @throws, @var, @deprecated, @see, @example tags
    • Type hint merging with PHPDoc

Code Metrics


Architecture

Follows the same pattern as golang analyzer with modular framework support:

php/
โ”œโ”€โ”€ types.go              - Internal type definitions
โ”œโ”€โ”€ analyzer.go           - PathAnalyzer implementation
โ”œโ”€โ”€ api_analyzer.go       - APIAnalyzer implementation
โ”œโ”€โ”€ phpdoc.go             - PHPDoc parser (PHP-specific helper)
โ”œโ”€โ”€ analyzer_test.go      - CodeAnalyzer tests
โ”œโ”€โ”€ api_analyzer_test.go  - APIAnalyzer tests
โ”œโ”€โ”€ parser_test.go        - Parser validation tests
โ””โ”€โ”€ laravel/              - Laravel framework module (separate package)
    โ”œโ”€โ”€ types.go          - Laravel-specific types (Eloquent, Controllers, Routes)
    โ”œโ”€โ”€ analyzer.go       - Laravel framework analyzer coordinator
    โ”œโ”€โ”€ eloquent.go       - Eloquent Model analyzer
    โ”œโ”€โ”€ controller.go     - Controller analyzer
    โ””โ”€โ”€ README.md         - Laravel module documentation

Framework Modules

Framework-specific analyzers are separated into their own packages:

This modular design allows: