Skip to content

2.0

Compare
Choose a tag to compare
@ondrejmirtes ondrejmirtes released this 10 Mar 13:22
· 1954 commits to master since this release

Slevomat Coding Standard 2.0

New major version has been in the works for a long time. Its main focus is to help projects with transition from PHP 5.x to PHP 7.0 and 7.1, but includes a lot of other cool features as well.

All new sniffs are flexible and configurable and although we'd like you to, it's not required to use the coding standard as a whole, you can choose only the sniffs that make sense to you and make your code better.

The release notes only focus on the changes, you can find the complete documentation and manual in the project's README.

🔧 = Automatic errors fixing

🚧 = Sniff check can be suppressed locally using @phpcsSuppress annotation with the name of the sniff

New sniffs:

Functional - improving the safety and behaviour of code

SlevomatCodingStandard.TypeHints.TypeHintDeclaration 🔧🚧

  • Checks for missing property types in phpDoc @var.
  • Checks for missing typehints in case they can be declared natively. If the phpDoc contains something that can be written as a native PHP 7.0 or 7.1 typehint, this sniff reports that.
  • Checks for missing @return and/or native return typehint in case the method body contains return with a value.
  • Checks for useless doc comments. If the native method declaration contains everything and the phpDoc does not add anything useful, it's reported as useless and can optionally be automatically removed with phpcbf.
  • Some phpDocs might still be useful even if they do not add any typehint information. They can contain textual descriptions of code elements and also some meaningful annotations like @expectException or @dataProvider. These annotations that prevent the phpDoc to be marked as useless and removed can be configured in usefulAnnotations property.
  • Forces to specify what's in traversable types like array, iterable and \Traversable. Additional traversable types like custom collections can be configured using traversableTypeHints property.
  • Distinguishes what's possible in PHP 7.0 (scalar typehints) and PHP 7.1 (nullable types and void return typehint).

SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly 🔧

In PHP 7.0, a Throwable interface was added that allows catching and handling errors in more cases than Exception previously allowed. So if the catch statement contained Exception on PHP 5.x, it means it should probably be rewritten to reference Throwable on PHP 7.x. This sniff enforces that.

SlevomatCodingStandard.TypeHints.DeclareStrictTypes 🔧

Enforces having declare(strict_types = 1) at the top of each PHP file. Allows configuring how many newlines should be between the <?php opening tag and the declare statement.

SlevomatCodingStandard.ControlStructures.AssignmentInCondition

Disallows assignments in if, elseif and do-while loop conditions:

if ($file = findFile($path)) {

}

Assignment in while loop condition is specifically allowed because it's commonly used.

This is a great addition to already existing SlevomatCodingStandard.ControlStructures.YodaComparison because it prevents the danger of assigning something by mistake instead of using comparison operator like ===.

SlevomatCodingStandard.ControlStructures.DisallowEqualOperators 🔧

Disallows using loose == and != comparison operators. Use === and !== instead, they are much more secure and predictable.

Cleaning - detecting dead code

SlevomatCodingStandard.Exceptions.DeadCatch

This sniffs finds unreachable catch blocks:

try {
	doStuff();
} catch (\Throwable $e) {
	log($e);
} catch (\InvalidArgumentException $e) {
	// unreachable!
}

Formatting - rules for consistent code looks

SlevomatCodingStandard.Classes.ClassConstantVisibility

In PHP 7.1 it's possible to declare visibility of class constants. In a similar vein to optional declaration of visibility for properties and methods which is actually required in sane coding standards, this sniff also requires to declare visibility for all class constants.

const FOO = 1; // visibility missing!
public const BAR = 2; // correct

On PHP 7.0, this sniff must be manually excluded.

SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing 🔧

Enforces consistent formatting of return typehints, like this:

function foo(): ?int

SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue 🔧

Checks whether the nullablity ? symbol is present before each nullable and optional parameter (which are marked as = null):

function foo(
	int $foo = null, // ? missing
	?int $bar = null // correct
) {

}

On PHP 7.0, this sniff must be manually excluded.

SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing 🔧

  • Checks that there's a single space between a typehint and a parameter name: Foo $foo
  • Checks that there's no whitespace between a nullability symbol and a typehint: ?Foo

SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation

Enforces fully qualified names of classes and interfaces in phpDocs - in @var, @param, @return, @throws. This results in unambiguous phpDocs.

SlevomatCodingStandard.TypeHints.LongTypeHints

Enforces using shorthand scalar typehint variants in phpDocs: int instead of integer and bool instead of boolean. This is for consistency with native scalar typehints which also allow shorthand variants only.

SlevomatCodingStandard.Commenting.ForbiddenAnnotations 🔧

Reports forbidden annotations. No annotations are forbidden by default, the configuration is completely up to the user. It's recommended to forbid obsolete and inappropriate annotations like:

  • @author, @created, @version - we have version control systems
  • @package - we have namespaces
  • @copyright, @license - it's not necessary to repeat licensing information in each file
  • @throws - it's not possible to enforce this annotation and the information can become outdated

SlevomatCodingStandard.Namespaces.DisallowGroupUse

Group use declarations are ugly, make diffs ugly and this sniffs prohibits them.

Enhancements and changes to existing sniffs:

  • Exceptions-related sniffs were updated to support PHP 7.1 exception union types in catch blocks

SlevomatCodingStandard.Classes.UnusedPrivateElements 🚧

  • Checks for unused private constants
  • Supports suppressing reports of unused elements with @phpcsSuppress

SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly 🔧

  • Sniff is now automatically fixable
  • Added option to allow fully qualified name for a class with a colliding use: allowFullyQualifiedNameForCollidingClasses

SlevomatCodingStandard.Files.TypeNameMatchesFileName

  • Allows different file extensions using extensions property

BC breaks:

  • PHP-Parallel-Lint was removed from dependencies to gain flexibility and loosen up dependencies. It is recommended to install and run the tool before running the sniffs because in a lot of instances, sniffs assume they are executed on valid PHP code. When executed on invalid code, they can lead to unexpected results and even infinite loops.