Skip to content
CAI
Software that uses CAICheck a score

nunomaduro/phpinsights

74.3

Strong · 19 September 2026

8.8k

lines of production code

PHP

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a static analysis tool for PHP codebases that evaluates code quality, complexity, architecture, and style. It automatically detects popular frameworks like Laravel, Symfony, and WordPress to apply tailored inspection rules and exclusions. The tool provides detailed metrics and supports multiple output formats for CI/CD integration, while also offering an auto-fix feature to correct code style issues.

Features

Add Laravel Artisan command for PHP Insights

Introduces a new \InsightsCommand\ class that allows users to run the PHP Insights analysis tool directly via the Laravel Artisan CLI using the \php artisan insights\ command. The command automatically resolves the configuration file path (defaulting to \config/insights.php\), handles configuration validation errors with user-friendly output, and displays funding messages to the error output stream upon completion.

src/Application/Adapters/Laravel/Commands · high confidence

Add WordPress-specific code analysis preset

A new preset for WordPress projects has been introduced, automatically activating when the project depends on 'johnpbloch/wordpress' or 'roots/wordpress'. This preset configures the static analysis tool to exclude standard WordPress directories (such as 'web/wp', 'web/app/plugins', and 'web/app/uploads') and enforces stricter coding standards by forbidding the use of 'eval', 'error\_log', and 'print\_r' functions, providing a tailored experience for WordPress-based codebases.

src/Application/Adapters/WordPress · high confidence

Added Magento 2 preset configuration

A new preset named 'magento2' is now available for projects using Magento 2 (Community or Enterprise editions). This preset automatically applies when the project includes specific Magento Composer packages and extends the default configuration with exclusions for standard Magento directories (such as bin, dev, generated, lib, pub, setup, var) and key entry files.

src/Application/Adapters/Magento2 · high confidence

Added Symfony and Yii framework presets

New preset configurations have been introduced for the Symfony and Yii frameworks, allowing the tool to automatically detect and apply framework-specific inspection rules. The Symfony preset excludes common directories like \var\ and \public\, and configures PHP\_CodeSniffer to flag the use of \dd\ and \dump\ functions, while the Yii preset excludes directories such as \web\ and \runtime\. These presets are automatically applied when the respective framework packages are detected in the project's dependencies.

src/Application/Adapters/Symfony · high confidence

Added complexity metrics for average cyclomatic complexity

A new Complexity metric class has been introduced to provide insights into code complexity. It calculates the average cyclomatic complexity per method and triggers specific insights when cyclomatic complexity is deemed too high at the class, method, or average method levels.

src/Domain/Metrics/Complexity · high confidence

Introduces comprehensive PHP code style and syntax inspection rules

The new \Style\ metric class in \src/Domain/Metrics/Style\ now enforces a wide range of coding standards by integrating numerous sniffs from PHP\_CodeSniffer (covering PSR-1, PSR-2, PSR-12, and Generic standards) and fixers from PHP-CS-Fixer. This change adds checks for syntax correctness, file structure (such as closing tags, line endings, and byte order marks), naming conventions, spacing, and import ordering, ensuring that the codebase adheres to consistent formatting and style guidelines.

src/Domain/Metrics/Style · high confidence

Introduces new Code metrics for Classes, Code, Comments, Functions, and Globally

The tool now provides detailed metrics for code structure and style, including class statistics (lines, average/max length), general code insights (control structures, variable usage, type hints), comment quality (docblocks, TODOs), function metrics (length, unused parameters), and global constant usage. These metrics are powered by a comprehensive set of PHP\_CodeSniffer sniffs, Slevomat Coding Standard rules, and PhpCsFixer fixers, replacing the previous global constants analysis with a broader view of code quality.

src/Domain/Metrics/Code · high confidence

Introduces standalone PHP executable for PHP Insights

A new executable script \bin/phpinsights\ has been added to the project, allowing users to run the tool directly via the command line. This script bootstraps the application kernel, loads console commands from the configuration, and initializes the Symfony Console application with the default command set to 'analyse'. It also includes a compatibility fix for the \T\_MATCH\ constant to prevent conflicts between php-codesniffer and php-cs-fixer v3.

bin · high confidence

New Architecture metrics for classes, functions, interfaces, namespaces, traits, constants, and files

