Statistics
259240
198
5
3d
Badges
Dependencies

Slevomat Coding Standard

Latest version Downloads Travis build status AppVeyor build status Code coverage PHPStan

Slevomat Coding Standard for PHP_CodeSniffer provides sniffs that fall into three categories:

  • Functional - improving the safety and behaviour of code
  • Cleaning - detecting dead code
  • Formatting - rules for consistent code looks

Table of contents

  1. Sniffs included in this standard
  1. Installation
  2. How to run the sniffs
  1. Fixing errors automatically
  2. Suppressing sniffs locally
  3. Contributing

Sniffs included in this standard

🔧 = Automatic errors fixing

🚧 = Sniff check can be suppressed locally

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, 7.1 or 7.2 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.
  • Forces to specify what's in traversable types like array, iterable and \Traversable.

Sniff provides the following settings:

  • DEPRECATED enableNullableTypeHints: enforces to transform Foo|null in phpDoc into ?Foo in native typehint.
  • DEPRECATED enableVoidTypeHint: enforces to transform @return void into native void return typehint.
  • enableObjectTypeHint: enforces to transform @param object or @return object into native object typehint. It's on by default if you're on PHP 7.2+
  • traversableTypeHints: enforces which typehints must have specified contained type. E. g. if you set this to \Doctrine\Common\Collections\Collection, then \Doctrine\Common\Collections\Collection must always be supplied with the contained type: \Doctrine\Common\Collections\Collection|Foo[].
  • usefulAnnotations: prevents reporting and removing useless phpDocs if they contain an additional configured annotation like @dataProvider.
  • enableEachParameterAndReturnInspection: enables inspection and fixing of @param and @return annotations separately. Useful when you only want to document parameters or return values that could not be expressed natively (i.e. member types of array or Traversable).

This sniff can cause an error if you're overriding or implementing a parent method which does not have typehints. In such cases add @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint annotation to the method to have this sniff skip it.

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.

Sniff provides the following settings:

  • newlinesCountBetweenOpenTagAndDeclare: allows to set 0 to N newlines to be between <?php and declare
  • newlinesCountAfterDeclare: allows to set 0 to N newlines to be between declare and next statement
  • spacesCountAroundEqualsSign: allows to set number of required spaces around the = operator

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.DisallowYodaComparison 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.

SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator 🔧

Require usage of null coalesce operator when possible.

SlevomatCodingStandard.ControlStructures.EarlyExit 🔧

Require usage of early exit.

Cleaning - detecting dead code

SlevomatCodingStandard.Classes.UnusedPrivateElements 🚧

Although PHP_CodeSniffer is not suitable for static analysis because it is limited to analysing one file at a time, it is possible to use it to perform certain checks. UnusedPrivateElementsSniff checks for unused methods, unused or write-only properties in a class and unused private constants. Reported unused elements are safe to remove.

This is very useful during refactoring to clean up dead code and injected dependencies.

Sniff provides the following settings:

  • alwaysUsedPropertiesAnnotations: mark certain properties as always used, for example the ones with @ORM\Column
  • alwaysUsedPropertiesSuffixes: mark properties with name ending with a certain string to be always marked as used

SlevomatCodingStandard.Namespaces.UnusedUses 🔧

Looks for unused imports from other namespaces.

Sniff provides the following settings:

  • searchAnnotations (defaults to false): enables searching for mentions in annotations, which is especially useful for projects using Doctrine Annotations
  • ignoredAnnotationNames: case sensitive list of annotation names that the sniff should ignore (only the name is ignored, annotation content is still searched). Useful for name collisions like @testCase annotation and TestCase class.

SlevomatCodingStandard.Namespaces.UseFromSameNamespace 🔧

Prohibits uses from the same namespace:

namespace Foo;

use Foo\Bar;

SlevomatCodingStandard.Exceptions.DeadCatch

This sniff finds unreachable catch blocks:

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

Formatting - rules for consistent code looks

SlevomatCodingStandard.Arrays.TrailingArrayComma 🔧

Commas after last element in an array make adding a new element easier and result in a cleaner versioning diff.

This sniff enforces trailing commas in multi-line arrays and requires short array syntax [].

SlevomatCodingStandard.ControlStructures.LanguageConstructWithParentheses 🔧

LanguageConstructWithParenthesesSniff checks and fixes language construct used with parentheses.

SlevomatCodingStandard.ControlStructures.NewWithParentheses 🔧

Require new with parentheses.

SlevomatCodingStandard.ControlStructures.DisallowYodaComparison/RequireYodaComparison 🔧

Yoda conditions decrease code comprehensibility and readability by switching operands around comparison operators forcing the reader to read the code in an unnatural way.

DisallowYodaComparisonSniff looks for and fixes such comparisons not only in if statements but in the whole code.

However, if you prefer Yoda conditions, you can use RequireYodaComparisonSniff.

SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses 🔧

Checks whether uses at the top of a file are alphabetically sorted. Follows natural sorting and takes edge cases with special symbols into consideration. The following code snippet is an example of correctly sorted uses:

use LogableTrait;
use LogAware;
use LogFactory;
use LoggerInterface;
use LogLevel;
use LogStandard;

Sniff provides the following settings:

  • psr12Compatible: sets the required order to classes, functions and constants. Default is PHPStorm compatible: classes, constants and functions.
  • caseSensitive: compare namespaces case sensitively, which makes this order correct:
use LogAware;
use LogFactory;
use LogLevel;
use LogStandard;
use LogableTrait;
use LoggerInterface;

SlevomatCodingStandard.Namespaces.UseSpacing 🔧

Enforces configurable number of lines before first use, after last use and between two different types of use (eg. between use function and use const).

Sniff provides the following settings:

  • linesCountBeforeFirstUse: allows to configure the number of lines before first use.
  • linesCountBetweenUseTypes: allows to configure the number of lines between two different types of use.
  • linesCountAfterLastUse: allows to configure the number of lines after last use.

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.PHP.TypeCast 🔧

Enforces using shorthand cast operators, forbids use of unset and binary cast operators: (bool) instead of (boolean), (int) instead of (integer), (float) instead of (double) or (real). (binary) and (unset) are forbidden.

SlevomatCodingStandard.Files.TypeNameMatchesFileName

For projects not following the PSR-0 or PSR-4 autoloading standards, this sniff checks whether a namespace and a name of a class/interface/trait follows agreed-on way to organize code into directories and files.

Other than enforcing that the type name must match the name of the file it's contained in, this sniff is very configurable. Consider the following sample configuration:

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
	<properties>
		<property name="rootNamespaces" type="array" value="app/ui=>Slevomat\UI,app=>Slevomat,build/SlevomatSniffs/Sniffs=>SlevomatSniffs\Sniffs,tests/ui=>Slevomat\UI,tests=>Slevomat"/>
		<property name="skipDirs" type="array" value="components,forms,model,models,services,stubs,data,new"/>
		<property name="ignoredNamespaces" type="array" value="Slevomat\Services"/>
	</properties>
</rule>

Sniff provides the following settings:

  • rootNamespaces property expects configuration similar to PSR-4 - project directories mapped to certain namespaces.
  • skipDirs are not taken into consideration when comparing a path to a namespace. For example, with the above settings, file at path app/services/Product/Product.php is expected to contain Slevomat\Product\Product, not Slevomat\services\Product\Product.
  • extensions: allow different file extensions. Default is php.
  • ignoredNamespaces: sniff is not performed on these namespaces.

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 declaring visibility for all class constants.

Sniff provides the following settings:

  • fixable: the sniff is not fixable by default because we think it's better to decide about each constant one by one however you can enable fixability with this option.
const FOO = 1; // visibility missing!
public const BAR = 2; // correct

SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing 🔧

Enforces consistent formatting of return typehints, like this:

function foo(): ?int

Sniff provides the following settings:

  • spacesCountBeforeColon: the number of spaces expected between closing brace and colon.

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
) {

}

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.DisallowGroupUse

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

SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword 🔧

Enforces fully qualified type references after configurable set of language keywords.

For example, with the following setting, extended or implemented type must always be referenced with a fully qualified name:

<rule ref="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword">
	<properties>
		<property name="keywordsToCheck" type="array" value="T_EXTENDS,T_IMPLEMENTS"/>
	</properties>
</rule>

SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions 🔧

This sniff reduces confusion in the following code snippet:

try {
	$this->foo();
} catch (Exception $e) {
	// Is this the general exception all exceptions must extend from? Or Exception from the current namespace?
}

All references to types named Exception or ending with Exception must be referenced via a fully qualified name:

try {
	$this->foo();
} catch (\FooCurrentNamespace\Exception $e) {

} catch (\Exception $e) {

}

Sniff provides the following settings:

  • Exceptions with different names can be configured in specialExceptionNames property.
  • If your codebase uses classes that look like exceptions (because they have Exception or Error suffixes) but aren't, you can add them to ignoredNames property and the sniff won't enforce them to be fully qualified. Classes with Error suffix has to be added to ignored only if they are in the root namespace (like LibXMLError).

SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalConstants 🔧

All references to global constants must be referenced via a fully qualified name.

Sniff provides the following settings:

  • exclude: list of global constants that are allowed not to be referenced via FQN.

SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions 🔧

All references to global functions must be referenced via a fully qualified name.

Sniff provides the following settings:

  • exclude: list of global functions that are allowed not to be referenced via FQN.

SlevomatCodingStandard.Namespaces.MultipleUsesPerLine

Prohibits multiple uses separated by commas:

use Foo, Bar;

SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly 🔧

Sniff provides the following settings:

  • searchAnnotations (defaults to false): enables searching for mentions in @var, @param, @return and @throws annotations.
  • namespacesRequiredToUse: if not set, all namespaces are required to be used. When set, only mentioned namespaces are required to be used. Useful in tandem with UseOnlyWhitelistedNamespaces sniff.
  • fullyQualifiedKeywords: allows fully qualified names after certain keywords. Useful in tandem with FullyQualifiedClassNameAfterKeyword sniff.
  • allowFullyQualifiedExceptions, specialExceptionNames & ignoredNames: allows fully qualified exceptions. Useful in tandem with FullyQualifiedExceptions sniff.
  • allowFullyQualifiedNameForCollidingClasses: allow fully qualified name for a class with a colliding use statement.
  • allowFullyQualifiedNameForCollidingFunctions: allow fully qualified name for a function with a colliding use statement.
  • allowFullyQualifiedNameForCollidingConstants: allow fully qualified name for a constant with a colliding use statement.
  • allowFullyQualifiedGlobalClasses: allows using fully qualified classes from global space (i.e. \DateTimeImmutable).
  • allowFullyQualifiedGlobalFunctions: allows using fully qualified functions from global space (i.e. \phpversion()).
  • allowFullyQualifiedGlobalConstants: allows using fully qualified constants from global space (i.e. \PHP_VERSION).
  • allowFallbackGlobalFunctions: allows using global functions via fallback name without use (i.e. phpversion()).
  • allowFallbackGlobalConstants: allows using global constants via fallback name without use (i.e. PHP_VERSION).
  • allowPartialUses: allows using and referencing whole namespaces:

SlevomatCodingStandard.Namespaces.UseOnlyWhitelistedNamespaces

Disallows uses of other than configured namespaces.

Sniff provides the following settings:

  • namespacesRequiredToUse: namespaces in this array are the only ones allowed to be used. E. g. root project namespace.
  • allowUseFromRootNamespace: also allow using top-level namespace:
use DateTimeImmutable;

SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash 🔧

Disallows leading backslash in use statement:

use \Foo\Bar;

SlevomatCodingStandard.Types.EmptyLinesAroundTypeBraces 🔧

Enforces one configurable number of lines after opening class/interface/trait brace and one empty line before the closing brace.

Sniff provides the following settings:

  • linesCountAfterOpeningBrace: allows to configure the number of lines after opening brace.
  • linesCountBeforeClosingBrace: allows to configure the number of lines before closing brace.

SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 🔧

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

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.

Sniff provides the following settings:

  • forbiddenAnnotations: allows to configure which annotations are forbidden to be used.

SlevomatCodingStandard.Commenting.ForbiddenComments 🔧

Reports forbidden comments in descriptions. Nothing is forbidden by default, the configuration is completely up to the user. It's recommended to forbid generated or inappropriate messages like:

  • Constructor.
  • Created by PhpStorm.

Sniff provides the following settings:

  • forbiddenCommentPatterns: allows to configure which comments are forbidden to be used. This is an array of regular expressions (PCRE) with delimiters.

SlevomatCodingStandard.Commenting.DocCommentSpacing 🔧

Enforces configurable number of lines before first content (description or annotation), after last content (description or annotation), between description and annotations, between two different annotations types (eg. between @param and @return).

Sniff provides the following settings:

  • linesCountBeforeFirstContent: allows to configure the number of lines before first content (description or annotation).
  • linesCountBetweenDescriptionAndAnnotations: allows to configure the number of lines between description and annotations.
  • linesCountBetweenDifferentAnnotationsTypes: allows to configure the number of lines between two different annotations types.
  • linesCountAfterLastContent: allows to configure the number of lines after last content (description or annotation).

SlevomatCodingStandard.Commenting.EmptyCommentSniff 🔧

Reports empty comments.

SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration 🔧

