PHPCS - PHP Code Sniffer
The PHP_CodeSniffer project describes the tool as follows:
PHP_CodeSniffer is a set of two PHP scripts; the main
phpcsscript that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a secondphpcbfscript to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent.
PHPCS reports where your PHP breaks the Drupal coding standards.
Fixing those violations keeps custom modules, themes and scripts on the same
conventions, so code review can skip the formatting nitpicks. Vortex
comes with a pre-configured PHPCS
ruleset for Drupal
projects. The ruleset adds a strict types check and a compatibility check
for your PHP version. The bundled phpcbf command fixes the violations
that have an automatic fix.
This page is for developers who write PHP in a Vortex project. It shows how to check and fix your code, what the shipped ruleset enforces and how to ignore a rule.
Usage
Check for violations
The Ahoy command runs PHPCS, then PHPStan and Rector. The Docker Compose command runs PHPCS alone. To check the code, run 1 of the following commands:
- Ahoy
- Docker Compose
ahoy lint-be
docker compose exec cli vendor/bin/phpcs
Confirm that the check passed: PHPCS prints no FILE: report, and
echo $? prints 0 right after the command.
Fix violations
The PHPCS report marks each violation that PHPCBF can fix with [x]. To fix
the marked violations, run 1 of the following commands:
- Ahoy
- Docker Compose
# Fix all back-end lint issues (Rector, then PHPCBF).
ahoy lint-be-fix
docker compose exec cli vendor/bin/phpcbf
Configuration
See the PHP_CodeSniffer configuration reference.
All global configuration lives in the
phpcs.xml file.
By default, PHPCS checks against the following standards and sniffs:
Drupal- the Drupal coding standardsDrupalPractice- Drupal best practicesGeneric.PHP.RequireStrictTypes- adeclare(strict_types=1);statement in every filePHPCompatibility- compatibility with the PHP version intestVersionDrevOps- the DrevOps standard, which requires the following:- Snake_case names for local variables and parameters
- PHPUnit data providers that start with
dataProvider, match the name of their test and come after it
SlevomatCodingStandard.TypeHints.DNFTypeHintFormat- no spaces around|and&in union and intersection types, set through itswithSpacesAroundOperatorsproperty
The ruleset also adds 3 whitespace sniffs from the standards that ship with PHPCS and reports them as warnings. They flag a blank line after a function's opening brace and a blank line before or after a control structure's closing brace. Warnings fail the check too, because PHPCS exits with a non-zero code when it reports any.
The ruleset allows long array lines in test files. It also exempts the Behat contexts from the project class name prefix.
The ruleset sets the following command-line arguments for every run:
colors- colored outputs- the sniff code after each messagep- a progress indicatorparallelset to10- 10 parallel processes, which you can change to match your CPU cores
PHPCS checks the following paths, which the <file> entries in phpcs.xml
list:
web/modules/customweb/themes/customweb/sites/default/settings.phpweb/sites/default/includestestsscripts
Within them, PHPCS checks files with the inc, info, install,
module, php, profile, test and theme extensions. It skips
minified files and the build, fonts, images and node_modules
directories of custom themes.
To add or remove targets, add or remove the <file> entries in
phpcs.xml:
<file>path/to/dir_or_file</file>
The PHPCompatibility checks run against the testVersion value in
phpcs.xml, set to 8.4. The composer.json key config.platform.php
pins PHP 8.4.27, a patch release of the same version. PHPCS doesn't read
that key, so update both values when you move to a new PHP version. The
testVersion line looks like this:
<config name="testVersion" value="8.4"/>
Ignore violations
To ignore a rule across the project, configure it in the
phpcs.xml file.
The following example turns a rule off for the files that match its
patterns:
<!-- Comment about why this rule is excluded. -->
<rule ref="DrupalPractice.General.ClassName.ClassPrefix">
<exclude-pattern>*\/dir\/another\/*\.php</exclude-pattern>
<exclude-pattern>*\/dir\/another\/*\.inc</exclude-pattern>
</rule>
To ignore all PHPCS rules in a file, add this line to the file header:
// phpcs:ignoreFile
To ignore a specific rule in a file, add this line to the file header:
// phpcs:disable <rule_name>
Replace <rule_name> with the sniff code that the report prints in
parentheses after the message, such as
Drupal.Commenting.FunctionComment.Missing.
To ignore a rule for a block of code, put it between a disable and an
enable comment:
// phpcs:disable <rule_name>
$a = 1;
// phpcs:enable <rule_name>
To ignore the next line only, add this comment on the line before it:
// phpcs:ignore
$a = 1;
Continuous integration
PHPCS runs in the lint job of the continuous integration
pipeline and fails the build on
violations.
Ignore failures
To let the build pass anyway, set the VORTEX_CI_PHPCS_IGNORE_FAILURE CI
variable to 1. PHPCS still runs and prints every violation in the job
log, so you can see what you're letting through.