-
-
Notifications
You must be signed in to change notification settings - Fork 73
Version 4.0 Developer Upgrade Guide
Caution
PHP_CodeSniffer 4.0.0 is currently in the pre-release phase. The information in this upgrade guide is subject to change until PHP_CodeSniffer 4.0.0 has been released.
If you find errors in this upgrade guide or would like to contribute improvements based on tests you've run with a PHP_CodeSniffer 4.0 pre-release, please open an issue.
PHP_CodeSniffer version 4.0.0 contains a number of core changes and breaks backwards compatibility in select situations. The aim of this guide is to help sniff developers and integrators to upgrade from PHP_CodeSniffer version 3.x to version 4.x.
Note
A certain level of technical understanding of PHP_CodeSniffer is presumed for readers of this upgrade guide.
There is a separate Upgrade Guide for Ruleset Maintainers and End-Users available.
- Should I upgrade ?
- Upgrading the ruleset.xml file
- Upgrading Standards
-
Upgrading Custom Sniffs
- Sniffs need to comply with the naming conventions
- Sniffs must implement the
PHP_CodeSniffer\Sniffs\Sniff
interface - Support for JS/CSS has been removed
- Property type casting has been made more consistent
- Changed Methods
- Tokens class changes
- Tokenizer Changes
- Changes to abstract sniffs
- Changes to PHPCS native sniffs
- Miscellaneous other changes which may affect code extending PHP_CodeSniffer
- Unit Tests
It is highly recommended to upgrade external standards and integrations as soon as you are able.
Once PHP_CodeSniffer 4.0 has been released, the PHP_CodeSniffer 3.x branch will no longer receive updates, with the exception of security fixes and runtime compatibility fixes for new PHP versions. This "limited support" will last a maximum of one year from the date of the PHP_Codesniffer 4.0.0 release.
Important
This also means that support for new PHP syntaxes will only land in PHP_CodeSniffer 4.x and will NOT be backported to the 3.x branch.
There are basically two upgrade strategies:
- Drop support for PHP_CodeSniffer 3.x completely and adopt support for PHP_CodeSniffer 4.x.
- Make your package cross-version compatible with both PHP_CodeSniffer 3.x as well as 4.x.
Which strategy is best suited for your project will depend on your userbase.
If your userbase is known to often combine multiple external standards, making the package PHPCS cross-version compatible may be preferred to allow users to upgrade as soon as possible, while still benefitting from updates to your package if they can't upgrade to PHPCS 4.x yet.
The fast majority of the below upgrade tasks will need to be executed in both cases, but there are some upgrade tasks which can only be executed once support for PHP_CodeSniffer 3.x is being dropped.
See the Upgrade Guide for Ruleset Maintainers and End-Users for everything you need to know about upgrading the ruleset.xml
file.
In the exceptional situation that your custom PHP_CodeSniffer standard is called Internal
, you will need to rename the standard and the namespace used by all sniffs in the standard.
When renaming, make sure to follow all naming conventions for standards and sniffs as outlined in About Standards.
The naming conventions for sniffs have not changed, but will be enforced strictly as of PHP_CodeSniffer 4.0.
If any of your sniffs do not comply with the directory layout and naming conventions for external standards, PHPCS 3.13.x will alert you with a deprecation notice.
Please carefully read the naming conventions for standards and sniffs as outlined in About Standards to find out how to fix your sniffs.
... either directly or indirectly via an abstract sniff. This is now actively enforced.
PHP_CodeSniffer 3.13.0 will throw a deprecation notice for any sniffs which don't implement the interface. As of PHP_CodeSniffer 4.0.0, PHP_CodeSniffer will error out on such sniffs.
Support for the JS/CSS tokenizers has been removed. To cause the least amount of friction, this has been executed as follows:
- Sniffs which specify the
$supportedTokenizers
property and don't include'PHP'
in the array value will no longer run on PHPCS 4.0. The end-user will be shown an error message about this and PHP_CodeSniffer will exit with this error. This error message can be silenced by implementing thePHP_CodeSniffer\Sniffs\DeprecatedSniff
interface (PHPCS 3.9.0+) to mark the sniff as deprecated. In that case, the sniff will show a deprecation notice when running on PHPCS 3.x and the sniff will be silently ignored on PHPCS 4.x. - Sniffs which specify the
$supportedTokenizers
property and include both'PHP'
as well as something else, will run against the scanned files, with all files being treated as PHP, as of PHPCS 4.0.0 and will not cause any notices about the sniff to be shown to the end-user.
This has been implemented in this way to allow external standards to be cross-version compatible with PHPCS 3.x as well as 4.x for a while and to not force external standards to release a new major release to support PHPCS 4.0 (due to sniffs needing to be removed).
Search for sniffs which specify the public $supportedTokenizers
property to find sniffs which may need updating.
Making sniffs cross-version compatible:
- Mark sniffs which are only aimed at CSS/JS files as deprecated by implementing the
PHP_CodeSniffer\Sniffs\DeprecatedSniff
interface (PHPCS 3.9.0+) if your standard still intends to support PHPCS 3.x for a while. - The
$phpcsFile->tokenizerType
property has been removed in PHPCS 4.0. Make sure that any code which checks the$phpcsFile->tokenizerType
property, first checks whether that property is available before accessing its value.
Dropping support for PHPCS 3.x:
- Remove sniffs which are only aimed at CSS/JS files.
- For mixed sniffs, which also scan PHP files, remove any code which is specific to the scanning of CSS/JS files, including removing the
public $supportedTokenizers
property declaration and checking of the$phpcsFile->tokenizerType
property.
Type casting for sniff property values set from within a ruleset has been made more consistent.
-
true
andfalse
will now always be set to a boolean value, independently of the case in which the value was provided. -
null
will now be set to an actualnull
value. Previously, the sniff property would have been set to string'null'
. - Array element values will now also get the type casting treatment. Previously, array values would always be strings.
Search for sniff which have public
properties which can be changed from within a ruleset.
- If the sniff has work-arounds in place to handle non-lowercase string
'true'
or'false'
values for boolean properties, those work-arounds can be removed. - If the sniff has work-arounds in place to handle (any case) string
'null'
values, those work-arounds can be removed. - If the sniff explicitly expects only string values for array elements, the sniff may need to be updated.
- If the sniff has work-arounds in place to handle the type casting of
true
,false
and/ornull
for array elements, those work-arounds can be removed.
The File::getDeclarationName()
method no longer accepts T_ANON_CLASS
or T_CLOSURE
tokens. Getting the "name" of an anonymous construct is an oxymoron. A RuntimeException
will be thrown if the method receives these tokens.
Additionally, when a name could not be determined, like during live coding, the method used to return null
. Now, it will return an empty string.
It is recommended to search your codebase for all uses of the File::getDeclarationName()
method and to review whether the code needs updating.
Typically:
- Verify that the sniff does not pass anonymous constructs to the method.
If necessary, either add guard-code to prevent this, or wrap the method call in a
try ... catch
. - Verify if the return value of the method is checked correctly.
For PHPCS cross-version compatibility, check the return value with
empty($name)
. If cross-version compatibility is not a concern, replace checks againstnull
with a check against an empty string.$name = $phpcsFile->getDeclarationName($stackPtr); -if ($name === null) { +if ($name === '') { // PHPCS 4.0+ +if (empty($name)) { // PHPCS cross-version compatible. return; }
The File::getMemberProperties()
method used to be inconsistent in how it handled variable tokens which were not property declarations.
- In most cases ("normal" variable, function parameter), it would throw a
RuntimeException
"'$stackPtr is not a class member var'". - However, for "properties" declared in an
enum
orinterface
construct, it would register a warning about a possible parse error and return an empty array.
This parse error warning has now been removed.
As, as of PHP 8.4, declaring (hooked) properties in an interface is no longer a parse error (see the Property Hooks RFC), properties declared in interfaces will now be accepted for analysis by the function and will return an array of information about the property.
For "properties" declared in enums, which is still not allowed in PHP, the method will throw the "'$stackPtr is not a class member var'" RuntimeException
.
The above is significant change in behaviour and how it needs to be handled will depend on the sniff calling the method.
It is recommended to search your codebase for all uses of the File::getMemberProperties()
method and to review whether the code needs updating.
Typically:
- If the sniff itself already guards against passing non-properties to the method, you should be fine.
- If the sniff has the method call wrapped within a
try ... catch
, you should also be fine. - If neither of the above is the case, apply one of the two above mentioned solutions.
In all cases, checking the return value of the method for being an empty array is no longer needed and such code can be removed.
Also, in all cases, the sniff may need to start taking PHP 8.4 properties on interfaces into account, but that's another matter altogether.
... and the associated private Config::$overriddenDefaults
property is also no longer static.
In practice, this means that two consecutively created Config
objects without the same process will now contain the same settings. Previously, settings overridden in the first Config instance, could not be set for the second Config instance.
Typically, this may impact projects which call new Config
consecutive times programmatically, whether it is for a custom integration or for a custom test suite.
Typical work-arounds for the old behaviour will use Reflection
to reset the Config::$overriddenDefaults
property between instantiations.
These type of work-arounds can now be removed.
All token arrays declared as static properties in the Tokens
class are now soft-deprecated.
When dropping support for PHP_CodeSniffer 3.x, start using the corresponding constants on the Tokens
class instead.
Search for | Replace with |
---|---|
Tokens::$weightings |
Tokens::getHighestWeightedToken() |
Tokens::$assignmentTokens |
Tokens::ASSIGNMENT_TOKENS |
Tokens::$equalityTokens |
Tokens::EQUALITY_TOKENS |
Tokens::$comparisonTokens |
Tokens::COMPARISON_TOKENS |
Tokens::$arithmeticTokens |
Tokens::ARITHMETIC_TOKENS |
Tokens::$operators |
Tokens::OPERATORS |
Tokens::$booleanOperators |
Tokens::BOOLEAN_OPERATORS |
Tokens::$castTokens |
Tokens::CAST_TOKENS |
Tokens::$parenthesisOpeners |
Tokens::PARENTHESIS_OPENERS |
Tokens::$scopeOpeners |
Tokens::SCOPE_OPENERS |
Tokens::$scopeModifiers |
Tokens::SCOPE_MODIFIERS |
Tokens::$methodPrefixes |
Tokens::METHOD_MODIFIERS |
Tokens::$blockOpeners |
Tokens::BLOCK_OPENERS |
Tokens::$emptyTokens |
Tokens::EMPTY_TOKENS |
Tokens::$commentTokens |
Tokens::COMMENT_TOKENS |
Tokens::$phpcsCommentTokens |
Tokens::PHPCS_ANNOTATION_TOKENS |
Tokens::$stringTokens |
Tokens::STRING_TOKENS |
Tokens::$textStringTokens |
Tokens::TEXT_STRING_TOKENS |
Tokens::$bracketTokens |
Tokens::BRACKET_TOKENS |
Tokens::$includeTokens |
Tokens::INCLUDE_TOKENS |
Tokens::$heredocTokens |
Tokens::HEREDOC_TOKENS |
Tokens::$functionNameTokens |
Tokens::FUNCTION_NAME_TOKENS |
Tokens::$ooScopeTokens |
Tokens::OO_SCOPE_TOKENS |
Tokens::$magicConstants |
Tokens::MAGIC_CONSTANTS |
Tokens::$contextSensitiveKeywords |
Tokens::CONTEXT_SENSITIVE_KEYWORDS |
The following tokens have been removed:
Name | Remark |
---|---|
T_ARRAY_HINT |
This token was deprecated in PHPCS 3.3.0 and has been unused since that time. |
T_RETURN_TYPE |
This token was deprecated in PHPCS 3.3.0 and has been unused since that time. |
T_PROTOTYPE |
Token was specific to the JS tokenizer. |
T_THIS |
Token was specific to the JS tokenizer. |
T_REGULAR_EXPRESSION |
Token was specific to the JS tokenizer. |
T_PROPERTY |
Token was specific to the JS tokenizer. |
T_LABEL |
Token was specific to the JS tokenizer. |
T_OBJECT |
Token was specific to the JS tokenizer. |
T_CLOSE_OBJECT |
Token was specific to the JS tokenizer. |
T_TYPEOF |
Token was specific to the JS tokenizer. |
T_ZSR |
Token was specific to the JS tokenizer. |
T_ZSR_EQUAL |
Token was specific to the JS tokenizer. |
T_COLOUR |
Token was specific to the CSS tokenizer. |
T_HASH |
Token was specific to the CSS tokenizer. |
T_URL |
Token was specific to the CSS tokenizer. |
T_STYLE |
Token was specific to the CSS tokenizer. |
T_EMBEDDED_PHP |
Token was specific to the CSS tokenizer. |
If these tokens are used in PHP-only sniffs, they can be safely removed. If these tokens are used in JS/CSS only sniffs, as mentioned in "Support for JS/CSS has been removed": deprecate or remove the sniff. If these tokens are used in mixed sniffs, which also scan PHP files, remove the CSS/JS specific code or, for cross-version compatibility, check for the existance of the tokens before using them.
These tokens have been added to the Tokens::$parenthesisOpeners
array and will now get the parenthesis_owner
, parenthesis_opener
and parenthesis_closer
token indexes if parentheses were found (i.e. not import/trait use, not exit/die without parentheses, not parse error).
- Check if any of your sniffs/code uses the
Tokens::$parenthesisOpeners
array. It is generally discouraged to use that token array as it is mostly intended for internal use by PHPCS itself, but if you do use it, be aware that the above mentioned tokens have been added to the array. You may want to exclude them from your sniff, or in case ofT_USE
, you may need to validate that it is a closureuse
token and not an import/traituse
token before acting on the token. - Search your codebase for
T_USE
,T_ISSET
,T_UNSET
,T_EMPTY
,T_EVAL
,T_EXIT
. Anywhere the parentheses for those tokens are "manually" determined, either for use in the sniff or to skip over them, you can now use theparenthesis_owner
,parenthesis_opener
andparenthesis_closer
keys instead.
The tokenization of identifier names has changed.
This change was made in PHP itself in 8.0 and was "undone" in PHP_CodeSniffer for the PHPCS 3.x releases. As of PHPCS 4.0, identifier names will tokenize following the PHP 8.0+ tokenization.
The following type of code is affected:
Code | PHPCS 3.x tokenization | PHPCS 4.x tokenization |
---|---|---|
functionName() |
T_STRING + parentheses |
T_STRING + parentheses |
Partially\qualified() |
T_STRING , T_NS_SEPARATOR , T_STRING + parentheses |
T_NAME_QUALIFIED + parentheses |
\Fully\qualified() |
T_NS_SEPARATOR , T_STRING , T_NS_SEPARATOR , T_STRING + parentheses |
T_NAME_FULLY_QUALIFIED + parentheses |
namespace\qualified() |
T_NAMESPACE , T_NS_SEPARATOR , T_STRING + parentheses |
T_NAME_RELATIVE + parentheses |
A new Tokens::NAME_TOKENS
token array containing the set of tokens used for tokenizing identifier names in PHPCS 4.x has been introduced to assist with mitigating this change.
The Tokens::FUNCTION_NAME_TOKENS
token array, as well as the deprecated Tokens::$functionNameTokens
, now also contains all identifier name tokens.
Typically, search your code base for use of the Tokens::$functionNameTokens
token array, T_NS_SEPARATOR
, T_NAMESPACE
and T_STRING
tokens and review whether the sniff/code is examining identifier names. If so, update the code to allow for the new tokens.
You may also want to search for checks involving T_TRUE
, T_FALSE
and T_NULL
tokens, as if these are used in a fully qualified form, they will now tokenize as T_NAME_FULLY_QUALIFIED
, so sniffs may need to take this into account.
Tip
If you want to forbid the use of the fully qualified form of true
/false
/null
, PHPCSExtra offers the Universal.PHP.NoFQNTrueFalseNull
sniff, which will do just that.
The static
keyword is normally tokenized as T_STATIC
. However, there was one (odd) exception: instanceof static
. In that case, the static
keyword was tokenized as T_STRING
.
This re-tokenization has now been removed.
- Search your sniffs/code for
T_INSTANCEOF
and'static'
to find any potential work-arounds in place for the old tokenization. Those can now be removed.
Long open tags will no longer include any whitespace. Previously the T_OPEN_TAG
when used for long open tags could potentially include a single space or a new line character.
Any potential whitespace previously included will now be tokenized as T_WHITESPACE
following the normal whitespace tokenization rules.
Note
Short open tags, whether <?
with short_open_tags=on
, or <?=
(T_OPEN_TAG_WITH_ECHO
) already didn't contain any whitespace in the token contents.
- Search your sniffs/code for any code specifically checking
T_OPEN_TAG
tokens and whitespace contained in the token. - Search for
new PHP('<?php ...
to check if whatever is being done there needs to take the split off of the whitespace into account.
The T_GOTO_LABEL
token used to be joined with the :
following it and would include the colon in the token 'content'
. This has been undone and the label and the colon will now be tokenized as separate tokens, T_GOTO_LABEL
and T_GOTO_COLON
respectively.
And loosely related to this, if a PHP keyword is used as a label in a goto
statement (= parse error), it will now be tokenized as T_STRING
to prevent confusing sniffs.
"Semi-keywords", which are allowed as labels, will now consistently be tokenized as T_STRING
when used in a goto
statement.
To illustrate:
goto bar; // T_GOTO T_WHITESPACE T_STRING.
echo 'hi';
bar: // T_GOTO_LABEL T_GOTO_COLON (was one token, T_GOTO_LABEL, with the colon included in the content).
haveSomeWater();
goto true; // T_GOTO T_WHITESPACE T_STRING (was T_GOTO T_WHITESPACE T_TRUE).
echo 'hi';
true: // T_GOTO_LABEL T_GOTO_COLON (was one token, T_GOTO_LABEL, with the colon included in the content).
doSomething();
- Search your sniffs/code for any code looking for
T_GOTO
orT_GOTO_LABEL
tokens and evaluate if the code needs updating.
-
All
T_DOC_COMMENT_*
tokens will now have thecomment_opener
andcomment_closer
indexes set. This should allow for more flexibility for sniffs examining aspects of docblocks. -
The
Tokens::FUNCTION_NAME_TOKENS
token array, as well as the deprecatedTokens::$functionNameTokens
, now also contains theT_ANON_CLASS
token. If you use this token array in your sniffs, you will need to evaluate whether this is a desired change or will need excluding.
The AbstractPatternSniff::__construct()
method no longer takes any arguments. The $ignoreComments
parameter was deprecated in PHPCS 1.4.0.
Since PHPCS 1.4.0, the AbstractPatternSniff sets the ignoreComments
option using a public
var rather than through the constructor.
This allows the setting to be overwritten in ruleset.xml
files.
- Search for sniffs which extend the
AbstractPatternSniff
. - If the sniff calls the
parent::__construct()
method with an argument, remove the argument. - Overload the
public $ignoreComments
property instead.
If you have a custom sniff which extends any of the following classes AND has a custom processVariable()
or processVariableInString()
method, the sniff will break as those methods will no longer be called.
PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidVariableNameSniff
PHP_CodeSniffer\Standards\PSR2\Sniffs\Classes\PropertyDeclarationSniff
PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\VariableCommentSniff
PHP_CodeSniffer\Standards\Squiz\Sniffs\Scope\MemberVarScopeSniff
PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\MemberVarSpacingSniff
- Search for the above mentioned sniff class names and check if any of your sniffs
extend
these. - Check if the sniff has a non-empty
processVariable()
orprocessVariableInString()
method. - If so, add the following to the sniff to revert to the old behaviour:
public function __construct() { AbstractVariableSniff::__construct(); }
The protected
getDeclarationNameWithNamespace()
and getNamespaceOfScope()
methods have been removed.
- Search for the above mentioned sniff class name and check if any of your sniffs
extend
this and uses either of the two removed methods. - Refactor your code to use the new
PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\SelfMemberReferenceSniff::getNamespaceName()
method instead.
-
The
PHP_CodeSniffer\Config::setSettings()
method no longer returns any value. It was always declared as avoid
method, but was previously returning the set value. -
The
PHP_CodeSniffer\Config::printConfigData()
method is deprecated and should no longer be used. Useecho Config::prepareConfigDataForDisplay()
instead once support for PHPCS 3.x is being dropped. -
The signature of the
DummyFile::setErrorCounts()
method has changed and now expects the following parameters:$errorCount, $warningCount, $fixableErrorCount, $fixableWarningCount, $fixedErrorCount, $fixedWarningCount
. -
The abstract
PHP_CodeSniffer\Filters\ExactMatch::getBlacklist()
andPHP_CodeSniffer\Filters\ExactMatch::getWhitelist()
methods have been replaced with abstractPHP_CodeSniffer\ExactMatch::getDisallowedFiles()
andPHP_CodeSniffer\ExactMatch::getAllowedFiles()
methods. If you have custom classes which extend theExactMatch
class, implement the newgetDisallowedFiles()
andgetAllowedFiles()
methods instead. Note: this is a name change only. The functionality remains the same. -
Various
print*(): void
methods in the Generator classes have been removed in favour ofget*(): string
methods. If you extend any of theGenerator
classes...:Search for Replace with PHP_CodeSniffer\Generators\Text::printTitle()
PHP_CodeSniffer\Generators\Text::getFormattedTitle()
PHP_CodeSniffer\Generators\Text::printTextBlock()
PHP_CodeSniffer\Generators\Text::getFormattedTextBlock()
PHP_CodeSniffer\Generators\Text::printCodeComparisonBlock()
PHP_CodeSniffer\Generators\Text::getFormattedCodeComparisonBlock()
PHP_CodeSniffer\Generators\Markdown::printHeader()
PHP_CodeSniffer\Generators\Markdown::getFormattedHeader()
PHP_CodeSniffer\Generators\Markdown::printFooter()
PHP_CodeSniffer\Generators\Markdown::getFormattedFooter()
PHP_CodeSniffer\Generators\Markdown::printTextBlock()
PHP_CodeSniffer\Generators\Markdown::getFormattedTextBlock()
PHP_CodeSniffer\Generators\Markdown::printCodeComparisonBlock()
PHP_CodeSniffer\Generators\Markdown::getFormattedCodeComparisonBlock()
PHP_CodeSniffer\Generators\HTML::printHeader()
PHP_CodeSniffer\Generators\HTML::getFormattedHeader()
PHP_CodeSniffer\Generators\HTML::printToc()
PHP_CodeSniffer\Generators\HTML::getFormattedToc()
PHP_CodeSniffer\Generators\HTML::printFooter()
PHP_CodeSniffer\Generators\HTML::getFormattedFooter()
PHP_CodeSniffer\Generators\HTML::printTextBlock()
PHP_CodeSniffer\Generators\HTML::getFormattedTextBlock()
PHP_CodeSniffer\Generators\HTML::printCodeComparisonBlock()
PHP_CodeSniffer\Generators\HTML::getFormattedCodeComparisonBlock()
-
The
PHP_CodeSniffer\Reporter::$startTime
property has been removed. This property was unused since PHPCS 3.0.0. -
The
PHP_CodeSniffer\Reporter::$totalFixable
andReporter::$totalFixed
properties are deprecated and should no longer be used. Use respectively(Reporter::$totalFixableErrors + Reporter::$totalFixableWarnings)
and(Reporter::$totalFixedErrors + Reporter::$totalFixedWarnings)
instead. -
PHP_CodeSniffer\Ruleset::setSniffProperty()
: the BC-layer supporting the old array format for the$settings
parameter for the method has been removed. The$settings
parameter must be passed as an array with the following two keys:'scope'
and'value'
, with'scope'
being set to either'sniff'
or'standard'
, and'value'
containing the new property value. Also see https://github.com/squizlabs/PHP_CodeSniffer/pull/3629 -
Various class properties have been replaced with class constants. Where these were in the public API (= the below list), the properties still exist, but are now (soft) deprecated and will be removed in PHP_CodeSniffer 5.0. The visibility of the (deprecated) properties and their class constant replacements is the same. If you previously overloaded one of these properties in a custom sniff extending one of the affected sniffs, you will now need to overload the class constant. To obtain cross-version compatibility with PHPCS 3.x as well as 4.x, you may need to overload both the property as well as the constant.
Search for | Replace with | Notes |
---|---|---|
(public ) PHP_CodeSniffer\Util\Common::$allowedTypes
|
PHP_CodeSniffer\Util\Common::ALLOWED_TYPES |
|
(public ) PHP_CodeSniffer\Tokenizers\PHP::$tstringContexts
|
PHP_CodeSniffer\Tokenizers\PHP::T_STRING_CONTEXTS |
|
(protected ) PHP_CodeSniffer\Sniffs\AbstractVariableSniff::$phpReservedVars
|
PHP_CodeSniffer\Sniffs\AbstractVariableSniff::PHP_RESERVED_VARS |
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$magicMethods
|
PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::MAGIC_METHODS |
This also affects the PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff class which extends the CamelCapsFunctionNameSniff
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$methodsDoubleUnderscore
|
PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::DOUBLE_UNDERSCORE_METHODS |
This also affects the PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff class which extends the CamelCapsFunctionNameSniff
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$magicFunctions
|
PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::MAGIC_FUNCTIONS |
This also affects the PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff class which extends the CamelCapsFunctionNameSniff
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\Files\ByteOrderMarkSniff::$bomDefinitions
|
PHP_CodeSniffer\Standards\Generic\Sniffs\Files\ByteOrderMarkSniff::BOM_DEFINITIONS |
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\Files\InlineHTMLSniff::$bomDefinitions
|
PHP_CodeSniffer\Standards\Generic\Sniffs\Files\InlineHTMLSniff::BOM_DEFINITIONS |
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\CharacterBeforePHPOpeningTagSniff::$bomDefinitions
|
PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\CharacterBeforePHPOpeningTagSniff::BOM_DEFINITIONS |
|
(protected ) PHP_CodeSniffer\Standards\Generic\Sniffs\VersionControl\SubversionPropertiesSniff::$properties
|
PHP_CodeSniffer\Standards\Generic\Sniffs\VersionControl\SubversionPropertiesSniff::REQUIRED_PROPERTIES |
|
(protected ) PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FileCommentSniff::$tags
|
PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FileCommentSniff::EXPECTED_TAGS |
This also affects the PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\ClassCommentSniff class which extends the FileCommentSniff
|
(protected ) PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::$magicMethods
|
PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::MAGIC_METHODS |
|
(protected ) PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::$magicFunctions
|
PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::MAGIC_FUNCTIONS |
This also affects the PHP_CodeSniffer\Standards\Squiz\Sniffs\NamingConventions\ValidFunctionNameSniff class which extends the PEAR ValidFunctionNameSniff
|
(protected ) PHP_CodeSniffer\Standards\Squiz\Sniffs\PHP\DisallowSizeFunctionsInLoopsSniff::$forbiddenFunctions
|
PHP_CodeSniffer\Standards\Squiz\Sniffs\PHP\DisallowSizeFunctionsInLoopsSniff::FORBIDDEN_FUNCTIONS |
-
The visibility of the following class constants has changed from
public
toprivate
. If you used these in your own code, you will need to create your own constants instead:PHP_CodeSniffer\Generators\HTML::STYLESHEET
PHP_CodeSniffer\Util\Timing::MINUTE_IN_MS
PHP_CodeSniffer\Util\Timing::SECOND_IN_MS
-
The
PHP_CodeSniffer\Util\Standards::printInstalledStandards()
method is deprecated and should no longer be used. Useecho PHP_CodeSniffer\Util\Standards::prepareInstalledStandardsForDisplay()
instead once support for PHPCS 3.x is being dropped. -
The
PHP_CodeSniffer\Utils\Timing
class is now afinal
class.
The Ruleset class now respects sniff selection via --sniffs=...
, even when in a test context.
If your own test framework contained work-arounds to get round the previous restriction, it should now be safe to remove those work-arounds and to use the --sniffs=...
argument when initiating the Config
class.
Typically, these type of work-around can be found by searching for calls to the Ruleset::registerSniffs()
method.
External standards which use the PHP_CodeSniffer native test framework as the basis for the sniff tests need to be aware of the following changes. If an external standard uses its own test framework, this section can be skipped.
- The test setup now supports PHPUnit 8, 9, 10 and 11, which is in line with the new minimum PHP version of 7.2.
Please read the changelogs for PHPUnit itself for information about the changes.
Most notable changes which will likely impact your tests:
- The test suite may need a separate PHPUnit config file for PHPUnit < 10 and PHPUnit 10+.
- The custom
TestSuite
setup has been removed from the framework as it is no longer needed since PEAR support was dropped and was incompatible with PHPUnit 10. - All abstract base test cases now use the
TestCase
class name suffix.Old Name New Name PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest PHP_CodeSniffer\Tests\Core\AbstractMethodTestCase PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase - Fixture methods no longer use the
@before|after[Class]
annotations, but use the PHPUnitsetUp|tearDown[BeforeClass|AfterClass]()
methods again. These methods now havevoid
return type declarations. - The global
printPHPCodeSnifferTestOutput()
function, which printed a "# sniff test files generated # unique error codes; # were fixable (#%)" summary after the tests is no longer available. - The following properties which were previously available in the
AbstractSniffUnitTest
class have been removed:protected $backupGlobals
public $standardsDir
-
public $testsDir
The first is (very) old-school PHPUnit and should not be used anyway. The last two were never intended to be overwritten by concrete test classes, so shouldn't have been public properties.
- The following property which was previously available in the
AbstractMethodUnitTest
class has been removed:-
protected static $fileExtension
This property is redundant now support for JS/CSS files has been dropped.
-
- The test framework no longer uses global variables. I.e. the following are no longer available:
$GLOBALS['PHP_CODESNIFFER_STANDARD_DIRS']
$GLOBALS['PHP_CODESNIFFER_TEST_DIRS']
$GLOBALS['PHP_CODESNIFFER_CONFIG']
$GLOBALS['PHP_CODESNIFFER_RULESETS']
$GLOBALS['PHP_CODESNIFFER_SNIFF_CASE_FILES']
$GLOBALS['PHP_CODESNIFFER_SNIFF_CODES']
$GLOBALS['PHP_CODESNIFFER_FIXABLE_CODES']
- Sniff tests which extend the
AbstractSniffTestCase
for which no test case files (.inc
files) can be found, will now be marked as "incomplete". - Sniff tests which extend the
AbstractSniffTestCase
for which no.fixed
files can be found, while the sniff would make fixes to the test case file, will now fail.
For compatibility with the PHP_CodeSniffer native test framework, the directory layout conventions and class naming conventions for tests have to be strictly followed and external standards which want to use the PHPCS native test framework need to be registered in the PHP_CodeSniffer CodeSniffer.conf
file.
This is not really any different from before, just even more important now.
In practice this means the following for most test suites for external standards which extend the PHP_CodeSniffer native test suite:
- In
composer.json
: update the PHPUnit version requirements. The PHP_CodeSniffer native test framework supports PHPUnit^8.0 || ^9.3.4 || ^10.5.32 || ^11.3.3
as of PHP_CodeSniffer 4.0.0. - In the
phpunit.xml[.dist]
file: ensure that this file contains a<testsuites>
element which points to your test directory/directories. - In the test bootstrap file: register your own standard and any other external standards your standard needs with the autoloader.
Typically, this can be done using the following code snippet after loading the PHPCS
autoload.php
file:$installedStandards = Standards::getInstalledStandardDetails(); foreach ($installedStandards as $details) { Autoload::addSearchPath($details['path'], $details['namespace']); }
[!NOTE] If you load the PHPCS test
bootstrap.php
file from within your testbootstrap.php
file, this is not needed, as the PHPCS bootstrap will already do this for you. - There is no need anymore to set the
PHPCS_IGNORE_TESTS
environment variable in a PHPUnit config file. - Update the import use statements for the sniff tests to point to the
AbstractSniffTestCase
and update theextends
in the class declaration, like so:External standards which want to support PHP_CodeSniffer 3 and 4 and run their tests on both could consider aliasing the name of the test case class in their test bootstrap file.-use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; -final class YourSniffNameUnitTest extends AbstractSniffUnitTest { +final class YourSniffNameUnitTest extends AbstractSniffTestCase {
- Make sure that all
inc
test case files which test fixers are accompanied by a.inc.fixed
file. In PHPCS 3.x, the test framework would already warn about any missing.fixed
files. This has now become an error which will fail a test run. - For running the tests: do not pass the
./vendor/squizlabs/php_codesniffer/tests/AllTests.php
file anymore and the--filter ExternalStndName
argument should also no longer be needed. Run the tests for your external standard by calling plainphpunit
.
Additional changes may still be needed depending on whether your test suite contains custom test methods; test classes which don't extend the PHPCS test framework and/or whether you overload methods from the PHPCS test cases.
For everyone
Introduction
Requirements
Usage
Advanced Usage
Reporting
Configuration Options
Fixing Errors Automatically
FAQ
For coding standard creators
About Standards for PHP_CodeSniffer
Annotated Ruleset
Customisable Sniff Properties
Version 4.0 Upgrade Guide
For sniff developers
Coding Standard Tutorial
Version 4.0 Upgrade Guide (Dev)
Version 3.0 Upgrade Guide
Version 1.3.0 Upgrade Guide