Reports invalid format of inline phpDocs with @var.

Installation

The recommended way to install Slevomat Coding Standard is through Composer.

{
	"require-dev": {
		"slevomat/coding-standard": "~4.0"
	}
}

It's also recommended to install jakub-onderka/php-parallel-lint which checks source code for syntax errors. Sniffs count on the processed code to be syntactically valid (no parse errors), otherwise they can behave unexpectedly. It is advised to run PHP-Parallel-Lint in your build tool before running PHP_CodeSniffer and exiting the build process early if PHP-Parallel-Lint fails.

How to run the sniffs

You can choose one of two ways to run only selected sniffs from the standard on your codebase:

Choose which sniffs to run

Mention Slevomat Coding Standard in your project's ruleset.xml:

<?xml version="1.0"?>
<ruleset name="AcmeProject">
	<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml"><!-- relative path to your ruleset.xml -->
		<!-- sniffs to exclude -->
	</rule>
</ruleset>

When running phpcs on the command line, use the --sniffs option to list all the sniffs you want to use separated by a comma:

vendor/bin/phpcs --standard=ruleset.xml \
--sniffs=SlevomatCodingStandard.ControlStructures.DisallowYodaComparison,SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses \
--extensions=php --encoding=utf-8 --tab-width=4 -sp src tests

Or write your own ruleset.xml by referencing the selected sniffs. This is a sample ruleset.xml:

<?xml version="1.0"?>
<ruleset name="AcmeProject">
	<config name="installed_paths" value="../../slevomat/coding-standard"/><!-- relative path from PHPCS source location -->
	<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma"/>
	<!-- other sniffs to include -->
</ruleset>

Then run the phpcs executable the usual way:

vendor/bin/phpcs --standard=ruleset.xml --extensions=php --tab-width=4 -sp src tests

Using all sniffs from the standard

⚠️ This is no longer a recommended way to use Slevomat Coding Standard, because your build can break when moving between minor versions of the standard (which can happen if you use ^ or ~ version constraint in composer.json). We regularly add new sniffs even in minor versions meaning your code won't most likely comply with new minor versions of the package.

If you want to use the whole coding standard, besides requiring slevomat/coding-standard in composer.json, require also Consistence Coding Standard:

{
	"require-dev": {
		"consistence/coding-standard": "~2.0"
	}
}

Then mention both standards in ruleset.xml:

<?xml version="1.0"?>
<ruleset name="AcmeProject">
	<rule ref="vendor/consistence/coding-standard/Consistence/ruleset.xml" />
	<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml" />
	<!-- additional settings -->
</ruleset>

To check your code base for violations, run PHP-Parallel-Lint and PHP_CodeSniffer from the command line:

vendor/bin/parallel-lint src tests
vendor/bin/phpcs --standard=ruleset.xml --extensions=php --tab-width=4 -sp src tests

Fixing errors automatically

Sniffs in this standard marked by the 🔧 symbol support automatic fixing of coding standard violations. To fix your code automatically, run phpcbf instead of phpcs:

vendor/bin/phpcbf --standard=ruleset.xml --extensions=php --tab-width=4 -sp src tests

Always remember to back up your code before performing automatic fixes and check the results with your own eyes as the automatic fixer can sometimes produce unwanted results.

Suppressing sniffs locally

Selected sniffs in this standard marked by the 🚧 symbol can be suppressed for a specific piece of code using an annotation. Consider the following example:

/**
 * @param int $max
 */
public function createProgressBar($max = 0): ProgressBar
{

}

The parameter $max could have a native int scalar typehint. But because the method in the parent class does not have this typehint, so this one cannot have it either. PHP_CodeSniffer shows a following error:

----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 67 | ERROR | [x] Method ErrorsConsoleStyle::createProgressBar()
    |       |     does not have parameter type hint for its parameter $max
    |       |     but it should be possible to add it based on @param
    |       |     annotation "int".
    |       |     (SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint)

If we want to suppress this error instead of fixing it, we can take the error code (SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint) and use it with a @phpcsSuppress annotation like this:

/**
 * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
 * @param int $max
 */
public function createProgressBar($max = 0): ProgressBar
{

}

Contributing

To make this repository work on your machine, clone it and run these two commands in the root directory of the repository:

composer install
bin/phing

After writing some code and editing or adding unit tests, run phing again to check that everything is OK:

bin/phing

We are always looking forward for your bugreports, feature requests and pull requests. Thank you.

Code of Conduct

