PHPackages                             amoifr/phpquality-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. amoifr/phpquality-bundle

ActiveSymfony-bundle[Testing &amp; Quality](/categories/testing)

amoifr/phpquality-bundle
========================

Symfony bundle for PHP static code analysis, metrics, and quality reports

v2.0.0(1mo ago)320↓82.5%MITPHPPHP &gt;=8.3CI passing

Since Mar 25Pushed 1mo agoCompare

[ Source](https://github.com/Amoifr/phpquality)[ Packagist](https://packagist.org/packages/amoifr/phpquality-bundle)[ Docs](https://github.com/amoifr/PhpQuality)[ RSS](/packages/amoifr-phpquality-bundle/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (26)Versions (12)Used By (0)

PhpQuality - PHP Static Code Analyzer
=====================================

[](#phpquality---php-static-code-analyzer)

> PHP static analyzer available as a Symfony Bundle and Docker image, designed to replace `phpmetrics/phpmetrics` (now unmaintained). Analyzes your PHP code and generates detailed reports on complexity, maintainability, coupling, architecture, and test coverage.

**Version:** 2.0.0 **Author:** [Pascal CESCON](https://moi.ruedesjasses.fr)**GitHub:** [amoifr/PhpQuality](https://github.com/amoifr/PhpQuality)

---

Migrating from 1.x
------------------

[](#migrating-from-1x)

Version **2.0** sharply reduces false positives in architectural and SOLID analysis on framework projects. If you are upgrading from 1.x:

- The Laravel preset (`--type=laravel`) is now a real preset: `*Action` is `Application` (not Controller), `ServiceProvider` is `Wiring` (exempt from layer-violation reporting), and Eloquent / Carbon / facades / queue traits are excluded from the DIP ratio.
- DIP only counts type-hinted, injectable dependencies. Old DIP scores are not directly comparable.
- A `phpquality.json` file at the project root can override layer rules, add to whitelists, and pin a baseline.
- `--generate-baseline=phpquality.baseline.json` then `--baseline=…` lets you adopt the tool on existing projects without rewriting them.

See [`CHANGELOG.md`](CHANGELOG.md) for the full breaking changes list and detailed migration notes.

---

Installation
------------

[](#installation)

### As a Symfony Bundle

[](#as-a-symfony-bundle)

```
composer require amoifr/phpquality-bundle
```

Then register the bundle in `config/bundles.php`:

```
return [
    // ...
    PhpQuality\PhpQualityBundle::class => ['all' => true],
];
```

Run the analysis:

```
php bin/console phpquality:analyze --source=src/
```

### Using Docker

[](#using-docker)

```
# Pull the pre-built image
docker pull amoifr13/phpquality

# Run analysis
docker run --rm -v $(pwd):/project amoifr13/phpquality --source=/project/src
```

---

Features
--------

[](#features)

### Code Metrics v0.1

[](#code-metrics-v01)

MetricDescription**LOC**Lines of Code (total, CLOC without comments, LLOC logical)**CCN**McCabe Cyclomatic Complexity per method**MI**Maintainability Index (0-100, higher = better)**LCOM**Lack of Cohesion of Methods (0-1, lower = better)**Halstead**Volume, Difficulty, Effort, Estimated Bugs### Architecture Analysis v0.4

[](#architecture-analysis-v04)

FeatureDescription**Layer Detection**Auto-detection of layers (Controller, Application, Domain, Infrastructure)**Layer Violations**Detection of forbidden dependencies (e.g., Domain → Infrastructure)**SOLID Violations**Detection of SRP, OCP, ISP, DIP violations**Circular Dependencies**Detection of dependency cycles using Tarjan's algorithm**Dependency Graph**Interactive D3.js visualization**Dependency Matrix**Matrix view of dependencies between layers**Architecture Score**Global score 0-100 based on violations### Test Coverage v1.1

[](#test-coverage-v11)

FeatureDescription**Line Coverage**Percentage of code lines covered by tests**Method Coverage**Percentage of methods tested**Class Coverage**Percentage of classes tested**Package Coverage**Coverage analysis by namespace/package**File Coverage**Coverage details for each file**Coverage Grade**A-F grade based on coverage percentage### Hall of Fame / Hall of Shame v0.3

[](#hall-of-fame--hall-of-shame-v03)

FeatureDescription**Git Blame Analysis**Per-author statistics via git blame**Composite Score**Score combining MI and CCN per contributor**Hall of Fame**Top contributors in code quality**Hall of Shame**Contributors whose code needs attention### HTML Reports v0.2

[](#html-reports-v02)

Multi-page HTML report includes:

PageContent**Dashboard**Overview with distribution charts**Documentation**Detailed explanation of each metric**CCN**Complexity details per method**MI**Maintainability index per class**LCOM**Cohesion per class**LOC**Lines of code per file**Halstead**Advanced complexity metrics**Analysis**Multi-dimensional analysis, code tree, contributors**Architecture**Dependency graph, SOLID violations, dependency matrix**Coverage**Test coverage per file and package**Dependencies**Composer dependency analysis### Supported Project Types

[](#supported-project-types)

PhpQuality adapts its analysis based on project type. Use `--type=` to specify the framework:

TypeLabelDescription`php`PHP (Generic)Generic PHP analysis (default)`symfony`SymfonySymfony Framework (Controllers, Services, Repositories...)`laravel`LaravelLaravel Framework (Eloquent Models, Middleware, Jobs...)`prestashop`PrestaShopPrestaShop E-commerce (Modules, ObjectModel, Hooks...)`magento`Magento 2Magento 2 E-commerce (Plugins, Observers, Blocks...)`wordpress`WordPressWordPress CMS (Plugins, Themes, Hooks...)`woocommerce`WooCommerceWooCommerce Extension (Gateways, Shipping...)`drupal`DrupalDrupal CMS (Modules, Plugins, Forms...)`joomla`JoomlaJoomla CMS (Components, Modules, Plugins...)`typo3`TYPO3TYPO3 CMS (Extensions, ViewHelpers...)`sulu`Sulu CMSSulu CMS (Symfony-based, Content Types...)`sylius`SyliusSylius E-commerce (Processors, Calculators...)`codeigniter`CodeIgniterCodeIgniter Framework (Controllers, Models...)`cakephp`CakePHPCakePHP Framework (Tables, Behaviors, Cells...)Each type defines:

- Directories to automatically exclude
- Class categorization patterns
- Recommended quality thresholds

---

Usage with Docker
-----------------

[](#usage-with-docker)

### Quick Analysis

[](#quick-analysis)

```
# Analysis with auto-detection of project type
docker run --rm \
  -v $(pwd):/project \
  -v $(pwd)/reports:/reports \
  amoifr13/phpquality \
  --source=/project/src --report-html=/reports
```

### Specify Project Type

[](#specify-project-type)

```
# Symfony project
docker run --rm \
  -v $(pwd):/project \
  -v $(pwd)/reports:/reports \
  amoifr13/phpquality \
  --source=/project/src --type=symfony --report-html=/reports

# PrestaShop project
docker run --rm \
  -v $(pwd):/project \
  amoifr13/phpquality \
  --source=/project/modules/mymodule --type=prestashop

# WordPress project
docker run --rm \
  -v $(pwd):/project \
  amoifr13/phpquality \
  --source=/project/wp-content/plugins/myplugin --type=wordpress
```

### With Test Coverage

[](#with-test-coverage)

```
# First generate coverage report with PHPUnit
./vendor/bin/phpunit --coverage-clover coverage.xml

# Then analyze with coverage
docker run --rm \
  -v $(pwd):/project \
  -v $(pwd)/reports:/reports \
  amoifr13/phpquality \
  --source=/project/src --coverage=/project/coverage.xml --report-html=/reports
```

### With Hall of Fame/Shame (git blame)

[](#with-hall-of-fameshame-git-blame)

```
docker run --rm \
  -v $(pwd):/project \
  -v $(pwd)/reports:/reports \
  amoifr13/phpquality \
  --source=/project/src --git-blame --report-html=/reports
```

### Display Summary in Terminal Only

[](#display-summary-in-terminal-only)

```
docker run --rm \
  -v $(pwd):/project \
  amoifr13/phpquality \
  --source=/project/src --no-html
```

### JSON Export

[](#json-export)

```
docker run --rm \
  -v $(pwd):/project \
  -v $(pwd)/reports:/reports \
  amoifr13/phpquality \
  --source=/project/src --json=/reports/metrics.json
```

### List Available Types

[](#list-available-types)

```
docker run --rm amoifr13/phpquality --list-types
```

### CI Mode (Fail on Violations)

[](#ci-mode-fail-on-violations)

```
docker run --rm \
  -v $(pwd):/project \
  amoifr13/phpquality \
  --source=/project/src --type=symfony --fail-on-violation
```

---

Command Options
---------------

[](#command-options)

OptionDescription`--source`, `-s`Source directory to analyze (required)`--type`, `-t`Project type (`auto`, `symfony`, `laravel`, etc.)`--report-html`Output directory for HTML report`--json`Output file for JSON report`--exclude`, `-x`Additional directories to exclude (repeatable)`--no-html`Skip HTML report generation`--fail-on-violation`Exit with error if violations are detected`--git-blame`Enable git blame analysis for Hall of Fame/Shame (slower)`--coverage`, `-c`Path to Clover XML coverage file`--project-name`, `-p`Project name to display in report titles`--lang`, `-l`Report language (en, fr, de, es, it, pt, nl, pl, ru, ja, zh, ko...)`--list-types`List all available project types`--list-langs`List all available languages`--wizard`, `-w`Interactive wizard for guided configuration`--config`Path to a project configuration file (default: `./phpquality.json`)`--baseline`Path to a baseline file. Violations listed in the baseline are filtered out.`--generate-baseline`Write a baseline file with all current violations and exit successfully.### Project configuration file (`phpquality.json`, since 2.0)

[](#project-configuration-file-phpqualityjson-since-20)

Drop a `phpquality.json` at the root of the project being analyzed to extend the framework preset:

```
{
  "layers": {
    "rules": [
      { "match": "App\\Custom\\**", "layer": "Application" }
    ]
  },
  "wiring":           { "patterns": ["**ServiceProvider"] },
  "abstractionRatio": { "ignore":   ["App\\Models\\**"] },
  "ignore":           { "violations": ["solid.dip:App\\Foo\\Bar"] },
  "baseline":         "phpquality.baseline.json"
}
```

Project rules under `layers.rules` are **prepended** to the framework preset (first match wins). The other lists are **unioned** with the preset.

### Suppressing a violation locally

[](#suppressing-a-violation-locally)

```
/**
 * @phpquality-ignore solid.dip — this service intentionally wires concretes.
 */
final class FooService { /* … */ }
```

Codes: `solid.srp`, `solid.dip`, `solid.isp`, `architecture.layer`.

### Baseline workflow (CI-friendly)

[](#baseline-workflow-ci-friendly)

```
# 1. Pin existing violations as accepted (do NOT fail the build)
phpquality:analyze --source=app --type=laravel \
    --generate-baseline=phpquality.baseline.json

# 2. Subsequent runs only report NEW violations
phpquality:analyze --source=app --type=laravel \
    --baseline=phpquality.baseline.json --fail-on-violation
```

---

Architecture
------------

[](#architecture)

```
phpquality/
├── src/                           # Symfony Bundle
│   ├── PhpQualityBundle.php
│   ├── DependencyInjection/
│   ├── Analyzer/
│   │   ├── Ast/
│   │   │   ├── AstParser.php
│   │   │   └── Visitor/
│   │   ├── Architecture/
│   │   ├── ProjectType/
│   │   ├── Result/
│   │   ├── FileAnalyzer.php
│   │   └── ProjectAnalyzer.php
│   ├── Command/
│   │   └── AnalyzeCommand.php
│   ├── Report/
│   │   ├── HtmlReportGenerator.php
│   │   └── ConsoleReportGenerator.php
│   └── Resources/
│       ├── config/services.yaml
│       ├── views/report/
│       └── translations/
├── tests/
├── docker/
│   ├── app/                       # Minimal Symfony skeleton
│   ├── Dockerfile
│   └── entrypoint.sh
└── composer.json

```

---

Tech Stack
----------

[](#tech-stack)

ComponentTechnologyLanguagePHP 8.3FrameworkSymfony 7.xAST Parser[nikic/php-parser](https://github.com/nikic/PHP-Parser)HTML RenderingTwig + Chart.js + D3.jsCLISymfony ConsoleBase Image`php:8.3-cli-alpine`Dependency ManagementComposer---

Metrics Interpretation
----------------------

[](#metrics-interpretation)

### Maintainability Index (MI)

[](#maintainability-index-mi)

ScoreRatingInterpretation85-100AHighly maintainable65-84BModerately maintainable40-64CDifficult to maintain20-39DVery difficult to maintain0-19FUnmaintainable### Cyclomatic Complexity (CCN)

[](#cyclomatic-complexity-ccn)

ScoreRatingInterpretation1-4ALow complexity5-7BModerate complexity8-10CHigh complexity11-15DVery high complexity16+FExcessive complexity### Lack of Cohesion (LCOM)

[](#lack-of-cohesion-lcom)

ScoreRatingInterpretation0-0.2AExcellent cohesion0.2-0.4BGood cohesion0.4-0.6CModerate cohesion0.6-0.8DLow cohesion0.8-1.0FVery low cohesion### Architecture Score

[](#architecture-score)

ScoreRatingInterpretation85-100AExemplary architecture70-84BGood architecture50-69CAcceptable architecture30-49DArchitecture needs improvement0-29FCritical architecture### Test Coverage

[](#test-coverage)

ScoreRatingInterpretation80-100%AExcellent coverage60-79%BGood coverage40-59%CModerate coverage20-39%DLow coverage0-19%FCritical coverage### Layer Rules (Clean Architecture)

[](#layer-rules-clean-architecture)

PhpQuality automatically detects layers and checks dependency rules:

LayerCan depend onCannot depend on**Domain**nothingApplication, Infrastructure, Controller**Application**DomainInfrastructure, Controller**Infrastructure**Domain, ApplicationController**Controller**Domain, Application, Infrastructure-### Detected SOLID Violations

[](#detected-solid-violations)

PrincipleDetectionThresholds**SRP** (Single Responsibility)Classes with too many methods, dependencies, and lines of codeLCOM &gt; 0.7, methods &gt; 20, deps &gt; 15**OCP** (Open/Closed)Numerous switch/match on typeComing soon**ISP** (Interface Segregation)Interfaces with too many methods&gt; 5 methods**DIP** (Dependency Inversion)Concrete/abstract dependency ratioratio &lt; 0.5---

CI/CD Integration
-----------------

[](#cicd-integration)

### GitHub Actions

[](#github-actions)

```
name: Code Quality

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          coverage: xdebug

      - name: Install dependencies
        run: composer install

      - name: Run tests with coverage
        run: ./vendor/bin/phpunit --coverage-clover coverage.xml

      - name: Run PhpQuality
        run: |
          docker run --rm \
            -v ${{ github.workspace }}:/project \
            amoifr13/phpquality \
            --source=/project/src \
            --coverage=/project/coverage.xml \
            --fail-on-violation \
            --json=/project/phpquality.json

      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: phpquality-report
          path: phpquality.json
```

### GitLab CI

[](#gitlab-ci)

```
code-quality:
  image: amoifr13/phpquality
  script:
    - phpquality:analyze --source=/builds/$CI_PROJECT_PATH/src --coverage=/builds/$CI_PROJECT_PATH/coverage.xml --fail-on-violation
  artifacts:
    reports:
      codequality: phpquality.json
```

---

Roadmap
-------

[](#roadmap)

- **v0.1** - Basic analysis: LOC, CCN, MI, LCOM + HTML report + project types
- **v0.2** - Multi-page HTML report with metrics documentation
- **v0.3** - Multi-dimensional analysis, code tree, Hall of Fame/Shame, Composer dependency analysis
- **v0.4** - Architecture analysis (layers, SOLID violations, D3.js dependency graph, circular dependencies)
- **v1.0** - Git blame option, custom project name
- **v1.1** - Test coverage analysis (Clover XML)
- **v1.2** - Symfony Bundle architecture
- **v1.3** - Configurable CI rules, custom thresholds
- **v1.4** - PDF export, version comparison
- **v2.0** - Interactive web interface, analysis history

---

Contributing
------------

[](#contributing)

Contributions are welcome! To propose a missing metric or fix a calculation:

1. Fork the repository
2. Create a branch: `git checkout -b feature/my-metric`
3. Commit your changes
4. Open a Pull Request

---

License
-------

[](#license)

MIT - see [LICENSE](./LICENSE) file.

---

References
----------

[](#references)

- [phpmetrics/PhpMetrics (GitHub)](https://github.com/phpmetrics/PhpMetrics) - original project
- [nikic/php-parser](https://github.com/nikic/PHP-Parser)
- [Halstead complexity measures (Wikipedia)](https://en.wikipedia.org/wiki/Halstead_complexity_measures)
- [Cyclomatic complexity (Wikipedia)](https://en.wikipedia.org/wiki/Cyclomatic_complexity)
- [Software package metrics - Robert Martin (Wikipedia)](https://en.wikipedia.org/wiki/Software_package_metrics)
- [Deptrac (GitHub)](https://github.com/qossmic/deptrac) - inspiration for layer analysis
- [PHP Insights (GitHub)](https://github.com/nunomaduro/phpinsights) - inspiration for quality analysis
- [SOLID principles (Wikipedia)](https://en.wikipedia.org/wiki/SOLID)
- [Clean Architecture - Robert C. Martin](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
- [PHPUnit Code Coverage](https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html)

###  Health Score

43

—

FairBetter than 90% of packages

Maintenance90

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Recently: every ~10 days

Total

10

Last Release

49d ago

Major Versions

v1.6.0 → v2.0.02026-05-06

### Community

Maintainers

![](https://www.gravatar.com/avatar/277e4b07fc014cb5ef471444ba29b187832005ca7a8103d499218bbd4c89f3ed?d=identicon)[Amoifr](/maintainers/Amoifr)

---

Top Contributors

[![Amoifr](https://avatars.githubusercontent.com/u/31698966?v=4)](https://github.com/Amoifr "Amoifr (43 commits)")

---

Tags

phpstatic analysisMetricscode qualitySymfony Bundlecomplexityphpmetrics

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/amoifr-phpquality-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/amoifr-phpquality-bundle/health.svg)](https://phpackages.com/packages/amoifr-phpquality-bundle)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.5M373](/packages/easycorp-easyadmin-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M196](/packages/sulu-sulu)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.4M517](/packages/shopware-core)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9317.2k55](/packages/open-dxp-opendxp)[chameleon-system/chameleon-base

The Chameleon System core.

1027.9k4](/packages/chameleon-system-chameleon-base)[aeliot/todo-registrar

Register TODOs from source code in issue tracker

153.0k](/packages/aeliot-todo-registrar)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
