PHP_CodeSniffer 3.5.0 contains a lot of changes under the hood. For the most part these are non-breaking.
If you maintain an external standard, you have three options:
- Maintain compatibility with older PHP_CodeSniffer versions [1]. In that case, there is probably nothing you need to do. Just make sure you check the BC-breaks section below just in case. All the "old" utility methods and properties will still work. They will however be removed in PHPCS 4.0.
- Maintain compatibility with older PHP_CodeSniffer versions [2].
If you want to be both back-ward as well as forward compatible for PHPCS 4.0, you can wrap calls to the moved PHPCS utility methods in
method_exists()conditions, like so:Note: if you choose this direction, you can not (yet) use the new methods available in the new utility classes.use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Util\Sniffs\Conditions; class MySniff extends Sniff { public function register() { return [T_FUNCTION] } public function process(File $phpcsFile, $stackPtr) { if (method_exists('Conditions', 'getCondition') === true) { $result = Conditions::getCondition($phpcsFile, $stackPtr, [T_IF]); } else { $result = $phpcsFile->getCondition($stackPtr, T_IF); } // Sniff logic. } }
- Change you minimum PHPCS requirement to 3.5.0 and benefit fully from all the new features.
If you want to get the most out of PHPCS and benefit from all the new goodies, you will need to raise the minimum PHPCS requirement for your standard to
3.5.0. You will also need to change calls to the moved PHPCS utility methods to point to their new locations. If you choose this direction, you can start using all the new methods available and possibly deprecate/remove similar utility methods from within your own standard.
| Old Method | New Method |
|---|---|
\PHP_CodeSniffer\Files\File::getCondition($stackPtr, $type) |
\PHP_CodeSniffer\Util\Sniffs\Conditions::getCondition(File $phpcsFile, $stackPtr, $types=[], $reverse=false) |
\PHP_CodeSniffer\Files\File::hasCondition($stackPtr, $types) |
\PHP_CodeSniffer\Util\Sniffs\Conditions::hasCondition(File $phpcsFile, $stackPtr, $types) |
\PHP_CodeSniffer\Files\File::getMethodParameters($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::getParameters(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::getMethodProperties($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::getProperties(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::getMemberProperties($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::getMemberProperties(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::getClassProperties($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\ObjectDeclarations::getClassProperties(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::findExtendedClassName($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\ObjectDeclarations::findExtendedClassName(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::findImplementedInterfaceNames($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\ObjectDeclarations::findImplementedInterfaceNames(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::isReference($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\TokenIs::isReference(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Files\File::getDeclarationName($stackPtr) |
\PHP_CodeSniffer\Util\Sniffs\ConstructNames::getDeclarationName(File $phpcsFile, $stackPtr) |
\PHP_CodeSniffer\Util\Common::isCamelCaps($string, $classFormat=false, $public=true, $strict=true) |
\PHP_CodeSniffer\Util\Sniffs\ConstructNames::isCamelCaps($string, $classFormat=false, $public=true, $strict=true) |
\PHP_CodeSniffer\Util\Common::isUnderscoreName($string) |
\PHP_CodeSniffer\Util\Sniffs\ConstructNames::isUnderscoreName($string) |
\PHP_CodeSniffer\Util\Common::suggestType($varType) |
PHP_CodeSniffer\Util\Sniffs\Comments::suggestType($varType, $form='short', $allowedTypes=null) |
| Old property | New Property |
|---|---|
\PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$magicMethods and \PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::$magicMethods |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::$magicMethods |
\PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$methodsDoubleUnderscore |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::$methodsDoubleUnderscore |
\PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff::$magicFunctions and \PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff::$magicFunctions |
\PHP_CodeSniffer\Util\Sniffs\FunctionDeclarations::$magicFunctions |
\PHP_CodeSniffer\Sniffs\AbstractVariableSniff::$phpReservedVars |
\PHP_CodeSniffer\Util\Sniffs\Variables::$phpReservedVars |
\PHP_CodeSniffer\Util\Common::$allowedTypes |
PHP_CodeSniffer\Util\Sniffs\Comments::$allowedTypes |
This method, in combination with the new PHP_CodeSniffer\Util\Sniffs\Comments::suggestTypeString() method, has been enhanced to support a lot more, common type formats.
- Both
array(type => type)as well asarray<type, type>style are now supported. - PSR-5 style array types -
string[]and(string|int)[]- are now supported. - Union and intersect types are now fully supported, including for combinations of styles.
- Allows for prefixing a type with a
?to indicate nullability.
It now also accepts two additional parameters:
$formto elect whether "short" or "long" form of variable types should be suggested. Defaults toshortas that is the more common preference nowadays. This only affectsbooleanvsboolandintegervsint.$allowedTypesto overrule the default list of allowed variables types with a custom one.
In addition to this, the PHP_CodeSniffer\Util\Sniffs\Comments::suggestTypeString() method will now, if necessary:
- Unduplicate a type string.
- Combine multiple PSR-5 style array types, i.e.
(int|float)[]|string[]will become(int|float|string)[]. - Remove duplicate union/intersect separators, i.e.
int||floatwill becomeint|float. - Remove the nullability indicator, if
nullis included in the type, i.e.?int|float|nullwill becomeint|float|null.
The old method accepted only a single token type for the $type parameter.
The new method accepts both a single token type or an array of token types for the $type parameter, which has been renamed to $types to convey this. The parameter is also now optional.
Additionally, the new method has an optional boolean $reverse parameter which allows to indicate whether to get the first condition of a certain type or the last.
For your convenience, the class also contains getFirstCondition() and getLastCondition() methods which are wrappers for the getCondition() method.
While certain names may be invalid, such as PHP construct names starting with a number; for the purpose of alerting users to these invalid names, the getDeclarationName() method should be able to pick up on them.
The getDeclarationName() method has now been adjusted to allow for such names.
The parse error resilience for the method has also been improved.
To still be able to distinguish between an anonymous class/function having been passed to the method and a parse error, the method will continue to output null when an anonymous class/function has been passed but will return an empty string when a parse error has been encountered. Testing the function output with empty() catches both cases.
\PHP_CodeSniffer\Util\Sniffs\ObjectDeclarations::findExtendedClassName and \PHP_CodeSniffer\Util\Sniffs\ObjectDeclarations::findImplementedInterfaceNames
If the extended class name/implemented interface name would be a FQN, it could be interlaced with comments and/or whitespace. Previously the return values would contain the name as found, including these comments/whitespace. The new method will return the "clean" name stripped off comments/whitespace.
This property used to only contain the "long" form of variable types as values. The array has now changed to contain "short" form types as keys and "long" form as values.
The array has also been expanded to include all types as contained in the draft for PSR5.
The old format of this property will, for the time being, remain in its original location.
The moved $magicMethods, $methodsDoubleUnderscore, $magicFunctions properties have a slightly different format in their new location.
The old format was name without double underscores => true
The new format is name including double underscores => name without double underscores for $magicMethods and $magicFunctions.
For $methodsDoubleUnderscore, the new format is name including double underscores => name of the PHP module which contains the method
The old format of the properties is maintained in their original location.
The property now contains a more complete list of PHP reserved variable names.
The array values used to always be true. This has been changed to true for variables which are superglobals and false for other PHP reserved variable names.
There is one real BC break and it only occurs in a very specific situation:
If your standard contains a sniff which extends either the Generic.NamingConventions.CamelCapsFunctionName or the PEAR.NamingConventions.ValidFunctionName sniff and overloads the __construct() method without calling parent::__construct(), the $magicMethods, $methodsDoubleUnderscore, $magicFunctions properties will be empty.
This is easily fixed by adding a call to the parent::__construct() method from within your overloaded __construct().
When a sniff extends the AbstractVariableSniff and overloads the __construct() method without calling parent::__construct() for the $phpReservedVars property, the same thing happens, i.e. $phpReservedVars will be empty.
Other than that, the FunctionDeclarations::getParameters(), FunctionDeclarations::getProperties(), Variables::getMemberProperties() and the ObjectDeclarations::getClassProperties() methods used to throw a TokenizerException when an incorrect token was passed. They will now throw a RuntimeException.
-
suggestTypeString($typeString, $form='short', $allowedTypes=null)method allows for passing a complete type string without pre-processing and receiving a valid type string suggestion back. -
findEndOfComment(File $phpcsFile, $stackPtr)- to find the end of an inline/block comment based on the first comment token of a comment sequence. Returns the integer stackPtr position to the end of the comment. -
findStartOfComment(File $phpcsFile, $stackPtr)- to find the start of an inline/block comment based on the last comment token of a comment sequence. Returns the integer stackPtr position to the start of the comment. -
findConstantComment(File $phpcsFile, $stackPtr)- to find the end of a constant docblock/comment based on a T_CONST token. Returns the integer stackPtr position or false if no constant comment can be found. -
findFunctionComment(File $phpcsFile, $stackPtr)- to find the end of a function docblock/comment based on a T_FUNCTION token. Returns the integer stackPtr position or false if no function comment can be found. -
findOOStructureComment(File $phpcsFile, $stackPtr)- to find the end of a class/interface/trait docblock/comment based on a T_CLASS/T_INTERFACE/T_TRAIT token. Returns the integer stackPtr position or false if no comment can be found. -
findPropertyComment(File $phpcsFile, $stackPtr)- to find the end of a property docblock/comment based on a T_VARIABLE token. Returns the integer stackPtr position or false if no property comment can be found. -
findCommentAbove(File $phpcsFile, $stackPtr, $ignore=[])- to find the end of a docblock/comment above an arbitrary token. Returns the integer stackPtr position or false if no comment can be found.
getFirstCondition(File $phpcsFile, $stackPtr, $types=[])- to retrieve the first condition of a type passed in$typesfor a token or the first condition for a token if no types are specified. This is effectively just an alias for thegetCondition()method.getLastCondition(File $phpcsFile, $stackPtr, $types=[])- to retrieve the last condition of a type passed in$typesfor a token or the last condition for a token if no types are specified.isOOProperty(File $phpcsFile, $stackPtr)- to check if aT_VARIABLEtoken is a class/trait property. Returns true/false.isOOConstant(File $phpcsFile, $stackPtr)- to check if aT_CONSTANTtoken is a class/interface constant. Returns true/false.is_OOMethod(File $phpcsFile, $stackPtr)- to check if aT_FUNCTIONtoken is a class/interface/trait method. Returns true/false.validDirectScope(File $phpcsFile, $stackPtr, $validScopes)- to check the direct condition of an arbitrary token against a set of valid scope conditions. Returns the integer stackPtr to the direct condition if valid or false otherwise.
hasNumbers($name)- to check whether a name string contains numeric characters. Returns boolean.ltrimNumbers($name)- to remove any numeric characters from the start of the name string. Returns the transformed string.removeNumbers($name)- to remove all numeric characters from the name string. Returns the transformed string.lowerConsecutiveCaps($name)- to transform consecutive caps in a name string to lowercase. Returns the adjusted string or the original string if no consecutive caps were found, or when the input string was non-ASCII and the MBString extension is not available.
isMagicFunction(File $phpcsFile, $stackPtr)- to check if the function declared on aT_FUNCTIONtoken is a PHP magic function. Returns true/false.isMagicFunctionName($name)- to check if a given function name is the name of a PHP magic function. Returns true/false.isMagicMethod(File $phpcsFile, $stackPtr)- to check if the function declared on aT_FUNCTIONtoken is a PHP magic method. Returns true/false.isMagicMethodName($name)- to check if a given function name is the name of a PHP magic method. Returns true/false.isPHPDoubleUnderscoreMethod(File $phpcsFile, $stackPtr)- to check if the function declared on aT_FUNCTIONtoken is a PHP native double underscore method. Returns true/false.isPHPDoubleUnderscoreMethodName($name)- to check if a given function name is the name of a PHP native double underscore method. Returns true/false.isSpecialMethod(File $phpcsFile, $stackPtr)- to check if the function declared on aT_FUNCTIONtoken is a PHP magic method or a PHP native double underscore method. Returns true/false.isSpecialMethodName($name)- to check if a given function name is the name of a PHP magic method or PHP native double underscore method. Returns true/false.
The Name methods only check a given name, the non-Name method also check if the function is a method or global function.
getType(File $phpcsFile, $stackPtr)- to determine what a T_NAMESPACE token is used for. Returns a string. Eitherdeclarationoroperatoror an empty string when the type of statement for which it's used could not be determined.isDeclaration(File $phpcsFile, $stackPtr)- to check whether aT_NAMESPACEtoken is used to declare a namespace. Returns boolean.isOperator(File $phpcsFile, $stackPtr)- to check whether aT_NAMESPACEtoken is used as an operator. Returns boolean.getDeclaredName(File $phpcsFile, $stackPtr, $clean=true)- to retrieve the (cleaned up) name of a namespace based on the T_NAMESPACE token for the namespace declaration. Returns string|false - the namespace name or an empty string if the code is declared to be in the global namespace. Will return false if the passed token is not for a namespace declaration or in the case of parse errors.findNamespacePtr(File $phpcsFile, $stackPtr)- to find the stackPtr to theT_NAMESPACEtoken for the namespace an arbitrary token lives in. Returns the integer stackPtr to the keyword token or false if it couldn't be determined or if no namespace applies.determineNamespace(File $phpcsFile, $stackPtr)- to retrieve the (clean) name of the namespace an arbitrary token lives in. Returns string - the namespace name or an empty string if the code is not namespaced or the name could not be determined.
findExtendedInterfaceNames(File $phpcsFile, $stackPtr)- to retrieve the names of the interfaces that a specified interface extends. Returns an array of names or false when the interface doesn't extend another interface.
isFirstCharCapitalized($string)- to check whether the first character of an arbitrary text string is a capital letter. Returns boolean.isFirstCharLowercase($string)- to check whether the first character of an arbitrary text string is a lowercase letter. Returns boolean.isLastCharPunctuation($string, $allowedChars=self::TERMINAL_POINTS)- to check whether the last character of an arbitrary text string is a punctuation character. By default, the full stop, question mark and exclamation mark are accepted as valid punctuation, but this can easily be changed by passing the$allowedCharsparameter. Returns boolean. Ref: https://www.thepunctuationguide.com/terminal-points.html
This class also contains a TERMINAL_POINTS class constant containing the default allowed punctuation characters.
Important note: The return of isFirstCharCapitalized() is not the direct opposite of the output of isFirstCharLowercase().
isFirstCharCapitalized()will returntruefor capital letters and letters which don't have a concept of capitalization. It will returnfalsefor lowercase letters and non-letters.isFirstCharLowercase()will returntruefor lowercase letters only. It will returnfalsefor all other characters, including non-letters.
Targeted at open/close parentheses tokens:
getOwner(File $phpcsFile, $stackPtr)- to retrieve the stack pointer to the parentheses owner of an open/close parenthesis. Returns int or false if the parenthesis does not have an owner.isOwnerIn(File $phpcsFile, $stackPtr, $validOwners)- to check whether the parenthesis owner of an open/close parenthesis is within a limited set of valid owners. Returns bool.
Targeted at arbitrary tokens:
hasOwner(File $phpcsFile, $stackPtr, $validOwners)- to check whether the passed token is nested within parentheses owned by one of the valid owners. Returns bool.lastOwnerIn(File $phpcsFile, $stackPtr, $validOwners)- to check whether the owner of a direct wrapping set of parentheses is within a limited set of acceptable tokens. Returns int/false.getFirstOpener(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the opener to the first set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.getFirstCloser(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the closer to the first set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.getFirstOwner(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the parentheses owner to the first set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.getLastOpener(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the opener to the last set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.getLastCloser(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the closer to the last set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.getLastOwner(File $phpcsFile, $stackPtr, $validOwners=[])- to retrieve the position of the parentheses owner to the last set of parentheses an arbitrary token is wrapped in where the parentheses owner is within the set of valid owners. Returns int/false.
Where the return value is of the type int|false, the integer stack pointer to the parentheses opener/closer/owner will be returned or false when:
- the token is not wrapped in parentheses;
- the parentheses owner is not within the set of
$validOwnerspassed; - and in the case of
owner: when the desired set of parenthesis does not have an owner.
hasParameters(File $phpcsFile, $stackPtr)- to check if parameters have been passed. Returns true/false.getParameters(File $phpcsFile, $stackPtr)- to retrieve details of the passed parameters. Returns an array withstart(token position),end(token position) andraw(string content) information for each parameter.getParameter(File $phpcsFile, $stackPtr, $paramOffset)- to retrieve the details of a specific parameter. Index for the parameters is 1-based. Returns an array with the details for the specified parameter orfalseif the parameter does not exist.getParameterCount(File $phpcsFile, $stackPtr)- to get the a count of the number of parameters. Returns integer.getDoubleArrowPosition(File $phpcsFile, $start, $end)- to find the position of a double arrow within an array item. Returns the integer stackPtr position or false if the array item doesn't have a key.
These methods are intended for use with:
T_STRINGandT_VARIABLEtokens for function calls;T_SELFandT_STATICtoken for function calls in the form ofnew self();T_ARRAYandT_OPEN_SHORT_ARRAYtokens for array declarations;T_LISTandT_OPEN_SHORT_ARRAYtokens for list declarations;T_ISSETandT_UNSETtokens for calls to these language constructs.
getCompleteTextString(File $phpcsFile, $stackPtr, $stripQuotes=true)- to retrieve the complete text string content of a - potentially multi-line - text string. Returns the text string.stripQuotes($string)- to strip the text delimiter quotes off an arbitrary text string. Returns the resulting text string.
isShortList(File $phpcsFile, $stackPtr)- to check whether a short array is in actual fact a short list. Returns boolean.isUnaryPlusMinus(File $phpcsFile, $stackPtr)- to check whether a plus/minus sign is a unary or an arithmetic operator. Returns boolean.
getType(File $phpcsFile, $stackPtr)- to determine the type of statement a T_USE token is used for. Returns a string. Eitherclosure,importortraitor an empty string when the type of statement for which it's used could not be determined.isClosureUse(File $phpcsFile, $stackPtr)- Wrapper method to check whether a T_USE token is a closure use statement. Returns boolean.isImportUse(File $phpcsFile, $stackPtr)- Wrapper method to check whether a T_USE token is a class/function/constant import use statement. Returns boolean.isTraitUse(File $phpcsFile, $stackPtr)- Wrapper method to check whether a T_USE token is a trait importing use statement. Returns boolean.splitImportUseStatement(File $phpcsFile, $stackPtr)- to split a multi-import or group-import use statement into information about the individual imports. Returns an array with information about all imports found in the use statement. Please refer to the function documentation for more detailed information.
isPHPReservedVarName($name)- to check if a given variable name is the name of a PHP reserved variable. Returns true/false.isSuperglobal(File $phpcsFile, $stackPtr)- to check if a given variable or string array key token points to a PHP superglobal. Returns true/false.isSuperglobalName($name)- to check if a given variable name is the name of a PHP superglobal variable. Returns true/false.isForeachAs(File $phpcsFile, $stackPtr)- to determine if a variable is in theas $key => $valuepart of aforeachcondition. Returns true/false.