diff --git a/wiki/Version-4.0-Developer-Upgrade-Guide.md b/wiki/Version-4.0-Developer-Upgrade-Guide.md index 6afbb9a..e096f67 100644 --- a/wiki/Version-4.0-Developer-Upgrade-Guide.md +++ b/wiki/Version-4.0-Developer-Upgrade-Guide.md @@ -23,7 +23,7 @@ There is a separate [Upgrade Guide for Ruleset Maintainers and End-Users](https: 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. +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] @@ -78,7 +78,7 @@ Please carefully read the naming conventions for standards and sniffs as outline ... 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. +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.

back to top

@@ -88,9 +88,9 @@ 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 the `PHP_CodeSniffer\Sniffs\DeprecatedSniff` interface (PHPCS 3.9.0+) to mark the sniff as deprecated. +* 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 the `PHP_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. @@ -143,10 +143,10 @@ Additionally, when a name could not be determined, like during live coding, the 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. +* 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)`. +* 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 against `null` with a check against an empty string. ```diff $name = $phpcsFile->getDeclarationName($stackPtr); @@ -200,7 +200,7 @@ Typically, this may impact projects which call `new Config` consecutive times pr ##### Upgrading -Typical workarounds for the old behaviour will use `Reflection` to reset the `Config::$overriddenDefaults` property between instantiations. +Typical workarounds for the old behaviour will use `Reflection` to reset the `Config::$overriddenDefaults` property between instantiations. These type of workarounds can now be removed.

back to top

@@ -274,8 +274,8 @@ The following tokens have been removed: ##### Upgrading -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"](#support-for-jscss-has-been-removed): deprecate or remove the sniff. +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"](#support-for-jscss-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 existence of the tokens before using them.

back to top

@@ -289,10 +289,10 @@ These tokens have been added to the `Tokens::$parenthesisOpeners` array and will ##### Upgrading -* 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. +* 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 of `T_USE`, you may need to validate that it is a closure `use` token and not an import/trait `use` token before acting on the token. -* Search your codebase for `T_USE`, `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT`. +* 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 the `parenthesis_owner`, `parenthesis_opener` and `parenthesis_closer` keys instead.

back to top

@@ -302,7 +302,7 @@ These tokens have been added to the `Tokens::$parenthesisOpeners` array and will 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. +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: @@ -345,7 +345,7 @@ This re-tokenization has now been removed. #### T_OPEN_TAG -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. +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] @@ -390,10 +390,10 @@ doSomething(); #### Other Tokenizer Changes -* All `T_DOC_COMMENT_*` tokens will now have the `comment_opener` and `comment_closer` indexes set. +* All `T_DOC_COMMENT_*` tokens will now have the `comment_opener` and `comment_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 deprecated `Tokens::$functionNameTokens`, now also contains the `T_ANON_CLASS` token. +* The `Tokens::FUNCTION_NAME_TOKENS` token array, as well as the deprecated `Tokens::$functionNameTokens`, now also contains the `T_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.

back to top

@@ -403,7 +403,7 @@ doSomething(); 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. +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. **Upgrading** @@ -462,11 +462,11 @@ The `protected` `getDeclarationNameWithNamespace()` and `getNamespaceOfScope()` * 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()` and `PHP_CodeSniffer\Filters\ExactMatch::getWhitelist()` methods have been replaced with abstract `PHP_CodeSniffer\ExactMatch::getDisallowedFiles()` and `PHP_CodeSniffer\ExactMatch::getAllowedFiles()` methods. - If you have custom classes which extend the `ExactMatch` class, implement the new `getDisallowedFiles()` and `getAllowedFiles()` methods instead. +* The abstract `PHP_CodeSniffer\Filters\ExactMatch::getBlacklist()` and `PHP_CodeSniffer\Filters\ExactMatch::getWhitelist()` methods have been replaced with abstract `PHP_CodeSniffer\ExactMatch::getDisallowedFiles()` and `PHP_CodeSniffer\ExactMatch::getAllowedFiles()` methods. + If you have custom classes which extend the `ExactMatch` class, implement the new `getDisallowedFiles()` and `getAllowedFiles()` 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 of `get*(): string` methods. +* Various `print*(): void` methods in the Generator classes have been removed in favour of `get*(): string` methods. If you extend any of the `Generator` classes...: | Search for | Replace with | @@ -486,39 +486,39 @@ The `protected` `getDeclarationNameWithNamespace()` and `getNamespaceOfScope()` * The `PHP_CodeSniffer\Reporter::$startTime` property has been removed. This property was unused since PHPCS 3.0.0. -* The `PHP_CodeSniffer\Reporter::$totalFixable` and `Reporter::$totalFixed` properties are deprecated and should no longer be used. +* The `PHP_CodeSniffer\Reporter::$totalFixable` and `Reporter::$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` | The format of the array has changed from numerically indexed to associated with the keys and values containing the same information. | -| (`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` | | +* `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 [squizlabs/PHP_CodeSniffer#3629](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` | The format of the array has changed from numerically indexed to associated with the keys and values containing the same information. | + | (`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` to `private`. 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` + * `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. Use `echo PHP_CodeSniffer\Util\Standards::prepareInstalledStandardsForDisplay()` instead once support for PHPCS 3.x is being dropped. @@ -547,36 +547,38 @@ Typically, these type of workarounds can be found by searching for calls to the 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. +* 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 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 PHPUnit `setUp|tearDown[BeforeClass|AfterClass]()` methods again. + +* Fixture methods no longer use the `@before|after[Class]` annotations, but use the PHPUnit `setUp|tearDown[BeforeClass|AfterClass]()` methods again. These methods now have `void` 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. + * `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` + * `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']` + * `$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. @@ -586,10 +588,10 @@ This is not really any different from before, just even more important now. **Upgrading** In practice this means the following for most test suites for external standards which extend the PHP_CodeSniffer native test suite: -1. In `composer.json`: update the PHPUnit version requirements. +1. 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. 2. In the `phpunit.xml[.dist]` file: ensure that this file contains a `` element which points to your test directory/directories. -3. In the test bootstrap file: register your own standard and any other external standards your standard needs with the autoloader. +3. 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: ```php $installedStandards = Standards::getInstalledStandardDetails(); @@ -608,7 +610,7 @@ In practice this means the following for most test suites for external standards +final class YourSniffNameUnitTest extends AbstractSniffTestCase { ``` 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. -6. Make sure that all `inc` test case files which test fixers are accompanied by a `.inc.fixed` file. +6. 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. 7. 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 plain `phpunit`. diff --git a/wiki/Version-4.0-User-Upgrade-Guide.md b/wiki/Version-4.0-User-Upgrade-Guide.md index bc0069f..3da1fa4 100644 --- a/wiki/Version-4.0-User-Upgrade-Guide.md +++ b/wiki/Version-4.0-User-Upgrade-Guide.md @@ -19,7 +19,7 @@ There is a separate [Upgrade Guide for Sniff Developers and Integrators](https:/ It is highly recommended to upgrade as soon as you are able. -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. +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. ### External Standards @@ -55,7 +55,7 @@ If you want, you can even silence them by running PHP_CodeSniffer in quiet mode ### The minimum PHP version is now PHP 7.2.0 -This has no impact on the "code under scan", it just means that when running PHP_CodeSniffer, the minimum PHP version needs to be PHP 7.2. +This has no impact on the "code under scan", it just means that when running PHP_CodeSniffer, the minimum PHP version needs to be PHP 7.2. As an example, you can run PHP_CodeSniffer on PHP 8.4 to scan a code base which is supposed to run on PHP 5.6.

back to top

@@ -95,17 +95,17 @@ To continue running code style and code quality checks on JS and/or CSS files, u #### Upgrading There are two kinds of sniffs which are affected by this: -1. Sniffs which are specific to JS/CSS and only target JS/CSS code. +1. Sniffs which are specific to JS/CSS and only target JS/CSS code. If you use JS/CSS specific sniffs from either PHP_CodeSniffer itself or from an external standard, remove references to these sniffs from your ruleset. -2. "Mixed" sniffs, i.e. sniffs which target both PHP as well as JS and/or CSS code. +2. "Mixed" sniffs, i.e. sniffs which target both PHP as well as JS and/or CSS code. If an external standard you include in your ruleset contains these type of "mixed" sniffs, contact the maintainer of that standard about making the sniff compatible with PHP_CodeSniffer 4.0. PHP_CodeSniffer >= 3.13.0 will show you deprecation notices for these sniffs to help you find them. Secondly, review your `extensions` settings. -* If you have `extensions` set in a ruleset, like ``, be sure to remove any non-PHP extensions. +* If you have `extensions` set in a ruleset, like ``, be sure to remove any non-PHP extensions. You can also remove the language part, i.e. `php,inc/php` becomes `php,inc`. -* Next, make sure to also check for any hard-coded commands which pass the `--extensions=...` CLI argument, like in continuous integration scripts. +* Next, make sure to also check for any hard-coded commands which pass the `--extensions=...` CLI argument, like in continuous integration scripts. The same applies there: remove any non-PHP extensions and remove any potential language settings.

back to top

@@ -113,7 +113,7 @@ Secondly, review your `extensions` settings. ### Setting array properties for sniffs -PHP_CodeSniffer 3.3.0 introduced a new syntax to set the value of array properties for sniffs by specifying array elements using a new `element` tag with `key` and `value` attributes. The old syntax was deprecated in the same PHP_CodeSniffer version. +PHP_CodeSniffer 3.3.0 introduced a new syntax to set the value of array properties for sniffs by specifying array elements using a new `element` tag with `key` and `value` attributes. The old syntax was deprecated in the same PHP_CodeSniffer version. Support for the old syntax has been removed in PHP_CodeSniffer 4.0.0. #### Upgrading @@ -173,7 +173,7 @@ If you haven't done so already, search your `[.]phpcs.xml[.dist]` file for... ### Removed error codes -As of PHP_CodeSniffer 4.0, PHP_CodeSniffer will no longer throw warnings about potential parse errors. +As of PHP_CodeSniffer 4.0, PHP_CodeSniffer will no longer throw warnings about potential parse errors. This was only done in a few places anyway, while the vast majority of sniffs would try to silently ignore code with parse errors. > [!NOTE] @@ -274,7 +274,7 @@ If you haven't done so already, execute a search & replace on your code base. The exit codes used by PHP_CodeSniffer have changed. This change was made primarily to allow for `phpcbf` to exit with a `0` exit code if all fixable issues were fixed and there are no non-auto-fixable issues remaining. -The pre-existing [`ignore_warnings_on_exit`](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Configuration-Options#ignoring-warnings-when-generating-the-exit-code) and [`ignore_errors_on_exit`](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Configuration-Options#ignoring-errors-when-generating-the-exit-code) config flags will still be respected. +The pre-existing [`ignore_warnings_on_exit`](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Configuration-Options#ignoring-warnings-when-generating-the-exit-code) and [`ignore_errors_on_exit`](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Configuration-Options#ignoring-errors-when-generating-the-exit-code) config flags will still be respected. Additionally, you can now use the new `ignore_non_auto_fixable_on_exit` config flag to ignore non-auto-fixable issues when the exit code is generated. #### Upgrading @@ -292,8 +292,8 @@ Just before the final 4.0.0 release, the PHP_CodeSniffer `master` branch will be ##### Referencing the PHP_CodeSniffer XSD file for rulesets -If your ruleset includes a reference to the PHP_CodeSniffer XSD file via a URL, that URL will become invalid. -As of mid May 2025, the current PHP_CodeSniffer ruleset XSD file can be referenced via the following permalink: `https://schema.phpcodesniffer.com/phpcs.xsd`. +If your ruleset includes a reference to the PHP_CodeSniffer XSD file via a URL, that URL will become invalid. +As of mid May 2025, the current PHP_CodeSniffer ruleset XSD file can be referenced via the following permalink: `https://schema.phpcodesniffer.com/phpcs.xsd`. Permalinks to the XSD file for specific minors are also available in the following format: `https://schema.phpcodesniffer.com/#.#/phpcs.xsd`. Example changeset: @@ -308,7 +308,7 @@ Relative file references like `xsi:noNamespaceSchemaLocation="./vendor/squizlabs ##### Referencing the main branches in the repository -If you reference a development version of PHP_CodeSniffer in your `composer.json` file or in CI scripts, those references will need to be updated. +If you reference a development version of PHP_CodeSniffer in your `composer.json` file or in CI scripts, those references will need to be updated. What to update these to, depends on your use-case. * If you want to use the latest development version of PHP_CodeSniffer, use the `4.x` branch. For Composer, references to the branch will need to look like this: `4.x-dev`. @@ -350,7 +350,7 @@ Previously a ruleset could already "extend" an array property for a sniff set by As of PHP_CodeSniffer 4.0, a ruleset can also "extend" the default value of an array property as set in the sniff itself. -The upside of this is, that if you want to default value + some extras, you no longer need to duplicate the default values from sniff array properties in your ruleset. +The upside of this is, that if you want to default value + some extras, you no longer need to duplicate the default values from sniff array properties in your ruleset. The downside is, of course, that if the default value of the property in the sniff changes, your scans may start failing without warning. #### Upgrading @@ -386,7 +386,7 @@ Now you can "inherit" the default value and add to it by using `extend="true"`:

back to top

-### My scans are failing on a "No files were checked" error... +### My scans are failing on a "No files were checked" error Between the extension filtering via `--extensions=...` (CLI) / `` (ruleset), potential `--ignore=...` (CLI) / `...` (ruleset) directives being followed, and potential `--filter=...` directives, there are no files eligible for scanning.