The tool now includes a dedicated Architecture metric category that provides counts and quality insights for core code elements. It tracks the number of classes, functions, interfaces, namespaces, traits, constants, and files, while applying specific coding standards such as PSR-1/12 naming conventions, one-class-per-file rules, and checks for superfluous naming or excessive namespace depth. This replaces previous metrics that measured cyclomatic complexity and trait usage in these areas, shifting the focus to architectural structure and adherence to PHP coding standards.

src/Domain/Metrics/Architecture · high confidence

New Drupal preset excludes contrib directories and disables debug functions

A new Drupal-specific preset has been added that automatically applies to projects containing 'drupal/core'. This preset extends the default configuration but excludes common Drupal directories such as 'core', 'modules/contrib', 'sites', 'profiles/contrib', and 'themes/contrib' from analysis. Additionally, it configures the linter to forbid the use of 'dd' and 'dump' functions, which are commonly used for debugging in Drupal development.

src/Application/Adapters/Drupal · high confidence

New sniff to forbid setter methods

A new PHP\_CodeSniffer sniff, ForbiddenSetterSniff, has been added to the domain to enforce coding standards by disallowing setter methods. When this rule is active, any method matching the setter pattern (e.g., \setFoo\) will trigger an error, encouraging the use of constructor injection and behavior naming instead. The sniff includes a configurable \allowedMethodRegex\ property to exempt specific methods and automatically skips the \setUp\ method commonly found in test classes.

src/Domain/Sniffs · high confidence

PhpInsights v2.14.2: Complete domain layer rewrite with parallel execution and diff output

This release introduces a comprehensive rewrite of the analysis domain layer, shifting from a dependency on SebastianBergmann\\PHPLOC to a custom, in-house Analyser and Collector that handle tokenization and metrics collection directly. The new architecture introduces a parallel processing engine via the Runner class, which distributes file analysis across multiple threads using child processes to significantly improve performance. It also adds a configurable diff output feature, allowing users to see code changes for style fixes, and introduces a new FileLinkFormatter system to support hyperlinks in IDEs like VS Code and PHPStorm. Additionally, the domain now includes a dedicated Container for dependency management and a Kernel that bootstraps the environment and defines the application version (v2.14.2).

src/Domain · high confidence

Support for multiple output formats and new formatters

Users can now output analysis results in multiple formats simultaneously or choose from new export options. The new FormatResolver allows selecting formats like 'checkstyle', 'codeclimate', 'json', and 'github-action' via the --format option, in addition to the existing console output. New formatter classes (Checkstyle, CodeClimate, GithubAction, Json) have been added to generate structured reports suitable for CI/CD pipelines and static analysis tools, while the Multiple formatter enables combining several outputs in a single run.

src/Application/Console/Formatters · high confidence

Behavioural changes

Console output formatting interface refactored

The \PublisherRepository\ interface has been renamed to \Formatter\ and moved to the \Application\\Console\\Contracts\ namespace, changing its purpose from retrieving publisher data to formatting analysis results. The new \format\ method accepts an \InsightCollection\ and metrics array, replacing the previous \get\ method that returned a \Publisher\ object. Additionally, the \Style\ interface had its PHPDoc comments cleaned up and \declare(strict\_types=1)\ added for consistency.

src/Application/Console/Contracts · high confidence

FilesRepository interface updated for path handling and return types

The FilesRepository interface has been modified to improve type safety and support multiple exclusion paths. The getFiles method now returns a typed array instead of an iterable, and a new getDefaultDirectory method has been added. Additionally, the in method has been replaced by within, which accepts both paths and an exclude list, allowing users to specify directories to ignore during file scanning.

src/Domain/Contracts/Repositories · high confidence

Introduce dedicated loaders for Fixer and Sniff insights

The system now uses specific loader classes to instantiate and configure code analysis tools. The new FixerLoader handles PhpCsFixer fixers, supporting configuration of indentation styles and exclusion patterns, while the SniffLoader manages PHP\_CodeSniffer sniffs by mapping configuration properties directly to sniff attributes and handling exclusions. These loaders implement the InsightLoader contract to bridge the configuration with the respective analysis engines.

src/Domain/InsightLoader · high confidence

Introduce structured console command definitions and auto-fix capability

The console application now uses dedicated definition classes (AnalyseDefinition, FixDefinition, BaseDefinition) to manage command inputs, replacing the previous Publisher class. This change introduces several new command-line options: users can now set minimum thresholds for quality, complexity, architecture, and style levels; disable security checks; specify multiple output formats (including console, json, checkstyle, codeclimate, and github-action); enable auto-fixing for fixable insights; flush the cache; and display a summary only. The 'fix' command is now explicitly defined with its own input structure, supporting the new auto-fix feature.

src/Application/Console/Definitions · high confidence

Laravel adapter now registers as a service provider with framework-specific linting rules

The Laravel adapter now includes an InsightsServiceProvider that registers the insights command and publishes a configuration file, ensuring the tool integrates seamlessly into Laravel applications. The accompanying Preset configures framework-specific behaviors: it excludes common Laravel directories and files (such as storage, config, and Telescope service providers), removes generic fixers like VoidReturnFixer and StaticClosureSniff that may conflict with Laravel conventions, and enforces rules against using debugging functions (dd, dump, ddd, tinker) while allowing Laravel's attribute setter methods.

src/Application/Adapters/Laravel · high confidence

New application infrastructure for preset resolution and configuration

The application layer now includes a dedicated Composer parser, a path resolver, and a configuration resolver that automatically detects and merges framework-specific presets (Drupal, Laravel, Magento2, Symfony, WordPress, Yii) with user configuration. A new default preset standardizes coding standards (e.g., strict types, unused variable checks) and excludes common directories, ensuring consistent analysis behavior across different project types.

src/Application · high confidence

New framework-specific configuration stubs for Drupal, Magento 2, and WordPress

PHP Insights now includes dedicated configuration stubs for Drupal, Magento 2, and WordPress, allowing users to quickly scaffold preset-specific settings. The Drupal stub replaces the previous 'drupal8' naming convention with 'drupal'. The Laravel stub has been updated to remove several Slevomat coding standard sniffs (such as strict types and mixed type hint checks) and now explicitly forbids final classes in the architecture metric, while also providing a custom title for the private methods insight. All stubs standardize on a 60-second timeout and support configurable exclude paths, requirements, and IDE URL handlers.

stubs · high confidence

Refactored console command registration to support new fix and internal processor commands

The console application's command registration has been refactored to use a new \InvokableCommand\ wrapper and explicit definition classes, replacing the previous \Router\-based approach. This change introduces two new commands: \fix\, which allows users to automatically correct code style issues, and a hidden \internal-processor\ command used for background processing tasks. The existing \analyse\ command remains available but is now registered using the new pattern.

config/routes · high confidence

Refactored console commands and introduced configurable quality thresholds

The console command layer has been refactored to support multiple formatters and configurable minimum requirements. The AnalyseCommand now accepts a Configuration dependency and enforces minimum thresholds for code quality, complexity, architecture, and style, returning a non-zero exit code if any metric falls below the configured minimum. It also supports a 'flush-cache' option and resolves formatters dynamically via FormatResolver. New commands, FixCommand and InternalProcessorCommand, have been added to handle fixing and internal processing tasks respectively, while InvokableCommand standardizes command execution and funding message display. Style classes (Bold, Title) have been cleaned up with strict types and removed docblocks.

src/Application/Console/Commands · high confidence

Refactored dependency injection container structure and configuration resolution

The application's dependency injection mechanism has been restructured to use dedicated injector classes within the \src/Application/Injectors\ namespace. Configuration resolution now explicitly checks for cached configurations during internal processing commands, while file processors (Sniff and Fixer) and insight loaders are now instantiated via specific injector classes (\FileProcessors\, \InsightLoaders\). The cache implementation has been moved from the domain structure layer to the application injectors, utilizing Symfony's FilesystemAdapter. Additionally, repository definitions have been simplified by removing unused publisher and git repository interfaces, focusing solely on local file repository injection.

src/Application/Injectors · high confidence

Refactored domain contracts and interfaces

The domain contract layer has been restructured to improve separation of concerns and type safety. Several legacy classes (Methods, Constants, SourceCode, GlobalAccesses, StringCell) have been converted into interfaces (FileLinkFormatter, FileProcessor, Fixable, GlobalInsight, Preset) and moved to the Contracts namespace. Metric interfaces (HasAvg, HasMax, HasPercentage, HasValue) now accept a Collector instead of a Publisher, and return types for details and insights have been tightened to specific object arrays. New contracts (DetailsCarrier, InsightLoader, Sniffer) have been added to support insight loading and PHP CS Fixer integration, and the Insight interface now includes a method to retrieve the insight class name.

src/Domain/Contracts · high confidence

Refactored exception classes for clearer error semantics

The exception hierarchy in the Domain layer has been refined to provide more specific error types for configuration and environment issues. Several new exception classes have been introduced: InsightClassNotFound, InternetConnectionNotFound, InvalidConfiguration, PresetNotFound, and SniffClassNotFound, all extending RuntimeException. Additionally, existing exceptions have been renamed to better reflect their purpose: DirectoryNotFoundException is now ComposerNotFound, and the previous Namespaces class (which was incorrectly located in the Structure namespace) has been moved and renamed to DirectoryNotFound. These changes improve the clarity of error handling when specific insights, presets, or directories cannot be found or configured.

src/Domain/Exceptions · high confidence

Refactored file discovery to support single files and improved exclusions

The LocalFilesRepository has been rewritten to support analyzing specific single files or directories, rather than only scanning entire directory trees. It now explicitly handles single file paths, ignores dotfiles and VCS directories by default, and excludes Blade template files. The previous LocalPublisherRepository was removed as its functionality was integrated into the new file handling logic.

src/Infrastructure · high confidence

Refactored insight architecture and added new complexity and security checks

The insight system has been refactored to remove the legacy Publisher dependency, replacing it with a Collector-based approach that simplifies instantiation and improves testability. This change introduces new insights: average cyclomatic complexity per class method, security advisory checks against Packagist, and stricter enforcement for forbidden globals, traits, and private methods. Additionally, the system now supports configurable exclusion lists for sniffs and fixers, and provides detailed feedback on fixes applied per file.

src/Domain/Insights · high confidence

Refactors console output handling and analysis logic

The console output layer has been refactored to decouple analysis from presentation. A new \Style\ class extends SymfonyStyle to provide a \waitForKey\ method, allowing users to pause and review issues by pressing Enter. The previous \TableFactory\ and \TableStructure\ classes have been removed, replacing the hardcoded table generation with a new \Formatter\ interface and \InsightCollectionFactory\. The \Analyser\ now accepts a \Formatter\ and \OutputInterface\, delegating the rendering of metrics and insights to the formatter, which enables more flexible output styling and structure.

src/Application/Console · high confidence

Removal of internal Row helper class

The internal \Row\ helper class, previously located in \src/Application/Console/Helpers/Row.php\, has been removed from the codebase. This class was responsible for formatting console output rows by extracting metric names, values, averages, maximums, and associated insight details from the \Feedback\ object. Its removal indicates a refactoring of the console output rendering logic, likely as part of the broader effort to reorganize metrics-related code into separate folders.

src/Application/Console/Helpers · high confidence

Removal of legacy code metrics and structural analysis reporters

The static analysis tool no longer reports several legacy code quality and structural metrics. Specifically, the removal of files in src/Domain/Dependencies eliminates reporting on static vs. non-static attribute and method accesses, as well as global constant and variable usage. The deletion of src/Domain/LinesOfCode files stops the measurement of code complexity (cyclomatic complexity for classes and methods), comment-to-code ratios, and the breakdown of lines of code by source element (classes, functions, methods, and global scope). Additionally, the removal of src/Domain/Structure files means the tool no longer provides statistics on class and method visibility (public vs. non-public), static vs. non-static methods, abstract vs. concrete classes, and named vs. anonymous functions.

src/Domain/Dependencies, src/Domain/LinesOfCode, src/Domain/Structure · high confidence

Standardizes development tooling configuration and CI infrastructure

The project replaces legacy configuration files with standardized, modern equivalents: \.phpcs.xml.dist\ now defines the PHP\_CodeSniffer ruleset, \phpstan.neon\ (replacing \.neon.dist\) sets static analysis to level 5, \phpunit.xml\ (replacing \.dist\) configures the test suite, \rector.php\ enables automated code upgrades, and \schema.json\ defines the JSON output structure. Additionally, Travis CI is removed in favor of GitHub Actions, and a \SECURITY.md\ policy is added for vulnerability reporting.

