Download Latest Version PHPMD 3.0.0 source code.zip (270.4 kB) Google Add to Preferred Sources
Home / 3.0.0
Name Modified Size InfoDownloads / Week
Parent folder
phpmd.phar.asc 2026-10-04 134 Bytes
phpmd.phar 2026-10-04 6.4 MB
PHPMD 3.0.0 source code.tar.gz 2026-10-04 151.0 kB
PHPMD 3.0.0 source code.zip 2026-10-04 270.4 kB
README.md 2026-10-04 12.1 kB
Totals: 5 Items   6.8 MB 0

New major release of PHPMD. See UPGRADING.md (github.com) for a detailed migration guide from PHPMD 2 to PHPMD 3.

Key New Features

  • Interactive Configuration Wizard: Run phpmd init to generate a custom configuration file through an interactive setup tool.
  • Configuration Migration Tool: Run phpmd migrate to upgrade legacy PHPMD 2 XML configurations directly into YAML.
  • Zero-Config CLI Execution: Running phpmd without arguments now automatically detects configuration and target paths.
  • Centralized Settings: Most analysis options (such as paths, format, cache, threads, and baseline) can now be defined directly inside configuration files instead of requiring CLI arguments.
  • PHP 8 Attributes Support: Use #[SuppressWarnings] as the preferred way to suppress warnings, backed by a new UnusedSuppression rule to identify stale suppressions.
  • Parallel Processing: Speed up analysis on large codebases using the new --threads option for multi-threaded parsing.
  • Visual Feedback: Added a progress bar during CLI analysis (with controls via --no-progress and --progress).
  • New Analysis Rules: IfStatementWithoutLogic and LongMethodName For flagging dead code and long method names.
  • Enhanced Rule Flexibility: Added exceptions parameter support to ignore specific methods across UnusedFormalParameter, UnusedPrivateField, and ExcessiveParameterList, along with enum method handling in StaticAccess.
  • GitHub Check Runs Renderer: Added native output renderer support for GitHub Check Runs integration.

Breaking changes:

  • Changed minimum PHP version from 5.3.9 to 8.1.
  • Changed CLI from positional arguments to Symfony Console with named options. The command signature is now phpmd analyze [options] [--] [<paths>...].
  • Standardized rule threshold properties to maximum (#670). Rules now report only when the measured value exceeds (>) the configured maximum. Rules that check a lower bound (ShortVariable, ShortMethodName, ShortClassName) keep the minimum property. Renamed properties (the old names remain accepted as aliases):
  • CyclomaticComplexity: reportLevel -> maximum
  • NPathComplexity: minimum -> maximum
  • ExcessiveMethodLength: minimum -> maximum
  • ExcessiveClassLength: minimum -> maximum
  • ExcessiveParameterList: minimum -> maximum
  • ExcessivePublicCount: minimum -> maximum
  • TooManyFields: maxfields -> maximum
  • TooManyMethods: maxmethods -> maximum
  • TooManyPublicMethods: maxmethods -> maximum
  • NumberOfChildren: minimum -> maximum
  • DepthOfInheritance: minimum -> maximum
  • Rules that previously reported when the value equaled the threshold (CyclomaticComplexity, NPathComplexity, ExcessiveMethodLength, ExcessiveClassLength, ExcessiveParameterList, ExcessivePublicCount, NumberOfChildren, DepthOfInheritance, ExcessiveClassComplexity, CouplingBetweenObjects) now only report when the value is greater than the threshold, so the configured maximum is the highest accepted value.
  • Removed --ignore option, use --exclude instead.
  • Removed --extensions option, use --suffixes instead.
  • Removed --reportfile option, use --reportfile-text, --reportfile-xml, etc.
  • Removed --minimumpriority and --maximumpriority aliases, use --minimum-priority and --maximum-priority.
  • Removed PHPMD\PHPMD::getIgnorePatterns() and setIgnorePatterns(), use getExcludePatterns() and addExcludePatterns().
  • Removed deprecated PHP_PMD_* class aliases.
  • Require pdepend/pdepend 3.x.
  • Changed exit code for processing errors from 1 to 3.
  • Introduced PHPMD-specific exception hierarchy under PHPMD\Exception\.
  • Removed PHPMD\RuleSetFactory::getIgnorePattern(), use getExcludePatterns() instead.
  • Renamed Rule::getBooleanProperty() to isTruthyProperty().
  • Renamed RuleSetFactory::getCache() to isCacheEnabled().
  • Changed --update-baseline to report violations that are not in the baseline (#1344). They are rendered with the configured format, make the command exit with code 2 and are not added to the baseline file. PHPMD\Baseline\BaselineValidator no longer takes a BaselineMode.
  • Renamed the rule classes PHPMD\Rule\Design\LongClass to ExcessiveClassLength, LongMethod to ExcessiveMethodLength, LongParameterList to ExcessiveParameterList, NpathComplexity to NPathComplexity and WeightedMethodCount to ExcessiveClassComplexity. The rule names are unchanged.
  • Changed suppressions to be applied by filtering the violations after the rules have run, instead of skipping suppressed code. RuleSet::apply() no longer skips suppressed nodes, and AbstractRule::setStrict() has been removed. Custom rules no longer need to check for suppressions.
  • Marked the parallel rule runner, the PDepend integration, the suppression handling and the Baseline, Cache, Config, RuleProperty, TextUI and Utility namespaces @internal. They are not covered by the 3.x compatibility promise.

New features:

  • Added phpmd init command that generates a phpmd.yml through an interactive wizard.
  • Added phpmd migrate command that upgrades a PHPMD 2 configuration file and converts it to YAML.
  • Added YAML, JSON, and PHP as configuration formats in addition to XML.
  • Added configuration file auto-detection for phpmd.yml, phpmd.yaml, phpmd.json, phpmd.xml, and phpmd.php.
  • Added exclude-pattern support in YAML, JSON, and PHP configuration files (#909).
  • Added format, cache-file, cache-strateg, baseline-file, bootstrap, cache, minimum-priority, maximum-priority, threads, paths, and suffixes to the configuration files.
  • Added #[SuppressWarnings] PHP attribute as the preferred way to suppress warnings.
  • Added [#1230]: UnusedSuppression rule (UnusedCode) that reports #[SuppressWarnings] attributes that no longer suppress anything.
  • Added progress bar during analysis on stderr, use --no-progress option to hide it or --progress to force it together with --quiet or --silent.
  • Added -vv output of the effective configuration (paths, exclude patterns, suffixes, threads, strict mode, baseline file, loaded rule sets, cache status) and the exit code, and -vvv output of every argument and option and every loaded rule. Both are written to stderr.
  • Added --threads option for parallel file parsing.
  • Added --xdebug option to enable Xdebug during analysis.
  • Added --bootstrap option to load a PHP script before analysis.
  • Added EnumAware and TraitAware rule marker interfaces.
  • Added [#1276]: exceptions parameter support for UnusedPrivateField.
  • Added [#1277]: exceptions parameter support for UnusedFormalParameter.
  • Added [#1076]: Option to force camelCase abbreviations in class names.
  • Added [#1078]: Option to force camelCase abbreviations in variable, property, and parameter names.
  • Added [#1196]: Support for custom renderers via RendererFactory.
  • Added: BooleanGetMethodName rule can now infer return type from type declarations.
  • Added: UnusedFormalParameter rule now omits parameters when the method uses the #[Override] attribute.
  • Added: StaticAccess rule ignores predefined enum static methods.
  • Added: Wildcard option for StaticAccess exceptions.
  • Added [#965]: GitHub Check Runs renderer.
  • Added [#706]: Relative path support in report output.
  • Added [#664]: Rule properties can now be overridden in a custom ruleset without excluding the rule.
  • Added [#1069]: UnusedPrivateMethod rule now recognises calls on cloned objects and new self/new static/new ClassName.
  • Added: IfStatementWithoutLogic rule (CleanCode) — flags conditional statements that contain only literals.
  • Added: LongMethodName rule (Naming) — flags method and function names that exceed a configurable length threshold.
  • Added: exceptions parameter support for ExcessiveParameterList (LongParameterList) rule to ignore listed methods.

Fixed:

  • Fixed false positive in UnusedLocalVariable for variables used with coalescing assignment.
  • Fixed: The result cache no longer hides the types declared in unchanged files from the rules applied to changed ones; unchanged files are restored through pdepend's cache and only skip rule application.
  • Fixed [#814]: Correctly attribute argument to variadic parameter.
  • Fixed [#927]: False positive in UnusedLocalVariable when a variable bound by reference is written to.
  • Fixed [#1016]: Crash when isPassedByReference checks a parent that does not exist.
  • Fixed [#1236]: PHP 8.4 deprecation for ReflectionMethod::__construct() with 1 argument.
  • Fixed [#1239]: ShortVariable rule now detects short parameter names in closures and arrow functions passed directly as arguments.
  • Fixed: #[SuppressWarnings(self::class)] never suppressed anything.
  • Fixed: --strict did not reveal LongVariable suppressions on fields/variables/parameters, nor UnusedPrivateMethod suppressions on private methods.
  • Fixed [#991]: False positive in UndefinedVariable for self::$name[...] and static::$name[...] when the static property is declared in a used trait or a parent class.

Deprecated:

  • The @SuppressWarnings doc comment annotations, use the #[SuppressWarnings] attribute instead. The annotations still suppress warnings, but are not reported by the UnusedSuppression rule.

Internal:

  • Migrated to Symfony Console for the CLI implementation.
  • Upgraded to PHPUnit 10/11 and PHPStan 2.
  • Applied PER CS v2 code style throughout.
  • Modernized codebase to PHP 8.1+ syntax (enums, readonly, named args, constructor promotion, etc.).
  • Added phpmd.project.yml, PHPMD's own self-analysis configuration, and made the codebase pass it cleanly (supressing allowable violations).

New Contributors

Also thank you to all the returning contributors that helped us get over the finish line with this major release.

Full Changelog: https://github.com/phpmd/phpmd/compare/2.15.0...3.0.0

Source: README.md, updated 2026-10-04