This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you are expected to uphold this code.

  • 4.4.6 4.4.6

    Fixes:

    • UnusedUsesSniff: Fixed false positives
  • 4.4.5 4.4.5

    Fixes:

    • UnusedUsesSniff: Fixed false positives of case mismatch in doccomments
    • ForbiddenAnnotationsSniff: fixed empty lines when fixer removes annotations
  • 4.4.4 4.4.4

    Fixes:

    • ReferenceUsedNamesOnlySniff: Importing global functions and constants is not necessary in the global namespace
    • ReferenceUsedNamesOnlySniff: Some references were ignored because of bug in allowFullyQualifiedNameForCollidingClasses option
    • EarlyExitSniff: Fixed fixing of complex conditions
    • EarlyExitSniff: Improved fixing conditions with comments
    • EarlyExitSniff: Fixed fixing of two negative conditions
    • UnusedUsesSniff: Case mismatch should be reported in doccomments too
    • UnusedUsesSniff: All occurrences of case mismatch are reported now
    • UseStatementHelper: Anonymous function in function should not be detected as use statement (thanks to @grongor)
  • 4.4.3 4.4.3

    Fixes:

    • EarlyExitSniff: Fixed fixing of negative logical conditions
    • EarlyExitSniff: Fixed fixing of binary AND condition
    • ReferenceUsedNamesOnlySniff: Fixed fixing of types in annotations at the end of line (thanks to @Majkl578)
  • 4.4.2 4.4.2

    Fixes:

    • EarlyExitSniff: Fixed internal exception
    • EarlyExitSniff: Fixed fixer causing parse error
  • 4.4.1 4.4.1

    Fixes:

    • EarlyExitSniff: Fixed false positive
  • 4.4.0 4.4.0

    New sniffs:

    • NewWithParenthesesSniff: Require new with parentheses
    • RequireNullCoalesceOperatorSniff: Require usage of null coalesce operator when possible
    • EarlyExitSniff: Require usage of early exit
    • ForbiddenCommentsSniff: Reports forbidden comments in descriptions (thanks to @Majkl578)

    Improvements:

    • ReferenceUsedNamesOnlySniff: searchAnnotations - Enables searching for mentions in @var, @param, @return and @throws annotations

    Fixes:

    • UnusedPrivateElementsSniff: Properties and methods used in HEREDOC should not be reported as unused
  • 4.3.2 4.3.2

    Fixes:

    • TypeHintDeclarationSniff: Reports more exact error line for @param and @return annotations errors
    • LongTypeHintsSniff: Reports more exact error line
    • AnnotationHelper: Improved annotations parsing
  • 4.3.1 4.3.1

    Fixes:

    • TypeHintDeclarationSniff: Fixed object type variance
    • TypeHintDeclarationSniff: Fixed false positive when description contains variable
    • ReferenceUsedNamesOnlySniff: Fixed support for global functions and constants
    • DeclareStrictTypesSniff: Improved whitespace detection before declare()
    • ReferencedNameHelper: declare() directives should not be considered as referenced name
  • 4.3.0 4.3.0

    Improvements:

    • TypeHintDeclarationSniff: enableObjectTypeHint - It's possible to enable/disable object type hint support
    • ReferenceUsedNamesOnlySniff: Functions and constants support is hopefully complete, see new options in README

    Fixes:

    • ReferenceThrowableOnlySniff: Fixed fixable
    • ReferencedNameHelper: Methods returning reference should not be considered as a referenced name
  • 4.2.1 4.2.1

    Fixes:

    • UnusedPrivateElementsSniff: Fixed false positive for write-only properties
    • AlphabeticallySortedUsesSniff: Fixed support for functions and constants
    • ReferenceUsedNamesOnlySniff: Fixed support for functions and constants
  • 4.2.0 4.2.0

    ⚠️ PHPCS 3.0.2+ is now required.

    Deprecated:

    • ClassConstantVisibilitySniff: enabled - Deprecated now
    • NullableTypeForNullDefaultValueSniff: enabled - Deprecated now
    • TypeHintDeclarationSniff: enableNullableTypeHints - Deprecated now
    • TypeHintDeclarationSniff: enableVoidTypeHint - Deprecated now

    Improvements:

    • UseDoesNotStartWithBackslashSniff: Detects functions and constants now
    • UseDoesNotStartWithBackslashSniff: Sniff is now fixable
    • DeclareStrictTypesSniff: newlinesCountAfterDeclare - Allows to set 0 to N newlines to be between declare and next statement
    • FullyQualifiedGlobalFunctionsSniff: exclude - List of global functions that are allowed not to be referenced via FQN
    • FullyQualifiedGlobalConstantsSniff: exclude - List of global constants that are allowed not to be referenced via FQN
    • ClassConstantVisibilitySniff: Sniff is now fixable (thanks to @Majkl578)
    • ClassConstantVisibilitySniff: fixable - The sniff is not fixable by default because we think it's better to decide about each constant one by one however you can enable fixability with this option
    • LongTypeHintsSniff: Sniff is now fixable

    Fixes:

    • RequireYodaComparisonSniff: Fixed short array support
    • DisallowYodaComparisonSniff: Fixed short array support
    • UnusedPrivateElementsSniff: Fixed false positive for static properties
    • UnusedPrivateElementsSniff: Fixed detection of write only properties
    • UnusedPrivateElementsSniff: Fixed false positive when calling private method on the same class
    • FullyQualifiedGlobalFunctionsSniff: Improved ignoring functions that are not global
    • FullyQualifiedGlobalConstantsSniff: Improved ignoring constants that are not global
    • ReferencedNameHelper: Methods imported from trait should not be detected as referenced names
  • 4.1.0 4.1.0

    ⚠️ PHP 7.1 is now required.

    Improvements:

    • FullyQualifiedExceptionsSniff: Sniff is now fixable (thanks to @VasekPurchart)
    • FullyQualifiedClassNameAfterKeywordSniff: Sniff is now fixable (thanks to @VasekPurchart)
    • FullyQualifiedClassNameInAnnotationSniff: Sniff is now fixable (thanks to @VasekPurchart)

    Fixes:

    • UnusedPrivateElementsSniff: Check for unused private methods is case insensitive now
    • TypeHintDeclarationSniff: Fixed useless doccomment detection when parameters are aligned
    • AnnotationHelper: Fixed parsing of multiline annotations
  • 4.0.0 4.0.0

    ⚠️ Using all sniffs from the standard is no longer a recommended way to use Slevomat Coding Standard, see How to run the sniffs.

    BC breaks:

    • YodaComparisonSniff was renamed to DisallowYodaComparisonSniff

    New sniffs:

    • RequireYodaComparisonSniff: If you prefer Yoda conditions, you can disable DisallowYodaComparison and use this sniff

    Improvements:

    • Basic support of object type hint

    Fixes:

    • TypeHintDeclarationSniff: {@ignoredoc} is case insensitive now
    • UnusedPrivateElementsSniff: Chained private methods should not be reported as unused
    • ReferencedNameHelper: Some references were not recognized
  • 2.5.0 2.5.0

    New checks:

    • TypeHintDeclarationSniff: Checks if closures use void type hint.

    New settings:

    • ReferenceUsedNamesOnlySniff: allowFullyQualifiedGlobalFunctions - allows using fully qualified functions from global space (i.e. \phpversion())
    • ReferenceUsedNamesOnlySniff: allowFullyQualifiedGlobalConstants - allows using fully qualified constants from global space (i.e. \PHP_VERSION)

    Fixes:

    • UseStatement: Constant name are not case insensitive
    • ReferencedNameHelper: Type hints of variadic parameters and parameters passed by reference wasn't recognized
    • TypeHintDeclarationSniff: Methods with {@ignoredoc} format wasn't ignored
    • TypeHintDeclarationSniff: {@ignoredoc} is case insensitive now
    • YodaComparisonSniff: Fixed bugs with logical and, or and xor
    • UnusedPrivateElementsSniff: Fixed false positive
  • 3.3.0 3.3.0

    New sniffs:

    • FullyQualifiedGlobalFunctionsSniff: All references to global functions must be referenced via a fully qualified name
    • FullyQualifiedGlobalConstantsSniff: All references to global constants must be referenced via a fully qualified name

    Fixes:

    • UseStatement: Constant name are not case insensitive
    • ReferencedNameHelper: Type hints of variadic parameters and parameters passed by reference wasn't recognized
  • 3.2.1 3.2.1

    Fixes:

    • TypeHintDeclarationSniff: Methods with {@ignoredoc} format wasn't ignored
    • YodaComparisonSniff: Fixed bugs with logical and, or and xor
  • 3.2.0 3.2.0

    New checks:

    • TypeHintDeclarationSniff: Checks if closures use void type hint.
  • 3.1.2 3.1.2

    Fixes:

    • LanguageConstructWithParenthesesSniff: T_EXIT should be checked too
  • 3.1.1 3.1.1

    Fixes:

    • UnusedPrivateElementsSniff: Fixed infinite loop
  • 3.1.0 3.1.0

    New sniffs:

    • LanguageConstructWithParenthesesSniff: Checks and fixes language construct used with parentheses

    Fixes:

    • UnusedPrivateElementsSniff: Fixed false positive
  • 3.0.5 3.0.5

    Fixes:

    • UnusedPrivateElementsSniff: Fixed false positive
  • 2.4.7 2.4.7

    Fixes:

    • UnusedPrivateElementsSniff: Fixed false positive
  • 2.4.6 2.4.6

    Fixes:

    • YodaComparisonSniff: Fixed comparisons in arrays
    • YodaComparisonSniff: Fixer should not reformat code
  • 3.0.4 3.0.4

    Fixes:

    • YodaComparisonSniff: Fixed comparisons in arrays
    • YodaComparisonSniff: Fixer should not reformat code
  • 3.0.3 3.0.3

    Fixes:

    • TypeHintDeclarationSniff: Parameters are not useless when they have description
    • TypeHintDeclarationSniff: Methods with @inheritdoc are ignored
  • 2.4.5 2.4.5

    Fixes:

    • TypeHintDeclarationSniff: Parameters are not useless when they have description
    • TypeHintDeclarationSniff: Methods with @inheritdoc are ignored
  • 3.0.2 3.0.2

    Fixes:

    • TypeHintDeclarationSniff: Parameters are not useless when they have description
    • TypeNameMatchesFileNameSniff: Improved normalization of "rootNamespaces" settings
    • TypeNameMatchesFileNameSniff: "extensions" settings should be normalized
  • 2.4.4 2.4.4

    Fixes:

    • TypeHintDeclarationSniff: Parameters are not useless when they have description
    • TypeNameMatchesFileNameSniff: Improved normalization of "rootNamespaces" settings
    • TypeNameMatchesFileNameSniff: "extensions" settings should be normalized
  • 3.0.1 3.0.1

    Fixes:

    • TrailingArrayCommaSniff: Should not report errors for empty multiline arrays
    • UnusedUsesSniff: Fixed annotation parsing
  • 2.4.3 2.4.3

    Fixes:

    • TrailingArrayCommaSniff: Should not report errors for empty multiline arrays
    • UnusedUsesSniff: Fixed annotation parsing
  • 3.0.0 3.0.0

    • Updated to PHP CodeSniffer 3
  • 2.4.2 2.4.2

    Fixes:

    • TypeHintDeclarationSniff: Missing traversable specification was not reported for type hints with partial use
  • 2.4.1 2.4.1

    Fixes:

    • TypeHintDeclarationSniff: Missing traversable specification was not reported for unqualified type hints
  • 2.4.0 2.4.0

    • Updated to PHP CodeSniffer 2.9
  • 2.3.0 2.3.0

    New settings:

    • AlphabeticallySortedUsesSniff: caseSensitive - compare namespaces case sensitively (thanks to @VasekPurchart)

    Fixes:

    • AlphabeticallySortedUsesSniff: more compatible with PHPStorm
    • Only PHP CodeSniffer 2.8.* is supported now because PHP CodeSniffer 2.9.0 has broken detection of nullability symbol
  • 2.2.0 2.2.0

    New sniffs:

    • InlineDocCommentDeclarationSniff - reports invalid format of inline phpDocs with @var

    Fixes:

    • FullyQualifiedClassNameInAnnotationSniff supports more ways how to write inline phpDocs
    • Invalid @param annotation should be ignored in TypeHintDeclarationSniff
  • 2.1.0 2.1.0

    New settings:

    • TypeHintDeclarationSniff: enableEachParameterAndReturnInspection - enables inspection and fixing of @param and @return annotations separately. Useful when you only want to document parameters or return values that could not be expressed natively (i.e. member types of array or Traversable) (thanks to @Majkl578)
    • ReturnTypeHintSpacingSniff: spacesCountBeforeColon - the number of spaces expected between closing brace and colon (thanks to @Majkl578)
    • ReferenceUsedNamesOnlySniff: allowFullyQualifiedGlobalClasses - allows using fully qualified names from global space (i.e. \DateTimeImmutable) (thanks to @Majkl578)
    • EmptyLinesAroundTypeBracesSniff: linesCountAfterOpeningBrace: allows to configure the number of lines after opening brace (thanks to @Majkl578)
    • EmptyLinesAroundTypeBracesSniff: linesCountBeforeClosingBrace: allows to configure the number of lines before closing brace (thanks to @Majkl578)

    Fixes:

    • TypeHintDeclarationSniff: Fix UselessDocComment detection when function has parameters/returns, but doesn't have corresponding annotation (thanks to @Majkl578)
    • UnusedUsesSniff: Fix detection of partially referenced functions and constants (thanks to @Majkl578)
    • UseStatementHelper: Fix isTraitUse() to work with anonymous class (thanks to @Majkl578)
    • TypeHintDeclarationSniff: Disabled enableNullableTypeHints does not work with optional parameters
    • FullyQualifiedClassNameAfterKeywordSniff: Improved support for checking T_USE

    And a lot of cleanup (thanks to @VasekPurchart and @Majkl578 )

  • 2.0.2 2.0.2

    • Fixed "TypeHintDeclarationSniff incorrectly reports about missing typehint when parameter docBlock contains union of two types, one is traversable and the second one does not specify the traversable type"
    • Fixed "UnusedPrivateElementsSniff incorrectly reports about methods returning references"
  • 2.0.1 2.0.1

    • Fixed spacesCountAroundEqualsSign settings for DeclareStrictTypesSniff
    • TypeHintDeclaration.UselessDocComment was sometimes reported for generator functions
  • 2.0 2.0

    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.
  • 1.1.1 1.1.1

    • UnusedUsesSniff - when a class implemented multiple interfaces with names listed in uses, the 2nd and next interfaces' use statements were marked as unused. (#55)
    • ReferenceUsedNamesOnlySniff - \Exception, \Throwable and PHP Errors referenced in files without namespace now report ReferenceViaFullyQualifiedNameWithoutNamespace code - consistent behaviour with other names. (f4c1d43)
    • FullyQualifiedExceptionsSniff & ReferenceUsedNamesOnlySniff - added configuration property ignoredNames. It should be used for type names that look like an exception (e. g. end with Exception or Error) but aren't. One example directly from PHP is LibXMLError. The sniffs will not enforce references to these types to be fully qualified. (#52 and #57)
  • 1.1

    • Consistent behaviour for fully qualified Throwable and Errors without any additional configuration (#41)
    • Support for use const and use function in AlphabeticallySortedUsesSniff (#47) - constants and functions are ordered at the end matching behaviour of "Optimize Imports" in PhpStorm
    • Support for use const and use function in UnusedUsesSniff (#43) - use statement will be marked as used only when a matching language construct mentions the used name (use const for referenced constants, use function for invoked functions and classes/interfaces/traits otherwise)
    • UnusedUsesSniff with searchAnnotations set to true (not enabled by default - see README) now searches phpDocs as fulltext (#25) - previously, used name had to be referenced in a listed and supported format. But there are a lot of formats annotations can be written in so the implementation was changed to a simple fulltext search of the used name in all phpDocs in a file.
    • Autoload sniffs in Composer so they can be used in 3rd party apps (#50)
  • 1.0.7 1.0.7

    • Updated dependencies (80f01d0)
    • Fixed phpdoc (78a44c5)
    • Fixed PHPStan configuration so it works on Windows too (cc8a132)
    • Added callable to ReferencedNameHelper (1986b15)
    • UnusedPrivateElementsSniff - optimization for classes without methods (702b989)
    • UnusedPrivateElementsSniff sometimes stopped prematurely after checking properties with multiple modifiers (3a3d1e7)
  • 1.0.6

    • Class constant is not a referenced name (5269229) (#21)
  • 1.0.5

    • Fixed ReferencedNameHelper to return underscored names from annotations (10726ed) (#10 #11)
    • Static analysis with PHPStan (3eaa085) (#13)
    • Normalize array properties (c117fe1) (#12)
  • 1.0.4

    • PHP7: return typehints are included in referenced names (cf23871)
    • Updated Consistence Coding Standard (6ef9a07)
  • 1.0.3

    • UnusedPrivateElementsSniff - fixed handling always-used property annotations (172a023)
  • 1.0.2

    • Fixed YodaComparisonSniff for negative or plus-prepended expressions (1a53b21)
    • ReferencedNameHelper - search in complex annotations (e. g. \Foo|\Bar) (46cd765)
    • UnusedPrivateElementsSniff - do not report private constructor (9dd9738)
    • UnusedPrivateElementsSniff - configurable always-used properties (f39a5e6)
    • ReferencedNameHelper - result contains traits used in a class (d93b9d4)
  • 1.0.1

    Fix FilepathNamespaceExtractor on Windows

  • 1.0.0 First stable open-source release

Is this addon outdated? Did you find an issue? Please report it.

Componette Componette admin@componette.com