(repo-wide) · high confidence

Switches dependency injection container to League Container with expanded injector support

The application's dependency injection container has been replaced with League\\Container, which now delegates to a ReflectionContainer for auto-wiring. This change expands the container's capabilities by integrating additional injectors for Configuration, Cache, FileProcessors, and InsightLoaders, allowing these components to be automatically registered and tagged (FileProcessor and InsightLoader) within the service container.

config · high confidence

Test coverage

Added test coverage for domain insights; Added test fakes for file repository and console input; Added test fixtures for the autofixer feature; Added tests for ConfigResolver preset detection and configuration merging; Added tests for FixerDecorator exclusion and fix capabilities; Added tests for Laravel attribute setter metrics; Added tests for LocalFilesRepository file discovery and filtering; Added tests for console formatters and format resolution; Added tests for sniff exclusion and autofixing; Added tests for the ForbiddenSetterMethods sniff; Added unit tests for Domain configuration, results, and details sorting; Refactored test infrastructure with new base TestCase; Removed feature test for AnalyseCommand output; Updated test fixtures for code analysis and sniffing.

Dependencies

Major dependency overhaul and PHP 8.4 upgrade

The project has been upgraded to require PHP 8.4 and replaced several core dependencies: \narration/console\ and \narration/container\ are removed in favor of \symfony/console\ and \league/container\, while \phploc/phploc\ is replaced by \cmgmyr/phploc\. Additionally, \composer/semver\ is added, and many Symfony components (cache, http-client, process) along with dev tools like \phpunit\ and \phpstan\ are updated to their latest major versions. The \composer.lock\ file has been deleted, and new Composer scripts for website asset management and CI testing have been introduced.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 74.

Lenses

  • Code Health 91
  • Architecture 96
  • Maturity 62
  • Readiness 78
  • Security 96

Changes since last survey

  • 300 commits — 217 feature/other, 83 fixes

By area

  • (root) — 94 commits
  • src/Domain — 62 commits
  • src/Application — 47 commits
  • .github/workflows — 33 commits
  • docs/insights — 16 commits
  • tests/Domain — 10 commits
  • (repo) — 9 commits
  • docs/get-started.md — 9 commits
  • docs/continuous-integration.md — 4 commits
  • .github/FUNDING.yml — 2 commits
  • src/Infrastructure — 2 commits
  • stubs/config.php — 2 commits
  • stubs/laravel.php — 2 commits
  • tests/Application — 2 commits
  • .github/dependabot.yml — 1 commit
  • bin/phpinsights — 1 commit
  • docker/Dockerfile — 1 commit
  • docs/readme.md — 1 commit
  • docs/support.md — 1 commit
  • tests/Infrastructure — 1 commit

Notable commits

  • fix: (fix): add "github-action" as a format option (#534)
  • fix: :memo: Fix documentation deployment (#718)
  • fix: Allow psr/simple-cache ^2.0 and ^3.0 (#580) - fixes #522, #573
  • fix: Changelog - fix h2 to h3
  • fix: Fix #401 (#402)
  • fix: Fix #517 by always loading CodeSniffer tokens (#542)
  • fix: Fix #73 : Add detail for ForbiddenGlobals Insight (#205)
  • fix: Fix ComposerLoader when composer:V2 is installed globally (#442)
  • fix: Fix FunctionLengthSniff namespace (#489)
  • fix: Fix Non-static methods called statically (#353)
  • fix: Fix SyntaxCheck launch with windows on large project (#437)
  • fix: Fix UnusedVariableSniff (#308)
  • fix: Fix analyse on one file (#297)
  • fix: Fix changing formatter (#443)
  • fix: Fix checkstyle formatter (#275)
  • fix: Fix copy logo script (#245)
  • fix: Fix display detail message without file (#404)
  • fix: Fix display tip repo when format is console (#301)
  • fix: Fix docs wrong namespace (#507)
  • fix: Fix error: The option "preset" with value "wordpress" is invalid (#646)
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

nunomaduro/phpinsights was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit e079a1043a57d0b3bbf3941eef478c2e8bd4cc0b — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.