Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make implementations of built-in interfaces PHP 8.1 friendly #123

Merged
merged 2 commits into from
Apr 20, 2022
Merged

Make implementations of built-in interfaces PHP 8.1 friendly #123

merged 2 commits into from
Apr 20, 2022

Conversation

the-csaba
Copy link
Contributor

Problem

Unfortunately, PHP 8.1 throws Fatal Error if the built-in interface implementation is incompatible with the new, type enhanced interfaces.

Example error:

Fatal error: During inheritance of ArrayAccess: Uncaught Return type of cebe\openapi\spec\Responses::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

Example differences:

-public function offsetExists($offset);
+public function offsetExists(mixed $offset):bool;

Solution

As the above error messages also refer to it, the solution is relatively straightforward. The implementation needs to be updated with type information, or the #[ReturnTypeWillChange] attribute must be added to the affected methods.

This pull implements a the later, to maintain the current PHP compatibility: PHP >= 7.1.0.

Fortunately, attributes syntax just comments on PHP 7.x, the added lines may look weird but ignored by PHP.

Note: Attributes are "references" to classes, so namespace rules apply. That's why the attributes incorporate the backslash as well, i.e.: #[\ReturnTypeWillChange].

Test

To successfully run PHPUnit tests under PHP 8.1, I used the following commands:

composer config minimum-stability dev
composer require phpunit/phpunit:dev-master --dev
composer update --prefer-stable
vendor/bin/phpunit

I tested these changes on 7.1.33, 7.2.34, 7.3.30, 7.4.23, 8.0.10 and 8.1.0beta3

References

Affected built-in interfaces:

ReturnTypeWillChange attribute introduced in this rfc: https://wiki.php.net/rfc/internal_method_return_types

Attributes in general: https://www.php.net/manual/en/language.attributes.php

@marcelthole
Copy link
Contributor

i really like this pr to add support for PHP 8.1 although it's still a RC.
Maybe some additional notes:

  • add explicit support for each version in the composer.json like ^7.1.0 || ~8.0.0 || ~8.1.0
  • add php 8.1 in the github test matrix

@the-csaba
Copy link
Contributor Author

Hi @marcelthole,

I intentionally left out the composer.json changes because of the implied minimum stability. The PHPUnit 10.x is not out yet, and the 9.5.x is failing under PHP 8.1. So, to make the Composer install or update work in PHP 8.1, apart from the changes you are mentioned, the config also needs to include something like this:

{
"minimum-stability": "dev",
"prefer-stable": true
}

In my (not exhausting) test, running the Composer with the above config installs the dev version of Symfony packages. So that's why I instead just documented how to install it on 8.1.

If this constrain is OK with you, I am happy to push a commit for that.

@Neirda24
Copy link

Since the support of PHP is at least 7.1. It means return types already exists. why not directly add those instead of the attribute ?

@marcelthole
Copy link
Contributor

@Neirda24 for the Paths object your solution would work. The offsetGet could return ?PathItem and the problem is fixed.
For the Responses class this is not possible because the offsetGet Method of the Responses could return Response|Reference|null and union types are not supported below PHP 8.0.

So yeah, some points here could use the correct return type but not all of them.

@Neirda24
Copy link

Indeed. @marcelthole . But that's already a good leap forward. Keep in ,ind that those warnings only come from native PHP objects (like ArrayAccess). I think those are the priority to fix. Then indeed use types where we can and phpdoc types where Union should be used.

@the-csaba
Copy link
Contributor Author

the-csaba commented Dec 31, 2021

As now PHP 8.1 released, I removed all unnecessary dependency manipulations.

The PHPUnit 10.x is not out yet, and the 9.5.x is failing under PHP 8.1.

It turned out PHPUnit 9.5.x is compatible with PHP 8.1. No need for change.

Since the support of PHP is at least 7.1. It means return types already exists. why not directly add those instead of the attribute ?

On older PHP, the built-in classes do not define return types. So if a user-land code defines it, it will fail on 7.x - 8.0. If not, on 8.1+.

The #[ReturnTypeWillChange] attribute is the only method to support ArrayAccess, JsonSerializable and Countable on PHP 7.x to 8.1.

Edited to add: Because Liskov, we can define return types, the failure comes from parameter types.

@the-csaba
Copy link
Contributor Author

Hi @cebe, I ran GH Actions against this pull in our fork. It looks like newer PHP versions are failing with older Symfony: https://github.com/OM4/php-openapi/runs/4672017289?check_suite_focus=true

I address those errors in #134

@cebe cebe modified the milestones: 1.6.0, 1.7.0 Feb 9, 2022
@the-csaba the-csaba closed this Feb 9, 2022
@the-csaba the-csaba deleted the php-8.1-compatibility branch February 9, 2022 20:58
@the-csaba the-csaba restored the php-8.1-compatibility branch February 9, 2022 20:58
@the-csaba the-csaba reopened this Feb 9, 2022
Reason: To maintain PHP >=7.1.0 and make implementation PHP 8.1 compatible
@garethellis36
Copy link

@cebe Hi - please can you let me know if there is anything I can do to help get the required changes for PHP 8.1 compatibility merged? This is the remaining blocker for my application's upgrade. I'm happy to pitch in if necessary :)

@gniewomir-mohawk
Copy link

@cebe Hi - please can you let me know if there is anything I can do to help get the required changes for PHP 8.1 compatibility merged? This is the remaining blocker for my application's upgrade. I'm happy to pitch in if necessary :)

Hi, another volunteer here :) If i can help, I will.

@shadowhand
Copy link
Contributor

@cebe I sent you an email with a sponsorship offer to get this moving.

@shadowhand
Copy link
Contributor

I've opened a PR against this PR that will fix the build failure: https://github.com/OM4/php-openapi/pull/3

@cebe cebe mentioned this pull request Apr 20, 2022
@cebe cebe merged commit 8e592f7 into cebe:master Apr 20, 2022
@cebe
Copy link
Owner

cebe commented Apr 20, 2022

Thanks @shadowhand , I merged that fix in #162.
Thank you @om4csaba ! I merged this with some adjustments, see #162.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants