8.1 / Exception / Property Type / Backwards compatbility

php.internals

Philip Hofstetter

5 years ago
Hello The following valid <= PHP 8.0 code that intends to make the $line property public is a fatal error in 8.1 class FooException extends Exception { public $line; } However, the fixed code for 8.1: class FooException extends Exception { public int $line; } Is a fatal error in <= 8.0 Is there a way to create a class that makes the $line property public that’s compatible with all versions of PHP without requiring conditional declaration of the class? For method return types, we have #[ReturnTypeWillChange], but for property types 🤷‍♀️ Philip

Unnamed Person

5 years ago
Den 2021-08-10 kl. 11:55, skrev Philip Hofstetter:
> Hello > > The following valid <= PHP 8.0 code that intends to make the $line property > public is a fatal error in 8.1 > > class FooException extends Exception { > public $line; > } > > However, the fixed code for 8.1: > > class FooException extends Exception { > public int $line; > } > > Is a fatal error in <= 8.0 > > Is there a way to create a class that makes the $line property public > that’s compatible with all versions of PHP without requiring conditional > declaration of the class? > > For method return types, we have #[ReturnTypeWillChange], but for property > types 🤷‍♀️ > > Philip >
Hi, Has this been adressed / solved in some way and does it needs to be fixed? I mean we are approaching RC1. r//Björn L

Dan Ackroyd

5 years ago
On Thu, 26 Aug 2021 at 12:42, Björn Larsson via internals <internals@lists.php.net> wrote:
> > Den 2021-08-10 kl. 11:55, skrev Philip Hofstetter: > > The following valid <= PHP 8.0 code that intends to make the $line property > > public is a fatal error in 8.1
....
> > > > For method return types, we have #[ReturnTypeWillChange], but for property > > types 🤷‍♀️
> Hi, > > Has this been adressed / solved in some way and does it needs > to be fixed?
My understanding is that the two scenarios are not the same and that there isn't much enthusiasm for 'fixing' it. For return types, the #[ReturnTypeWillChange] annotation is a temporary work-around, and one that would be used by a lot of people. It would only be used by a library until that library drops support for older versions of PHP. For the exception case, the way that (for legacy reasons) PHP supports having a public property in a child class that "overwrites" (mostly) the protected property in the parent class, is a pretty hinkey thing to do, and so this is likely to only affect a small number of people. It's not obvious to me how long a bridging annotation would need to hang around for, and it's really not obvious what the exact details of how it would work would be. I'd suggest using a getter method, which would work on all relevant versions. cheers Dan Ack

Ben Ramsey

5 years ago
Dan Ackroyd wrote on 8/26/21 09:43:
> On Thu, 26 Aug 2021 at 12:42, Björn Larsson via internals > <internals@lists.php.net> wrote: >> >> Den 2021-08-10 kl. 11:55, skrev Philip Hofstetter: >>> The following valid <= PHP 8.0 code that intends to make the $line property >>> public is a fatal error in 8.1 > .... >>> >>> For method return types, we have #[ReturnTypeWillChange], but for property >>> types 🤷‍♀️ > >> Hi, >> >> Has this been adressed / solved in some way and does it needs >> to be fixed? > > My understanding is that the two scenarios are not the same and that > there isn't much enthusiasm for 'fixing' it. > > For return types, the #[ReturnTypeWillChange] annotation is a > temporary work-around, and one that would be used by a lot of people. > It would only be used by a library until that library drops support > for older versions of PHP. > > For the exception case, the way that (for legacy reasons) PHP supports > having a public property in a child class that "overwrites" (mostly) > the protected property in the parent class, is a pretty hinkey thing > to do, and so this is likely to only affect a small number of people. > It's not obvious to me how long a bridging annotation would need to > hang around for, and it's really not obvious what the exact details of > how it would work would be. > > I'd suggest using a getter method, which would work on all relevant versions. > > cheers > Dan > Ack >
It's interesting to note that `$line` and `$file` both behave this way in PHP 8.1, but `$code` and `$message` do not. class Foo extends Exception { protected $code = 100; protected $message = 'Hello'; protected $line = 45; protected $file = '/path/to/file.php'; } Cheers, Ben

Nikita Popov

5 years ago
On Thu, Aug 26, 2021 at 4:43 PM Dan Ackroyd <Danack@basereality.com> wrote:
> On Thu, 26 Aug 2021 at 12:42, Björn Larsson via internals > <internals@lists.php.net> wrote: > > > > Den 2021-08-10 kl. 11:55, skrev Philip Hofstetter: > > > The following valid <= PHP 8.0 code that intends to make the $line > property > > > public is a fatal error in 8.1 > .... > > > > > > For method return types, we have #[ReturnTypeWillChange], but for > property > > > types 🤷‍♀️ > > > Hi, > > > > Has this been adressed / solved in some way and does it needs > > to be fixed? > > My understanding is that the two scenarios are not the same and that > there isn't much enthusiasm for 'fixing' it. > > For return types, the #[ReturnTypeWillChange] annotation is a > temporary work-around, and one that would be used by a lot of people. > It would only be used by a library until that library drops support > for older versions of PHP. > > For the exception case, the way that (for legacy reasons) PHP supports > having a public property in a child class that "overwrites" (mostly) > the protected property in the parent class, is a pretty hinkey thing > to do, and so this is likely to only affect a small number of people. > It's not obvious to me how long a bridging annotation would need to > hang around for, and it's really not obvious what the exact details of > how it would work would be. > > I'd suggest using a getter method, which would work on all relevant > versions. >
Right. I at least do not plan to address this issue. If you take a protected property and publicly re-export it, then any compatibility issues are on you. If you need to keep doing this for API stability reasons, then the way to do it would be a conditional class declaration. Or to keep the scope smaller, you can conditionally declare a trait with just the property and then use it inside a larger class. Regards, Nikita

Ben Ramsey

5 years ago
Nikita Popov wrote on 8/26/21 09:57:
> Right. I at least do not plan to address this issue. If you take a > protected property and publicly re-export it, then any compatibility issues > are on you.
This does not appear to affect only cases where one is re-exporting a protected property as public. Exception protected properties without type hints: * PHP <= 8.0 - https://3v4l.org/GWmrk * PHP 8.1 - https://3v4l.org/GWmrk/rfc Exception protected properties with type hints: * PHP <= 8.0 - https://3v4l.org/UX1Pa * PHP 8.1 - https://3v4l.org/UX1Pa/rfc Cheers, Ben

Unnamed Person

5 years ago
Den 2021-08-26 kl. 20:34, skrev Ben Ramsey:
> Nikita Popov wrote on 8/26/21 09:57: >> Right. I at least do not plan to address this issue. If you take a >> protected property and publicly re-export it, then any compatibility issues >> are on you. > > This does not appear to affect only cases where one is re-exporting a > protected property as public. > > Exception protected properties without type hints: > > * PHP <= 8.0 - https://3v4l.org/GWmrk > * PHP 8.1 - https://3v4l.org/GWmrk/rfc > > > Exception protected properties with type hints: > > * PHP <= 8.0 - https://3v4l.org/UX1Pa > * PHP 8.1 - https://3v4l.org/UX1Pa/rfc > > Cheers, > Ben >
So it looks like we have a bug here since the same code behaves differently between 8.0 and 8.1. I don't think it's obvoius that by adding a type hint we get different behaviour for the "same" code in 8.0 vs 8.1. The reason I brought this up is that in an Open source library it's discussed how to solve this. Loading different versions of the libray feels clunky. r//Björn L

Ben Ramsey

5 years ago
Philip Hofstetter wrote on 8/10/21 04:55:
> Hello > > The following valid <= PHP 8.0 code that intends to make the $line property > public is a fatal error in 8.1 > > class FooException extends Exception { > public $line; > } > > However, the fixed code for 8.1: > > class FooException extends Exception { > public int $line; > } > > Is a fatal error in <= 8.0 > > Is there a way to create a class that makes the $line property public > that’s compatible with all versions of PHP without requiring conditional > declaration of the class? > > For method return types, we have #[ReturnTypeWillChange], but for property > types 🤷‍♀️
This sounds like a bug. I don't see this reported yet in the bug tracker. Please open an issue at https://bugs.php.net Cheers, Ben

Alexandru Pătrănescu

5 years ago
On Tue, Aug 10, 2021 at 12:55 PM Philip Hofstetter < phofstetter@sensational.ch> wrote:
> Hello > > The following valid <= PHP 8.0 code that intends to make the $line property > public is a fatal error in 8.1 > > class FooException extends Exception { > public $line; > } > > However, the fixed code for 8.1: > > class FooException extends Exception { > public int $line; > } > > Is a fatal error in <= 8.0 > > Is there a way to create a class that makes the $line property public > that’s compatible with all versions of PHP without requiring conditional > declaration of the class? > >
Not sure exactly why you need to $line property public. If you need to be able to read it, you can use __get. If you also need to write it, as that also worked, you can also use __set. So an example that offers the same interface/interaction possible would be: https://3v4l.org/tHhEL#v8.0.9 https://3v4l.org/tHhEL/rfc#vgit.master But of course, when you look at the object with reflection, or how var_dump prints it, the property will still be protected. Regards, Alex