Set of rules for PHP_CodeSniffer preferring tabs and based on Nette coding standard.
Check rules overview for examples.
$ composer require zenify/coding-standard --dev
Run with Php_CodeSniffer:
vendor/bin/phpcs src --standard=vendor/zenify/coding-standard/src/ZenifyCodingStandard/ruleset.xml -p
That's all!
In case you don't want to use Php_CodeSniffer manually for every change in the code you make, you can add pre-commit hook via composer.json
:
"scripts": {
"post-install-cmd": [
"Zenify\\CodingStandard\\Composer\\ScriptHandler::addPhpCsToPreCommitHook"
],
"post-update-cmd": [
"Zenify\\CodingStandard\\Composer\\ScriptHandler::addPhpCsToPreCommitHook"
]
}
Every time you try to commit, Php_CodeSniffer will run on changed .php
files only.
This is much faster than checking whole project, running manually or wait for CI.
Pretty cool, huh?
composer check-cs
vendor/bin/phpunit
Rules are simple:
- new feature needs tests
- all tests must pass
- 1 feature per PR
We would be happy to merge your feature then!
Rules uses default numeric parameters (some can be changed to match your needs).
TOC:
- Opening brace for the class should be followed by 1 empty line
- Closing brace for the class should be preceded by 1 empty line
Correct
class SomeClass
{
public function run()
{
}
}
Wrong
class SomeClass
{
public function run()
{
}
}
- Non-abstract class that implements interface should be final.
- Except for Doctrine entities, they cannot be final.
Correct
final class SomeClass implements SomeInterface
{
public function run()
{
}
}
Wrong
class SomeClass implements SomeInterface
{
public function run()
{
}
}
- Block comment should be used instead of one liner
Correct
class SomeClass
{
/**
* @var int
*/
public $count;
}
Wrong
class SomeClass
{
/** @var int */
public $count;
}
- CreateComponent* method should have a doc comment
- CreateComponent* method should have a return tag
- Return tag should contain type
Correct
/**
* @return DisplayComponent
*/
protected function createComponentDisplay()
{
$this->displayComponentFactory->create();
}
Wrong
protected function createComponentDisplay()
{
$this->displayComponentFactory->create();
}
- Property should have docblock comment.
Correct
class SomeClass
{
/**
* @var int
*/
private $someProperty;
}
Wrong
class SomeClass
{
private $someProperty;
}
- Method without parameter typehints should have docblock comment.
Correct
class SomeClass
{
/**
* @param int $values
*/
public function count($values)
{
}
}
class SomeClass
{
public function count(array $values)
{
}
}
Wrong
class SomeClass
{
public function count($values)
{
}
}
- Getters should have @return tag or return type.
Correct
class SomeClass
{
/**
* @return int
*/
public function getResult()
{
// ...
}
}
Wrong
class SomeClass
{
/**
* This will return something.
*/
public function getResult()
{
}
}
- New class statement should not have empty parentheses
Correct
$someClass = new SomeNamespace\SomeClass;
$someClass = new SomeNamespace\SomeClass($keyHandler);
Wrong
$someClass = new SomeNamespace\SomeClass();
Correct
$suit = 'case';
switch ($suit) {
case 1:
echo 'ok';
break;
default:
echo 'not ok';
break;
}
Wrong
$suit = 'case';
switch ($suit) {
case 1:
echo 'ok';
break;
}
- Yoda condition should not be used; switch expression order
Correct
if ($i === TRUE) {
return;
}
$go = $decide === TRUE ?: FALSE;
Wrong
if (TRUE === $i) {
return;
}
$go = TRUE === $decide ?: FALSE;
- Debug functions should not be left in the code
Wrong
dump('It works');
- There must be 2 empty lines after the namespace declaration or 1 empty line followed by use statement.
Correct
namespace SomeNamespace;
use PHP_CodeSniffer;
class SomeClass
{
}
or
namespace SomeNamespace;
class SomeClass
{
}
Wrong
namespace SomeNamespace;
use SomeNamespace;
class SomeClass
{
}
or
namespace SomeNamespace;
class SomeClass
{
}
- There must be one USE keyword per declaration
- There must be 2 blank lines after the last USE statement
Correct
namespace SomeNamespace;
use Sth;
use SthElse;
class SomeClass
{
}
Wrong
namespace SomeNamespace;
use Sth, SthElse;
class SomeClass
{
}
- Abstract class should have prefix "Abstract"
Correct
abstract class AbstractClass
{
}
Wrong
abstract class SomeClass
{
}
- Interface should have suffix "Interface"
Correct
interface SomeInterface
{
}
Wrong
interface Some
{
}
- DocBlock lines should start with space (except first one)
Correct
/**
* Counts feelings.
*/
public function ...
Wrong
/**
* Counts feelings.
*/
public function ...
- Not operator (!) should be surrounded by spaces
Correct
if ( ! $s) {
return $s;
}
Wrong
if (!$s) {
return $s;
}
- Else/elseif/catch/finally statement should be preceded by 1 empty line
Correct
if ($i === 1) {
return $i;
} else {
return $i * 2;
}
Wrong
try (1 === 2) {
return 3;
} catch (2 === 3) {
return 4;
} finally (2 === 3) {
return 4;
}
- Method should have 2 empty lines after itself
Correct
class SomeClass
{
public function run()
{
}
public function go()
{
}
}
Wrong
class SomeClass
{
public function run()
{
}
public function go()
{
}
}
- Between properties and methods should be 2 empty lines
Correct
class SomeClass
{
private $jet;
public function run()
{
}
}
Wrong
class SomeClass
{
private $jet;
public function run()
{
}
}