| Name | Modified | Size | Downloads / 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 initto generate a custom configuration file through an interactive setup tool. - Configuration Migration Tool: Run
phpmd migrateto upgrade legacy PHPMD 2 XML configurations directly into YAML. - Zero-Config CLI Execution: Running
phpmdwithout 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 newUnusedSuppressionrule to identify stale suppressions. - Parallel Processing: Speed up analysis on large codebases using the new
--threadsoption for multi-threaded parsing. - Visual Feedback: Added a progress bar during CLI analysis (with controls via
--no-progressand--progress). - New Analysis Rules:
IfStatementWithoutLogicandLongMethodNameFor flagging dead code and long method names. - Enhanced Rule Flexibility: Added
exceptionsparameter support to ignore specific methods acrossUnusedFormalParameter,UnusedPrivateField, andExcessiveParameterList, along with enum method handling inStaticAccess. - 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 configuredmaximum. Rules that check a lower bound (ShortVariable, ShortMethodName, ShortClassName) keep theminimumproperty. 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
maximumis the highest accepted value. - Removed
--ignoreoption, use--excludeinstead. - Removed
--extensionsoption, use--suffixesinstead. - Removed
--reportfileoption, use--reportfile-text,--reportfile-xml, etc. - Removed
--minimumpriorityand--maximumpriorityaliases, use--minimum-priorityand--maximum-priority. - Removed
PHPMD\PHPMD::getIgnorePatterns()andsetIgnorePatterns(), usegetExcludePatterns()andaddExcludePatterns(). - 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(), usegetExcludePatterns()instead. - Renamed
Rule::getBooleanProperty()toisTruthyProperty(). - Renamed
RuleSetFactory::getCache()toisCacheEnabled(). - Changed
--update-baselineto 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\BaselineValidatorno longer takes aBaselineMode. - Renamed the rule classes
PHPMD\Rule\Design\LongClasstoExcessiveClassLength,LongMethodtoExcessiveMethodLength,LongParameterListtoExcessiveParameterList,NpathComplexitytoNPathComplexityandWeightedMethodCounttoExcessiveClassComplexity. 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, andAbstractRule::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,TextUIandUtilitynamespaces@internal. They are not covered by the 3.x compatibility promise.
New features:
- Added
phpmd initcommand that generates aphpmd.ymlthrough an interactive wizard. - Added
phpmd migratecommand 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-patternsupport in YAML, JSON, and PHP configuration files (#909). - Added
format,cache-file,cache-strateg,baseline-file,bootstrap,cache,minimum-priority,maximum-priority,threads,paths, andsuffixesto the configuration files. - Added
#[SuppressWarnings]PHP attribute as the preferred way to suppress warnings. - Added [#1230]:
UnusedSuppressionrule (UnusedCode) that reports#[SuppressWarnings]attributes that no longer suppress anything. - Added progress bar during analysis on stderr, use
--no-progressoption to hide it or--progressto force it together with--quietor--silent. - Added
-vvoutput of the effective configuration (paths, exclude patterns, suffixes, threads, strict mode, baseline file, loaded rule sets, cache status) and the exit code, and-vvvoutput of every argument and option and every loaded rule. Both are written to stderr. - Added
--threadsoption for parallel file parsing. - Added
--xdebugoption to enable Xdebug during analysis. - Added
--bootstrapoption to load a PHP script before analysis. - Added
EnumAwareandTraitAwarerule marker interfaces. - Added [#1276]:
exceptionsparameter support for UnusedPrivateField. - Added [#1277]:
exceptionsparameter 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:
BooleanGetMethodNamerule can now infer return type from type declarations. - Added:
UnusedFormalParameterrule now omits parameters when the method uses the#[Override]attribute. - Added:
StaticAccessrule 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]:
UnusedPrivateMethodrule now recognises calls on cloned objects andnew self/new static/new ClassName. - Added:
IfStatementWithoutLogicrule (CleanCode) — flags conditional statements that contain only literals. - Added:
LongMethodNamerule (Naming) — flags method and function names that exceed a configurable length threshold. - Added:
exceptionsparameter support forExcessiveParameterList(LongParameterList) rule to ignore listed methods.
Fixed:
- Fixed false positive in
UnusedLocalVariablefor 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
UnusedLocalVariablewhen 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]:
ShortVariablerule now detects short parameter names in closures and arrow functions passed directly as arguments. - Fixed:
#[SuppressWarnings(self::class)]never suppressed anything. - Fixed:
--strictdid not revealLongVariablesuppressions on fields/variables/parameters, norUnusedPrivateMethodsuppressions on private methods. - Fixed [#991]: False positive in
UndefinedVariableforself::$name[...]andstatic::$name[...]when the static property is declared in a used trait or a parent class.
Deprecated:
- The
@SuppressWarningsdoc comment annotations, use the#[SuppressWarnings]attribute instead. The annotations still suppress warnings, but are not reported by theUnusedSuppressionrule.
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
- @yourpropertyexpert made their first contribution in https://github.com/phpmd/phpmd/pull/1083
- @llaville made their first contribution in https://github.com/phpmd/phpmd/pull/1197
- @savinmikhail made their first contribution in https://github.com/phpmd/phpmd/pull/1199
- @phansys made their first contribution in https://github.com/phpmd/phpmd/pull/1211
- @Muetze42 made their first contribution in https://github.com/phpmd/phpmd/pull/1201
- @sebestenyb made their first contribution in https://github.com/phpmd/phpmd/pull/1229
- @sergiy-petrov made their first contribution in https://github.com/phpmd/phpmd/pull/1240
- @Jimbolino made their first contribution in https://github.com/phpmd/phpmd/pull/1236
- @simonchrz made their first contribution in https://github.com/phpmd/phpmd/pull/1260
- @jkatruska made their first contribution in https://github.com/phpmd/phpmd/pull/1268
- @hms5232 made their first contribution in https://github.com/phpmd/phpmd/pull/1270
- @wickedOne made their first contribution in https://github.com/phpmd/phpmd/pull/1272
- @k2tzumi made their first contribution in https://github.com/phpmd/phpmd/pull/1277
- @rodrigoprimo made their first contribution in https://github.com/phpmd/phpmd/pull/1281
- @iSWORD made their first contribution in https://github.com/phpmd/phpmd/pull/965
- @tis-dm-webfactory made their first contribution in https://github.com/phpmd/phpmd/pull/664
- @ttomdewit made their first contribution in https://github.com/phpmd/phpmd/pull/706
- @wg-vn made their first contribution in https://github.com/phpmd/phpmd/pull/1332
- @aymericcucherousset made their first contribution in https://github.com/phpmd/phpmd/pull/1330
- @mebetter123 made their first contribution in https://github.com/phpmd/phpmd/pull/1333
- @developerjillur made their first contribution in https://github.com/phpmd/phpmd/pull/1354
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