Provides a PHP CodeSniffer ruleset for the Brianvarskonst coding standard
The Brianvarskonst Coding Standard is an extension of the Symfony Coding Standard and adds specific rules for ensuring code quality and consistency.
PHP 8.0+ coding standard
=>
operators must be aligned in associative arrays.- Keys and
=>
operators must be on the same line in arrays.
- Opening brackets must be followed by a newline in multi-line arrays.
- Closing brackets must be on their own line.
- Elements must be indented in multi-line arrays.
use
statements must be sorted lexicographically.- Configurable sorting order via
order
property.
The order
property of the Brianvarskonst.Formatting.AlphabeticalUseStatements
sniff defines
which function is used for ordering.
Possible values for order:
dictionary
(default): based on strcmp, the namespace separator precedes any other characteruse Doctrine\ORM\Query; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder;
string
: binary safe string comparison using strcmpuse Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\Query\Expr; use ExampleSub; use Examples;
string-locale
: locale based string comparison using strcollstring-case-insensitive
: binary safe case-insensitive string comparison strcasecmpuse Examples; use ExampleSub;
To change the sorting order for your project, add this snippet to your custom ruleset.xml
:
<rule ref="Brianvarskonst.Formatting.AlphabeticalUseStatements">
<properties>
<property name="order" value="string-locale"/>
</properties>
</rule>
- The imported class name must be used, when it was imported with a
use
statement.
- Interpolated variables in double-quoted strings must be surrounded by
{}
, e.g.,{$VAR}
. instead of$VAR
.
const
must be followed by a single space.
Source: mediawiki/mediawiki-codesniffer
- No more than one empty consecutive line is allowed.
- Functions, classes, interfaces, traits, and constants must use names with a minimum length (default 3 characters).
- Configurable via
minLength
andallowedShortNames
.
<rule ref="Brianvarskonst.Usage.ElementNameMinimalLength">
<properties>
<property name="minLength" value="5"/>
<property name="allowedShortNames" type="array" value="id,db,ok,x,y"/>
</properties>
</rule>
alternatively, whitelist can be extended via additionalAllowedNames
config, e.g.:
<rule ref="Brianvarskonst.Usage.ElementNameMinimalLength">
<properties>
<property name="additionalAllowedNames" type="array" value="i,j" />
</properties>
</rule>
- Ensures a maximum nesting level within functions/methods.
- Default triggers a warning at level 3 and an error at level 5.
- Configurable via
warningLimit
anderrorLimit
.
For example:
function foo(bool $level_one, array $level_two, bool $level_three)
{
if ($level_one) {
foreach ($level_two as $value) {
if ($level_three) {
return $value;
}
}
}
return '';
}
The example codes contains a nesting level of 3.
By default, the sniff triggers a warning if nesting is equal or bigger than 3, and triggers an error if nesting is equal or bigger than 5.
The warning and error limit can be customized via, respectively, warningLimit
and errorLimit
properties:
<rule ref="Brianvarskonst.Complexity.NestingLevel">
<properties>
<property name="warningLimit" value="5" />
<property name="errorLimit" value="10" />
</properties>
</rule>
There's an exception. Normally a try
/catch
/finally
blocks accounts for a nesting level,
but this sniff ignores the increase of level causes by a try
/catch
/finally
that is found
immediately inside the level of function.
For example, the following code would be fine:
function bar(array $data, string $foo): string
{
// Indent level 1
try {
$encoded = json_encode($data, JSON_THROW_ON_ERROR);
// Indent level 2
if ($encoded) {
// Indent level 3
if ($append !== '') {
return $encoded . $foo;
}
return $encoded;
}
return '';
} catch (\Throwable $e) {
return '';
}
}
In fact, the two nested if
s would account for an indent level of 2, plus the try
/catch
block that would be 3, but because the try
/catch
is directly inside the function it is ignored,
so the max level considered by the sniff is 2, which is inside the limit.
This exception in the regard of try
/catch
/finally
blocks can be disabled via the
ignoreTopLevelTryBlock
property:
<rule ref="Brianvarskonst.Complexity.NestingLevel">
<properties>
<property name="errorLimit" value="10" />
<property name="ignoreTopLevelTryBlock" value="false" />
</properties>
</rule>
- Ensures a maximum number of properties per class (default 10).
- Configurable via
maxCount
.
<rule ref="Brianvarskonst.Classes.PropertyPerClassLimit">
<properties>
<property name="maxCount" value="120" />
</properties>
</rule>
- Enforces PSR-4 autoload standards.
- Configurable to match
composer.json
autoload settings.
Our style enforce the use of PSR-4 for autoload. This sniff make use of some configuration to check that files that contain classes are saved using the structure expected by PSR-4. If there is no configuration provided the sniff only checks that class name and match file name, which is not a warranty of PSR-4.
The needed configuration is specular to the PSR-4 configuration in composer.json
like:
{
"autoload": {
"psr-4": {
"Brianvarskonst\\Foo\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Brianvarskonst\\Foo\\Tests\\": "tests/php/"
}
}
}
The rule configuration should be:
<rule ref="Brianvarskonst.Namespace.Psr4">
<properties>
<property name="psr4" type="array" value="Brianvarskonst\Foo=>src,Brianvarskonst\Foo\Tests=>tests/php" />
</properties>
</rule>
Please note that when a PSR-4 configuration is given, all autoloadable entities (classes/interfaces/trait)
are checked to be compliant.
If there are entities in the sniffer target paths that are not PSR-4 compliant (e.g. loaded via classmap
or not autoloaded at all) those should be excluded via exclude
property, e.g.:
<rule ref="Brianvarskonst.Namespace.Psr4">
<properties>
<property name="psr4" type="array" value="Brianvarskonst\SomeCode=>src" />
<property name="exclude" type="array" value="Brianvarskonst\ExcludeThis,Brianvarskonst\AndThis" />
</properties>
</rule>
Note that anything that starts with any of the values in the exclude
array will be excluded.
E.g. by excluding Brianvarskonst\ExcludeThis
things like Brianvarskonst\ExcludeThis\Foo
and
Brianvarskonst\ExcludeThis\Bar\Baz
will be excluded as well.
To make sure what's excluded is a namespace, and not a class with same name, just use \
as last
character.
Further rules are imported from other standards, detailed in ruleset.xml
.
Most of the issues can be auto-fixed with phpcbf
.
For more information about included rules from PHP Standards Recommendations (PSR), refer to the official documentation:
A few rules have been included from the Slevomat Coding Standard.
A few rules have been included from the Symfony Coding Standard.
Some rules are also included from PHP_CodeSniffer itself, as well as PHPCSExtra.
Using Composer is the preferred way.
- Add the Brianvarskonst coding standard to
composer.json
$ composer require --dev brianvarskonst/coding-standard
- Use the coding standard:
$ ./vendor/bin/phpcs --standard=Brianvarskonst path/to/my/file.php
- Optionally, set Brianvarskonst as the default coding standard:
$ ./vendor/bin/phpcs --config-set default_standard Brianvarskonst
- Clone the repository:
$ git clone https://github.com/brianvarskonst/coding-standard.git
- Install dependencies:
$ composer install
- Verify coding standards:
$ ./vendor/bin/phpcs -i
- Use the coding standard:
$ ./vendor/bin/phpcs --standard=Brianvarskonst path/to/my/file.php
- Optionally, set Brianvarskonst as the default coding standard:
$ ./vendor/bin/phpcs --config-set default_standard Brianvarskonst
If phpcs
complains that Brianvarskonst
coding standard is not installed, please check the installed coding standards with
phpcs -i
and that installed_paths
is set correctly with phpcs --config-show
Sometimes it is necessary to not follow certain rules. To avoid error reporting, you can:
- Remove rules for an entire project via configuration.
- Disable rules from code, only in specific places.
In both cases, it is possible to remove or disable:
- A complete standard
- A standard subset
- A single sniff
- A single rule
These elements are in a hierarchical relationship: standards
consist of one or more subsets
,
which contain one or more sniffs
, which in turn contain one or more rules
.
Rules can be removed for the entire project by using a custom phpcs.xml
file, like this:
<?xml version="1.0"?>
<ruleset name="MyProjectCodingStandard">
<rule ref="Brianvarskonst">
<exclude name="PSR1.Classes.ClassDeclaration"/>
</rule>
</ruleset>
In the example above, the PSR1.Classes.ClassDeclaration
sniff (and all the rules it contains) has been removed.
By using PSR1
instead of PSR1.Classes.ClassDeclaration
, you would remove the entire PSR1
standard. Whereas using PSR1.Classes.ClassDeclaration.MultipleClasses
would remove this one rule only, without affecting other rules in the PSR1.Classes.ClassDeclaration
sniff.
Removing a rule/sniff/subset/standard only for a specific file or part of it can be done using special phpcs
annotations/comments. For example, // phpcs:disable
followed by an optional name of a standard/subset/sniff/rule. Like so:
// phpcs:disable PSR1.Classes.ClassDeclaration
For more information about ignoring files, please refer to the official PHP_CodeSniffer Wiki.
After installing the coding standard package as described above, configure PhpStorm to use PHP_CodeSniffer by following these steps:
- Open PhpStorm settings and navigate to:
Language & Frameworks
->PHP
->Quality Tools
->PHP_CodeSniffer
.
-
In the
Configuration
dropdown, selectLocal
. -
Click the
...
button next to the dropdown to open a dialog for specifying the path to the PHP_CodeSniffer executable. -
In the file selection dialog, navigate to
vendor/bin/
in your project directory and selectphpcs
. On Windows, selectphpcs.bat
. -
Click the
Validate
button next to the path input field. If everything is set up correctly, a success message will appear at the bottom of the window. -
Still in the PhpStorm settings, navigate to:
Editor
->Inspections
- In the search field, type
codesniffer
and then select:
PHP
->Quality Tools
->PHP_CodeSniffer validation
-
Enable it by checking the corresponding checkbox and clicking
Apply
. -
Select
PHP_CodeSniffer validation
, then click the refresh icon next to theCoding standard
dropdown on the right and chooseBrianvarskonst
.- If
Brianvarskonst
is not listed, selectCustom
as the standard and use the...
button next to the dropdown to specify thephpcs.xml
file.
- If
Once PhpStorm is integrated with PHP_CodeSniffer, warnings and errors will automatically be highlighted in your IDE editor.
- PHP CodeSniffer
- David Joos's Symfony Coding Standard
- Composer installer for PHP_CodeSniffer coding standards
- Slevomat Coding Standard
- PHPCSStandards / PHPCSUtils
See CONTRIBUTING.md for information.
Copyright (c) 2024, Brianvarskonst under MIT License