WordPress Coding Standards(WPCS) for PHP
The article discusses WordPress Coding Standards (WPCS) for PHP, emphasizing the importance of consistent code quality and adherence to coding conventions. It outlines installation procedures, usage of PHP_CodeSniffer for code validation, and customization options for creating tailored coding standards.
WordPress Coding Standards(WPCS) the list of PHP_CodeSniffer (PHPCS) ruleset (sniffs) to check your code inside WordPress. It can improve your code quality and adhere to basic code conventions for WordPress.
Do you work in a team or just want to upgrade a code quality? Then you need to think about a single coding standard. I’m afraid you but if in your team more then one person it doesn’t work without quality control tools. The control quality tool for coding standard names the linter and exists for each programming language.
Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors, and suspicious constructs.
Wikipedia
As example for Python – Pylint, for PHP – PHP_CodeSniffer, for JavaScript – ESLint or JSHint, etc.
The WordPress Coding Standard includes simple rules about spaces and blanks as harder security rules, caching, and etc.
How to install WPCS?
Just use the composer
:
composer require wp-coding-standards/wpcs --dev
When you add any packages for PHP_CodeSniffer you need to add these packages to the scope of PHPCS. The best solution is a package that automatically adds all packages from your vendor in the scope of PHPCS.
composer require dealerdirect/phpcodesniffer-composer-installer --dev
And now you can easy to check the file and fix it:
vendor/bin/phpcs --standard=WordPress path/to/some/file.php
vendor/bin/phpcbf --standard=WordPress path/to/some/file.php
How to setting the PHPStorm?
PHPStorm -> Settings -> Languages & Frameworks -> PHP -> CLI Interpreter and choose the current PHP version.
PHPStorm -> Settings -> Languages & Frameworks -> PHP -> Quality Tools -> PHP_CodeSniffer -> Configuration and click on ‘…‘ button
Fill the PHP_CodeSniffer path:
path/to/vendor/squizlabs/php_codesniffer/bin/phpcs
and fill the Path to phpcbf:
path/to/vendor/squizlabs/php_codesniffer/bin/phpcsbf
Press on Validate button and accept that your paths are correct.
PHPStorm -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer validation:
Checked Show sniff name
In the Coding Standard list, you can see the next packages: WordPress, WordPress-Core, WordPress-Docs, WordPress-Extra. Choose WordPress and save it.
If you violate coding standards, in the editor, the lines will be underlined. If you hover over the underlined line, you will see an error.
As example:
phpcs: WordPress.Security.NonceVerification.Missing: Processing form data without nonce verification.
Where WordPress.Security.NonceVerification.Missing – sniff name and Processing form data without nonce verification. – description.
How to ignore some rules?
Sometimes your code can’t fully compatibility with WPCS. As example:
global $wpdb;
$id = 15;
$my_query = $wpdb->get_results( 'SELECT name FROM my_table WHERE id=' . $id );
In this example a few notices:
- WordPress.DB.PreparedSQL.NotPrepared
- WordPress.DB.DirectDatabaseQuery.NoCaching
- WordPress.DB.DirectDatabaseQuery.DirectQuery
Raw data is a potential XSS backdoor. We can fix this with $wpdb->prepare
, cache some queries is also great for performance, but what do you need to do with a direct query? The right way is adding the ignore rule, but it is very important to understand the reason. If you add an ignore rule, you can read it as a developer’s signature about that line.
global $wpdb;
$id = 15;
$my_query = wp_cache_get( 'my_query' );
if ( ! $my_query ) {
$my_query = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->prepare( 'SELECT name FROM my_table WHERE id=%d', $id )
);
wp_cache_set( 'my_query', $my_query );
}
phpcs:ignore – is ignoring the next line of your code. The best practice you’re php:ignore
with the rule description phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
. So we ignoring only one rule from our coding standard. Also if you need to ignore rule for a few lines of the code then you can use the phpcs:disable
, but don’t forget to enable this rule after:
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$my_query = $wpdb->get_results(
$wpdb->prepare(
'SELECT name FROM my_table WHERE id=%d',
$id
)
);
//phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
The own coding standard based on WPCS
In my opinion for the middle and more size projects need to create their own codings standard. It’s very easy, just create the phpcs.xml
file:
<?xml version="1.0"?>
<ruleset name="AwesomeCS">
<description>Custom coding standards.</description>
<rule ref="WordPress"/>
</ruleset>
We create the AwesomeCS coding standard based on the WordPress coding standards.
Arguments
You can add arguments from CLI for your config. For example, argument extensions that can help you work only with the PHP files:
<ruleset name="AwesomeCS">
<!-- ... -->
<arg value="ps"/>
<arg name="colors"/>
<arg name="parallel" value="100"/>
<arg name="extensions" value="php"/>
<arg name="cache" value=".phpcs.cache"/>
<!-- ... -->
</ruleset>
- The
ps
can show results of check real-time; - The
colors
is just adds the colored output; - The
parallel
checks your files in separate processes. Unfortunately, but this feature based on the PCNTL library and doesn’t works on Non-Unix systems (Windows). But can add the super boost for your speed in the GH actions; - The
extensions
describes the extensions for the checking; - The
cache
is just super boost for the double-checking
Exclude files and directories
Add the list of pattern where phpcs
doesn’t check.
<ruleset name="AwesomeCS">
<!-- ... -->
<exclude-pattern>\.github/*</exclude-pattern>
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>node_modues/*</exclude-pattern>
<exclude-pattern>\.idea/*</exclude-pattern>
<exclude-pattern>assets/*</exclude-pattern>
<!-- ... -->
</ruleset>
The short array syntax
Frankly the short array syntax it’s uncomfortable and legacy, but important for WordPress coding standard. Let’s update it:
<ruleset name="AwesomeCS">
<!-- ... -->
<!-- Allow short array syntax -->
<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
<severity>0</severity>
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
<!-- ... -->
</ruleset>
This is a just example of how to add custom rules in your CS.
The PSR-4 naming
I prefer using the composer autoload, so let’s update CS for support PSR-4 naming:
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="WordPress">
<!-- PSR4 -->
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
</rule>
<!-- ... -->
</ruleset>
Cyclomatic Complexity
Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program’s source code.
Wikipedia
This metric will help control code complications and write simpler functions and methods.
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="4"/>
<property name="absoluteComplexity" value="5"/>
</properties>
</rule>
<!-- ... -->
</ruleset>
- If the cyclomatic complexity is higher than 4, you will see a warning
- If the cyclomatic complexity is higher than 5, you will see the error
Nesting Level
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="Generic.Metrics.NestingLevel">
<properties>
<property name="absoluteNestingLevel" value="1"/>
</properties>
</rule>
<!-- ... -->
</ruleset>
If the nesting level is higher than 1, you will see an error.
As example this code will cause an error on CS:
function awesome_function( $items ) {
if ( is_array( $items ) {
foreach( $items as $item ) {
// ...
}
}
}
This code needs to be refactored and used early exit from the method/function:
function awesome_function( $items ) {
if ( ! is_array( $items ) {
return false;
}
foreach( $items as $item ) {
// ...
}
}
PHPCompatibility
Just awesome coding standard PHPCompatibility which you can add the minimal support PHP version and phpcs
will detect in your code any problem for it. It’s really very well library for public plugins when you need to support the form PHP5.6 to PHP7.4 version. Just run your test in php7.4 and this library can help you find any problem with PHP compatibility in 5.6
Let’s install this library and update config:
composer require phpcompatibility/php-compatibility --dev
<ruleset name="AwesomeCS">
<!-- ... -->
<config name="testVersion" value="5.6-"/>
<rule ref="PHPCompatibility"/>
<!-- ... -->
</ruleset>
Thanks to this, you can check the compatibility from PHP5.6 to the version on which you are checking the files.
Add your own config to PHPStorm
File -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer
In the list of Coding standard select Custom and specify the path to our phpcs.xml
Full config
<?xml version="1.0"?>
<ruleset name="CS">
<description>Custom coding standards.</description>
<config name="testVersion" value="5.6-"/>
<exclude-pattern>\.codeception/*</exclude-pattern>
<exclude-pattern>\.github/*</exclude-pattern>
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>node_modues/*</exclude-pattern>
<exclude-pattern>\.idea/*</exclude-pattern>
<exclude-pattern>assets/*</exclude-pattern>
<arg value="ps"/>
<arg name="colors"/>
<arg name="parallel" value="100"/>
<arg name="extensions" value="php"/>
<arg name="cache" value=".phpcs.cache"/>
<rule ref="WordPress">
<!-- PSR4 -->
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
</rule>
<rule ref="PHPCompatibility"/>
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="3"/>
<property name="absoluteComplexity" value="5"/>
</properties>
</rule>
<rule ref="Generic.Metrics.NestingLevel">
<properties>
<property name="absoluteNestingLevel" value="3"/>
</properties>
</rule>
<!-- Allow short array syntax -->
<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
<severity>0</severity>
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
</ruleset>
Composer scripts
Add the scripts to run your CS using the composer scripts. Just add to the composer.json
next code:
{
...
"scripts": {
"cs": "phpcs --standard=.phpcs.xml .",
"cbf": "phpcbf --standard=.phpcs.xml .",
...
}
...
}
And now you can just run your coding standards and code beautifier and fixer:
composer cs
composer cbf
CS in the GitHub Actions
Create the file .github/workflows/php.yml
in your project:
name: My GH Actions
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: Run CS
run: vendor/bin/phpcs --standard=phpcs.xml .
After push action, your code will be checked on coding standards and you can see results on the GitHub.
If after this detailed article you don’t implement CS verification in your project, then I will come to you in a dream and kick your ass.
What the next? You can read how to write your own sniffs for PHP_CodeSniffer.
The original article can be read here
Related posts
Insights and Tips from My Journey
- Category:
- Dev
- Live coding
JWT Token Authentication in WordPress REST API
- Category:
- Maintenance
Effective Ways to Prevent Email Spam on Your Website
- Category:
- Dev
How to Send Contact Form 7 Submissions to a Telegram Bot
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!