PHP Classes

File: README.md

Recommend this page to a friend!
  Packages of DeGraciaMathieu   PHP Dep   README.md   Download  
File: README.md
Role: Documentation
Content type: text/markdown
Description: Documentation
Class: PHP Dep
Analyse the dependencies of classes in a project
Author: By
Last change:
Date: 23 days ago
Size: 6,922 bytes
 

Contents

Class file image Download

php-dep

PHP command-line dependency analyzer. Extracts and visualizes all class relationships in a project: inheritance, interfaces, traits, injections, instantiations, static calls, docblocks.

Installation

git clone <repo>
cd php-dep
composer install
chmod +x bin/php-dep

For global access:

ln -s /absolute/path/to/bin/php-dep /usr/local/bin/php-dep

Quick start

# Analyze the current directory
./bin/php-dep analyze

# Analyze a specific project
./bin/php-dep analyze /path/to/project/src

# JSON output (for scripts, CI, jq?)
./bin/php-dep analyze src/ --format=json -q

# Zoom in on a class
./bin/php-dep analyze src/ --class='App\Service\UserService'

analyze command

php-dep analyze [<path>] [options]

<path> is optional, defaults to .

Options

| Option | Shortcut | Description | |---|---|---| | --format=text\|json | -f | Output format (default: text) | | --class=FQCN | -c | Focus on a class (full FQCN) | | --sort=alpha\|deps\|fanin | -s | Table sort: alphabetical, number of outgoing dependencies, number of incoming dependencies (default: alpha) | | --limit=N | -l | Limit output to N classes | | --exclude=dir | | Exclude a directory (can be used multiple times) | | --include-vendor | | Include the vendor/ directory in the analysis | | --skip-docblocks | | Ignore @param/@return/@throws annotations | | --quiet | -q | Suppresses the progress bar and warnings (stdout preserved) | | --verbose | -v | Show warning details |

Exit codes

| Code | Meaning | |---|---| | 0 | Success | | 1 | Parsing error(s) | | 2 | Internal error | | 3 | Invalid arguments |

Examples

Project overview

./bin/php-dep analyze src/

Displays a table with, for each class: type, number of outgoing dependencies (what it uses), incoming dependencies (what uses it), and source file.

Find the most coupled classes

# Highest dependency consumers
./bin/php-dep analyze src/ --sort=deps --limit=10

# Most used by others (high fan-in)
./bin/php-dep analyze src/ --sort=fanin --limit=10

Inspect a class

./bin/php-dep analyze src/ --class='PhpDep\Parser\PhpFileParser' -v

Displays two tables: what the class uses (outgoing dependencies) and who uses it (incoming dependencies), with the relationship type and source line.

JSON pipeline with jq

# Count classes
./bin/php-dep analyze src/ -f json -q | jq '.meta.class_count'

# List all inheritance relationships
./bin/php-dep analyze src/ -f json -q | jq '[.edges[] | select(.type == "extends")]'

# Find classes with no dependants (leaves)
./bin/php-dep analyze src/ -f json -q | jq '[.classes[] | select(.dependants | length == 0) | .fqcn]'

# Find dependencies of a specific class
./bin/php-dep analyze src/ -f json -q | jq '.classes[] | select(.fqcn == "App\\Service\\UserService") | .dependencies'

Exclude directories

./bin/php-dep analyze . --exclude=tests --exclude=fixtures --exclude=migrations

Analysis without vendor

By default, vendor/ is excluded from the analysis but third-party classes appear as external nodes in the graph. No additional option is needed to ignore them entirely.

To analyze the vendor itself:

./bin/php-dep analyze . --include-vendor

JSON output structure

{
  "meta": {
    "version": "1.0",
    "generated_at": "2026-02-26T10:00:00+00:00",
    "analyzed_path": "/path/to/project",
    "file_count": 42,
    "class_count": 38,      // internal nodes only
    "node_count": 95,       // internal + external (vendor, built-in)
    "edge_count": 312,
    "warning_count": 2
  },
  "classes": [
    {
      "fqcn": "App\\Service\\UserService",
      "type": "class",      // class | interface | trait | enum
      "file": "/path/to/UserService.php",
      "line": 12,
      "dependencies": ["App\\Repository\\UserRepository", "Psr\\Log\\LoggerInterface"],
      "dependants":   ["App\\Controller\\UserController"]
    }
  ],
  "edges": [
    {
      "source":     "App\\Service\\UserService",
      "target":     "App\\Repository\\UserRepository",
      "type":       "param_type",   // see relationship types below
      "confidence": "certain",      // certain | high | medium | low
      "file":       "/path/to/UserService.php",
      "line":       23,
      "metadata":   {}
    }
  ],
  "warnings": [
    {
      "type":    "dynamic_instantiation",
      "file":    "/path/to/Factory.php",
      "line":    45,
      "message": "Dynamic instantiation: new $variable()"
    }
  ]
}

Relationship types (edge.type)

Tier 1 ? Maximum certainty (AST)

| Type | Description | |---|---| | extends | Class or interface inheritance | | implements | Interface implementation | | uses_trait | Trait usage | | param_type | Type hint on a method parameter | | return_type | Method return type | | property_type | Class property type | | instantiates | new Foo() | | static_call | Foo::method() | | static_property | Foo::$prop | | const_access | Foo::CONST | | instanceof | $x instanceof Foo | | catches | catch (FooException $e) |

Tier 2 ? High confidence (docblocks)

Extracted from @param, @return, @var, @throws. Confidence: high.

| Type | Source | |---|---| | docblock_param | @param FooType $x | | docblock_return | @return FooType | | docblock_var | @var FooType | | docblock_throws | @throws FooException |

Confidence levels

| Value | Meaning | |---|---| | certain | Structural relationship guaranteed by the AST | | high | Docblock, highly probable | | medium | Ambiguous pattern (instanceof) | | low | Dynamic pattern |

Warnings

| Type | Trigger | |---|---| | dynamic_instantiation | new $variable() ? class unknown at static analysis time | | dynamic_call | Unresolvable dynamic call | | parse_error | Invalid or unreadable PHP file |

Warnings are printed to stderr. The JSON output includes them in warnings[]. With -v, the text output lists them at the end of the report.

How it works

  • Discovery: `git ls-files` if inside a git repository, otherwise `RecursiveDirectoryIterator`. The `vendor/`, `node_modules/`, and `.git/` directories are excluded by default.
  • Parsing: nikic/PHP-Parser v5. The `NameResolver` runs first in the traverser: all downstream names are resolved FQCNs.
  • Docblocks: phpstan/phpdoc-parser for `@param`, `@return`, `@var`, `@throws`.
  • Memory: each file's AST is freed immediately after extraction (streaming). Only one AST in memory at a time.
  • Vendor: in `boundary` mode (default), vendor classes are `external` nodes (leaves) ? their files are not analyzed.

Requirements

  • PHP >= 8.2
  • Composer