mission-made / coding-standards
Requires
Requires (Dev)
- wp-coding-standards/wpcs: ^2.3
Suggests
- wp-coding-standards/wpcs: Required for validating WordPress sites
README
This package contains three coding standards for PHP Codesniffer:
MissionMadePHP
- a generic PHP coding standardMissionMadeLaravel
- a coding standard for Laravel applicationsMissionMadeWordPress
- a coding standard for WordPress sites
Installation
To install this package, run the following command:
composer require --dev dealerdirect/phpcodesniffer-composer-installer mission-made/coding-standards
For WordPress sites, you will also need to install wp-coding-standards/wpcs
:
composer require --dev wp-coding-standards/wpcs
It also includes PHP Compatibility, but as this requires that you specify the version yourself, you're left to configure that on a per-project basis.
Sample configurations
You should save this file in your project as phpcs.xml
. Here are some samples:
Laravel
<ruleset name="PHP_CodeSniffer">
<description>Coding standard.</description>
<arg value="np"/>
<file>app</file>
<file>config</file>
<file>routes</file>
<file>tests</file>
<rule ref="MissionMadeLaravel"/>
<!-- PHP Compatibility -->
<rule ref="PHPCompatibility"/>
<config name="testVersion" value="7.4-"/>
</ruleset>
WordPress (Bedrock in this case)
<?xml version="1.0"?>
<ruleset name="Site">
<description>Site Coding Standards</description>
<!-- Scan all files in directory -->
<file>.</file>
<!-- Ignore WordPress and Composer dependencies -->
<exclude-pattern>web/wp</exclude-pattern>
<exclude-pattern>vendor/</exclude-pattern>
<rule ref="MissionMadeWordPress"/>
<!-- PHP Compatibility -->
<rule ref="PHPCompatibility"/>
<config name="testVersion" value="7.4-"/>
</ruleset>
Importing standards
Importing a standard in the phpcs.xml
file is straightforward:
<rule ref="MissionMadePHP"/>
If any one sniff in a standard is causing issues and you want to disable it, you can do that too:
<rule ref="MissionMadePHP">
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint"/>
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint"/>
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint"/>
</rule>
Alternatively, you can set the severity of a rule to below 5 so it's not flagged as an error by default, but still raises a warning in any Codesniffer integration for your editor or IDE. This may make sense if you want to fix an issue eventually, but it requires a lot of work to get to a point where it can be resolved, and you still want any continuous integration task to pass:
<rule ref="SlevomatCodingStandard.Variables.DisallowSuperGlobalVariable">
<severity>4</severity>
</rule>
Gotchas
Be cautious when applying these standards to existing code bases. They are quite strict and you must not assume they won't break existing functionality. In particular, changing type hints and declaring strict types in files can cause breakages in code that worked beforehand, so make certain that either anything you change is thoroughly tested, or have a comprehensive test suite in place to catch breakages. If necessary you can always exclude any rules that cause problems, or reduce the severity.
PHP CodeSniffer is a powerful tool, but it doesn't understand the code base in the way a static analysis tool like Psalm does. It's highly recommended that alongside this tool, you install and configure Psalm on all of your PHP projects to help ensure your code base is well-typed, and that the types are correct and as precise as possible.
What does this check for?
PHP
The PHP standard extends the common PSR12 coding standard and also enforces the following rules:
- Disallow long array syntax (arrays must use
[]
instead ofarray()
) - Flag assignment in a condition
- Flag empty PHP statement
- Flag jumbled incrementer
- Flag unconditional if statement
- Flag unnecessary final modifier
- Flag unused function parameter
- Flag useless overriding method
- Require correctly formatted doc comments
- Flag FIXME
- Flag TODO
- Flag long lines
- Flag code with excessive cyclomatic complexity
- Flag code with excessive nesting levels
- Disallow silenced errors
- Disallow deprecated functions
- Catch PHP syntax errors
- Disallow GOTO
- Catch forbidden debugging or risky functions (eval, dd, var_dump etc).
- Catch Git merge conflicts
- Validates function/method comments
- Catch superfluous whitespace
- Doc comment alignment
- Forbid commented-out code (see https://kentcdodds.com/blog/please-dont-commit-commented-out-code for the rationale behind this)
- Forbid the
global
keyword` - Enforce consistent semicolon spacing
- Disallow implicit array creation
- Standardise multi-line array end bracket placement
- Standardise single line array whitespace
- Enforce trailing array commas
- Enforce a specific class structure, with placement of properties,traits used and methods enforced
- Prevent superfluous naming of items eg forbids an interface being called ItemInterface, or a trait being called DoThingsTrait
- Enforce consistent trait use declarations
- Enforce class member spacing
- Enforce method spacing
- Require a description for the deprecated annotation
- Forbid empty comments
- Disallow a continue without an integer operand in the switch
- Disallow Yoda comparison
- Enforce early exit where possible to help avoid unnecessary else statements and simplify conditions
- Enforce use of
Throwable
instead ofException
where possible - Require non-capturing catch in PHP 8.0+
- Catch unreachable code blocks
- Prevent unused inherited variables being passed to closure
- Catch useless parameter default values
- Disallow empty functions
- Sort use statements alphabetically
- Disallow group use for imports
- Catch and remove unused imports
- Prevent use from starting with backslash
- Prevent unnecessary use from same namespace
- Prevent useless alias
- Disallow equal operated (require strict comparison)
- Disallow increment and decrement operators
- Disallow references
- Require explicit assertion
- Require nowdoc instead of heredoc
- Catch useless parentheses
- Prevent use of argument unpacking with certain functions where it would cause performance problems
- Catch useless semicolon
- Enforce parameter type hint spacing
- Enforce property type hint spacing
- Enforce return type hint spacing
- Enforce union type hint format
- Catch duplicate assignment to variable
- Catch unused variable
- Catch useless variable
- Enforcing return type hints
- Enforcing parameter type hints
- Enforcing property type hints
- Enforce declaration of strict types
- Disallow use of superglobal variables
Laravel
The Laravel standard extends the PHP standard to disable the following rules which were problematic with Laravel:
- Enforcing return type hints
- Enforcing parameter type hints
- Enforcing property type hints
WordPress
The WordPress standard extends the existing WordPress coding standard and also enforces the following rules:
- Disallow long array syntax (arrays must use
[]
instead ofarray()
) - Flag assignment in a condition
- Flag empty PHP statement
- Flag jumbled incrementer
- Flag unconditional if statement
- Flag unnecessary final modifier
- Flag unused function parameter
- Flag useless overriding method
- Require correctly formatted doc comments
- Flag FIXME
- Flag TODO
- Flag long lines
- Flag code with excessive cyclomatic complexity
- Flagcode with excessive nesting levels
- Disallow silenced errors
- Disallow deprecated functions
- Catch PHP syntax errors
- Disallow GOTO
- Catch forbidden debugging or risky functions (eval, dd, var_dump etc).
die()
is not included as WP uses it - Catch Git merge conflicts
- Validates function/method comments
- Catch superfluous whitespace
- Doc comment alignment
- Forbid commented-out code
- Disallow implicit array creation
- Standardise multi-line array end bracket placement
- Standardise single line array whitespace
- Enforce trailing array commas
- Enforce a specific class structure, with placement of properties,traits used and methods enforced
- Prevent superfluous naming of items eg forbids an interface being called ItemInterface, or a trait being called DoThingsTrait
- Enforce consistent trait use declarations
- Enforce class member spacing
- Require a description for the deprecated annotation
- Forbid empty comments
- Disallow a continue without an integer operand in the switch
- Disallow Yoda comparison
- Enforce early exit where possible to help avoid unnecessary else statements and simplify conditions
- Enforce use of
Throwable
instead ofException
where possible - Require non-capturing catch in PHP 8.0+
- Catch unreachable code blocks
- Prevent unused inherited variables being passed to closure
- Catch useless parameter default values
- Disallow empty functions
- Sort use statements alphabetically
- Disallow group use for imports
- Catch and remove unused imports
- Prevent use from starting with backslash
- Prevent unnecessary use from same namespace
- Prevent useless alias
- Disallow equal operated (require strict comparison)
- Disallow increment and decrement operators
- Disallow references
- Require explicit assertion
- Require nowdoc instead of heredoc
- Catch useless parentheses
- Prevent use of argument unpacking with certain functions where it would cause performance problems
- Catch useless semicolon
- Enforce parameter type hint spacing
- Enforce property type hint spacing
- Enforce return type hint spacing
- Enforce union type hint format
- Catch duplicate assignment to variable
- Catch unused variable
- Catch useless variable