Static analysis tool for visualizing PHP class dependencies and call graphs.
Analyze your codebase in seconds. Explore thousands of classes interactively.
- Full call graph extraction — classes, methods, calls, instantiations, DI resolution
- Type-aware analysis — resolves constructor injection, method injection, property types,
app()container calls - Interactive WebGL viewer — powered by Sigma.js v2 + Graphology, handles 10k+ nodes smoothly
- Layer detection — auto-categorizes classes (Controller, Service, Model, Job, Action, etc.)
- Force-directed layout — ForceAtlas2 algorithm for natural clustering
- Search & filter — find classes instantly, filter by layer or edge type
- Zero dependencies viewer — single HTML file, loads via CDN, works offline with file picker
- Laravel optimized — understands Laravel patterns (service injection,
app()helper, Form Requests)
- PHP 8.1+
- A modern browser (Chrome, Firefox, Safari, Edge)
git clone git@github.com:furybee/php-deps.git
cd php-deps
composer installAlready in a PHP project with nikic/php-parser? (e.g. via PHPStan, Larastan) Skip
composer install— the tool will use your project'svendor/automatically.
php analyze.phpBy default, it scans the entire project (.) and outputs to output/graph.json.
Directories like vendor/, node_modules/, storage/ are excluded automatically.
open viewer/index.htmlLoad output/graph.json via the file picker (drag & drop supported).
If served via HTTP (
python3 -m http.server 8765 -d viewer), it auto-loadsgraph.jsonfrom the same directory.
php analyze.php [--dir=app] [--dir=app-modules] [--exclude=vendor] [--output=output/graph.json]| Option | Default | Description |
|---|---|---|
--dir |
. (entire project) |
Directories to scan (repeatable, relative to project root) |
--exclude |
vendor,node_modules,.claude,storage,bootstrap/cache |
Comma-separated directories to exclude |
--output |
output/graph.json |
Output path for the JSON graph |
# Scan the entire project (vendor/ excluded by default)
php analyze.php --dir=.
# Scan multiple directories
php analyze.php --dir=app --dir=app-modules
# Scan with custom exclusions
php analyze.php --dir=. --exclude=vendor,node_modules,tests
# Custom output path
php analyze.php --output=/tmp/graph.json| Type | Description |
|---|---|
| Class | Regular PHP classes |
| Interface | PHP interfaces |
| Trait | PHP traits |
| Enum | PHP 8.1 enums |
| Type | Example | Description |
|---|---|---|
calls |
$this->service->handle() |
Method call on a typed variable |
depends_on |
__construct(UserService $svc) |
Constructor injection |
instantiates |
new UserService() |
Direct instantiation |
resolves |
app(UserService::class) |
Laravel container resolution |
extends |
class Foo extends Bar |
Inheritance |
implements |
class Foo implements Bar |
Interface implementation |
uses_trait |
use SoftDeletes |
Trait usage |
Classes are categorized by namespace:
| Layer | Namespace Pattern |
|---|---|
| Controller | \Http\Controllers\ |
| Service | \Services\ |
| Model | \Models\ |
| Action | \Actions\ |
| Job | \Jobs\ |
| Event | \Events\ |
| Listener | \Listeners\ |
| Repository | \Repository\ |
| Command | \Console\ |
| DTO | \Dtos\ |
| ... | and 12 more |
| Feature | Description |
|---|---|
| Namespaces mode | Browse by folder/namespace, click to drill-down, breadcrumb navigation |
| Classes mode | All classes as nodes with aggregated edges |
| Full Graph mode | Classes + methods with detailed call edges |
| Search | Type / to search, autocomplete class names |
| Layer filter | Toggle visibility by layer (Controller, Service, Model...) |
| Type filter | Toggle by PHP type (Class, Abstract, Interface, Trait, Enum) |
| Edge filter | Toggle edge types (calls, extends, implements...) |
| Click | Select a node to see all its connections in the info panel |
| Hover | Highlight direct neighbors, fade everything else |
| Force Layout | Toggle ForceAtlas2 to reorganize the graph |
| Info panel | Shows dependencies, dependents, layer breakdown |
php-deps/
├── analyze.php # CLI entry point
├── composer.json # Dependencies (nikic/php-parser)
├── src/
│ ├── Analyzer.php # Orchestrator: scans files, runs 2-pass analysis
│ ├── ClassVisitor.php # Pass 1: extracts classes, methods, properties, DI
│ ├── CallVisitor.php # Pass 2: extracts method calls, instantiations
│ ├── TypeResolver.php # Resolves types from use statements, type hints
│ └── GraphBuilder.php # Builds the final JSON graph (nodes + edges)
├── viewer/
│ ├── index.html # Standalone viewer (works with file://)
│ ├── app.js # Sigma.js v2 + Graphology + ForceAtlas2
│ └── style.css # Dark theme UI
└── output/
└── graph.json # Generated graph (gitignored)
-
Pass 1 — Class extraction: Parses all PHP files with nikic/php-parser, extracts classes, methods, properties,
usestatements, constructor injection, traits, and inheritance. -
Pass 2 — Call graph: Traverses method bodies to detect
$this->prop->method()calls,ClassName::static()calls,new ClassName(), andapp(ClassName::class)container resolution. Types are resolved using the context from Pass 1. -
JSON export: Builds a graph with nodes (classes + methods) and edges (calls, dependencies, inheritance), then exports as JSON.
-
Viewer: Loads the JSON into a Graphology graph and renders it with Sigma.js v2 (WebGL). ForceAtlas2 computes the layout in real-time.
Tested on a real Laravel project:
| Metric | Value |
|---|---|
| Files scanned | 3,258 |
| Classes found | 3,245 |
| Methods found | 11,977 |
| Edges detected | 21,371 |
| Analysis time | 3.3s |
| JSON size | 10.3 MB |
| Viewer rendering | Smooth at 60fps |