Linting is the process of using an automated tool to scan your code for problems before you commit and deploy. It is a practice widely used in the development workflow of many languages, but hasn’t much been used in the PHP of WordPress developers.
The most commonly used linter in PHP right now is called “PHP Code Sniffer”, or phpcs for short. In this post I’ll show you how to install it in a project folder, configure it, and set up your editor to display its messages.
Sniff Codes
To phpcs, an “error” or a “warning” is generated by a function that checks PHP code for certain conditions.
phpcs calls a set of related errors or warnings a “sniff”.
Sniffs can be grouped together into a “category”.
phpcs calls a collection of categories a “standard”.
To make multiple sniff standards available in a single project, install the composer package dealerdirect/phpcodesniffer-composer-installer
. That will automatically use all installed standards in the current project with the composer type phpcodesniffer-standard
when you run phpcs.
To install that package in a PHP project, run the following (assuming you already have composer installed).
composer require --dev dealerdirect/phpcodesniffer-composer-installer
Each error or warning in a sniff has a “sniff code” which identifies it explicitly. A full sniff code includes the standard, the category, the sniff, and the error or warning, all separated by periods.
Standard.Category.Sniff.Error
For example:
MyStandard.MagicMethods.DisallowMagicGet.MagicGet
It’s possible to refer to all the errors in a sniff by omitting the error name. It’s further possible to refer to all the sniffs in a category, or the categories in a standard, but omitting those fields as well.
Therefore, these are all valid codes:
MyStandard.MagicMethods.DisallowMagicGet.MagicGet MyStandard.MagicMethods.DisallowMagicGet MyStandard.MagicMethods MyStandard
Built-in Standards
phpcs comes with several standards built-in. You can see them on the command-line by running phpcs -i
. These include PEAR
, PSR1
, PSR2
, Squiz
and Zend
.
WordPress has its own standard which you can install with composer as well.
composer require --dev wp-coding-standards/wpcs
I highly recommend the VariableAnalysis standard which looks for undefined and unused variables.
composer require --dev sirbrillig/phpcs-variable-analysis
Configuring Standards
When installing sniff standards in a project, you edit a phpcs.xml
file with the rule
tag inside the ruleset
tag. The ref
attribute of that tag should specify a standard, category, sniff, or error code to enable. It’s also possible to use these tags to disable or modify certain rules. The official annotated file explains how to do this.
For example, this would enable all the sniffs in a standard called MyStandard
:
My PHP project.
The following configuration will enable all the sniffs in MyStandard
, VariableAnalysis
, and WordPress
.
My PHP project.
Configuring An Editor
To run phpcs on a file in your project, just use the command-line as follows (the -s
causes the sniff code to be shown, which is very important for learning about an error).
vendor/bin/phpcs -s src/MyProject/MyClass.php
When it runs, phpcs will report any errors or warnings it finds. That’s pretty handy, but I find that it’s even more valuable to have linters run directly in your editor so that you can see problems as you code. Pretty much all editors support this, but the method of installation depends on your editor.
For vim, I recommend you install the ALE plugin. This has phpcs support already built-in and will use the standards you have configured in your project.
For phpstorm, the linting support is built-in, but you have to configure the app to know where to look. This guide shows how to set the path and enable the inspections. The guide neglects to mention that the path setting is under Preferences > Languages & Frameworks > PHP > Code Sniffer, and that the path should be set to your local installation of vendor/bin/phpcs
. It also neglects to say that the inspections are under Preferences > Editor > Inspections and that you have to set the “Coding standard” to your phpcs.xml
file manually (you may also want to disable some of the existing Inspections).
For vscode, I suggest installing the vscode-phpcs extension. It will automatically detect and use your local phpcs and configuration for your project. However, note that before version 1.0, the sniff code could not be shown.
Ignoring Rules
Sometimes you’ll need to ignore or disable one of the sniffs in a standard. The official documentation explains how to do this. You can surround or prefix your code with special comments to instruct phpcs to ignore it. Note that prior to version 3.2, you could not disable specific sniffs in this way; phpcs would ignore all of them for the marked lines.
$xmlPackage = new XMLPackage; // @codingStandardsIgnoreStart $xmlPackage['error_code'] = get_default_error_code_value(); $xmlPackage->send(); // @codingStandardsIgnoreEnd
$xmlPackage = new XMLPackage; // @codingStandardsIgnoreLine $xmlPackage['error_code'] = get_default_error_code_value(); $xmlPackage->send();
In the recent version 3.2 of phpcs, this feature was greatly improved. The above special comments were replaced with // phpcs:disable
/// phpcs:enable
and // phpcs:ignore
respectively. You can also use // phpcs:ignore
on the same line as a statement.
Even better, you are able to disable specific rules with either form by listing the sniff codes (comma-delimited) at the end of the special comment. For example, this following is possible.
doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings
You can even include comments in the disabling line!
doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings -- We are ok with bad things here
If there are specific sniffs you wish to ignore for your entire project, you can configure them in the phpcs.xml
file and set their severity to 0
. Here’s an example of disabling the WordPress function comment rule (standards can contain other standards, so some WordPress rules are actually part of the Squiz
standard).
My PHP project. 0
In a later post, I explain how a phpcs standard is built and how to create and modify your own. Until then, see if you can find some standards that you like and use them! Here is the phpcs.xml file I typically use right now for non-WordPress projects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<ruleset name="PaytonsStandard"> | |
<description> | |
Originally from https://gist.github.com/Ovsyanka/e2ab2ff76e7c0d7e75a1e4213a03ff95 | |
PSR2 with changes: | |
– tabs instead of spaces (https://gist.github.com/gsherwood/9d22f634c57f990a7c64) | |
– bracers on end of line instead new line | |
– unused/undefined variable detection (https://github.com/sirbrillig/phpcs-variable-analysis) | |
</description> | |
<arg name="tab-width" value="4"/> | |
<rule ref="PSR2"> | |
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine" /> | |
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine" /> | |
<exclude name="Generic.WhiteSpace.DisallowTabIndent"/> | |
</rule> | |
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/> | |
<rule ref="Generic.WhiteSpace.ScopeIndent"> | |
<properties> | |
<property name="indent" value="4"/> | |
<property name="tabIndent" value="true"/> | |
</properties> | |
</rule> | |
<rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie" /> | |
<rule ref="Generic.Classes.OpeningBraceSameLine"/> | |
<rule ref="VariableAnalysis.CodeAnalysis.VariableAnalysis"/> | |
</ruleset> |
(Photo by Noel Lopez on Unsplash)
One reply on “Linting PHP with phpcs sniffs”
[…] a follow-up to my summary of using phpcs to lint your PHP code, this post will explain how to create, modify, and test a phpcs […]