Skip to content

[META] PHP 8 backward incompatible changes detection #5368

@mglaman

Description

@mglaman

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.

https://phpstan.org/r/cae8e1b1-2d0d-4ee0-8e2c-b9c9a5796535

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.

https://phpstan.org/r/1d412d9d-76a1-440e-a65c-809b03250974

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.

https://phpstan.org/r/ef91bba8-d5eb-441b-91d8-60866e2af6e6

The ability to define case-insensitive constants has been removed. The third argument to define() may no longer be true.

https://phpstan.org/r/a303a478-e979-48f7-92fb-d56b0cd121b7

The ability to specify an autoloader using an __autoload() function has been removed. spl_autoload_register() should be used instead.

No idea how relevant

https://phpstan.org/r/f914387f-6e8f-4ee6-b601-75baa728084a

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.

https://phpstan.org/r/7b7db20f-8b1d-411d-9d9e-41dbec9bae4d

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.

https://phpstan.org/r/a00f7a19-f467-450c-9991-2ef41cd5d441

The ability to use array_key_exists() with objects has been removed. isset() or property_exists() may be used instead.

https://phpstan.org/r/a964496a-9929-4aaa-9c78-7dbc144c4d7b

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.

https://phpstan.org/r/e384296a-be57-4282-8621-be46c7865f44

The signature of abstract methods defined in traits is now checked against the implementing class method

https://phpstan.org/r/3eb722f0-eba2-49ef-9222-a717994d38af

Support for deprecated curly braces for offset access has been removed.

https://phpstan.org/r/41e34db1-9124-4233-8351-1e565a2b0093

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.

https://phpstan.org/r/617bee17-0fb8-4ee6-bec4-04118853506d

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

https://phpstan.org/r/d98ba1b6-6dd2-4ec4-ade2-aae0837f575a

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions