-
-
Notifications
You must be signed in to change notification settings - Fork 947
[META] PHP 8 backward incompatible changes detection #5368
Description
Feature request
We are starting to work on PHP 8 compatibility detection for the Drupal ecosystem. Currently, Drupal 9 and eventual Drupal 10 are PHP 8 compatible, but we have a wide array of an ecosystem and client code that needs inspection.
Some initial discussion started here: #5265. While some of it was Drupal specific "we only want to report PHP 8 specific errors", we discovered some PHP 8 incompatibilities were not discovered (or needed a different error message when phpVersion: 80000.
Having these rules makes it easy to check your PHP 7.4 code before running it on PHP 8 and hitting a bunch of errors.
List of the backward incompatible changes: https://www.php.net/manual/en/migration80.incompatible.php
Progress
- match is now a reserved keyword.
- Methods with the same name as the class are no longer interpreted as constructors. The __construct() method should be used instead.
- The ability to call non-static methods statically has been removed. Thus is_callable() will fail when checking for a non-static method with a classname (must check with an object instance).
- The ability to define case-insensitive constants has been removed. The third argument to define() may no longer be true.
- The ability to specify an autoloader using an __autoload() function has been removed. spl_autoload_register() should be used instead.
- create_function() has been removed. Anonymous functions may be used instead.
- each() has been removed. foreach or ArrayIterator should be used instead.
- The ability to use array_key_exists() with objects has been removed. isset() or property_exists() may be used instead.
- Using parent inside a class that has no parent will now result in a fatal compile-time error.
-
#[is no longer interpreted as the start of a comment, as this syntax is now used for attributes. - The signature of abstract methods defined in traits is now checked against the implementing class method:
- Support for deprecated curly braces for offset access has been removed.
- Magic Methods will now have their arguments and return types checked if they have them declared. The signatures should match the following list:
Notes
I figure we can use this to organize rules that need to be written. My original notes are here: https://impossible-tangerine-e23.notion.site/Drupal-PHP-8-Readiness-53094cf842df424899d83d20bfd9fba4
match is now a reserved keyword.
I don't know if this is possible to handle. When the parser runs across the following code we get a syntax error and the file stops parsing.
Methods with the same name as the class are no longer interpreted as constructors. The __construct() method should be used instead.
This was deprecated in PHP 7, so who knows if anyone hits this. But PHPStan doesn't warn of its deprecation on PHP 7 nor report it as an error in PHP 8. All we get is a warning about the return type.
The ability to call non-static methods statically has been removed. Thus is_callable() will fail when checking for a non-static method with a classname (must check with an object instance).
This seems like a good rule/check regardless of PHP. I didn't know is_callable could invoke a non-static method on a class this way.
The ability to define case-insensitive constants has been removed. The third argument to define() may no longer be true.
The ability to specify an autoloader using an __autoload() function has been removed. spl_autoload_register() should be used instead.
No idea how relevant
create_function() has been removed. Anonymous functions may be used instead.
Seems like a good generic rule of "Don't use create_function, use anonymous instead" for PHP 7 would be great. And in PHP 8 handle function is not found for backward incompat error.
Links: #5373, phpstan/phpstan-src#588
each() has been removed. foreach or ArrayIterator should be used instead.
No idea how relevant. But there is some ancient Drupal code out there.
The ability to use array_key_exists() with objects has been removed. isset() or property_exists() may be used instead.
I think "Call to function array_key_exists() with 'foo' and stdClass will always evaluate to false." just needs to be updated to match what happens in PHP8. I haven't tried directly to see if there is a runtime error versus always returning false.
Using parent inside a class that has no parent will now result in a fatal compile-time error.
I think phpstan-src/src/Rules/Classes/InstantiationRule.php just needs to have PHP8 specific checks. Instead of just Bar::__construct() calls parent::__construct() but Bar does not extend any class. we need an error on PHP8
#[ is no longer interpreted as the start of a comment, as this syntax is now used for attributes.
This might just cause a syntax error with php-parser and nothing we can do.
The signature of abstract methods defined in traits is now checked against the implementing class method
Support for deprecated curly braces for offset access has been removed.
Magic Methods will now have their arguments and return types checked if they have them declared. The signatures should match the following list:
Need to have a mapping of the defined return types + magic methods; defined in the page.
parse_str() can no longer be used without specifying a result array.
This works. but we don't verify the type of the 2nd param