Null-safe property access in interpolated strings

php.internals

Sara Golemon

6 years ago
Do we expect this to work? $foo = new stdClass; $foo->bar = "Hello"; echo "$foo?->bar world\n"; Because at the moment it doesn't: https://3v4l.org/nLv3l -Sara

Marco Pivetta

6 years ago
On Sun, Aug 9, 2020, 00:17 Sara Golemon <pollita@php.net> wrote:
> Do we expect this to work? > > $foo = new stdClass; > $foo->bar = "Hello"; > echo "$foo?->bar world\n"; > > Because at the moment it doesn't: https://3v4l.org/nLv3l > > -Sara >
Ooof, people still interpolate strings that way? Good riddance if it doesn't work: this code is questionable (and not just because of the question mark in it) 👍

Yousuf Tafhim

6 years ago
What are the good uses cases for this to work? On Sun, Aug 9, 2020 at 8:48 AM Marco Pivetta <ocramius@gmail.com> wrote:

Ilija Tovilo

6 years ago
Hi internals
> Do we expect this to work? > > $foo = new stdClass; > $foo->bar = "Hello"; > echo "$foo?->bar world\n"; > > Because at the moment it doesn't: https://3v4l.org/nLv3l
The patch can be found here: https://github.com/php/php-src/pull/5966 It adds ~5 lines to the lexer. As mentioned, there is a BC break although it is probably very small (I could find no code that breaks on grep.app). Because this BC break was never mentioned in the RFC I'm leaning towards not merging this patch but I am happy either way. Let's hear from a few more people what they think until we decide how to move forward. Ilija

Jordi Boggiano

6 years ago
On 09/08/2020 00:17, Sara Golemon wrote:
> Do we expect this to work? > > $foo = new stdClass; > $foo->bar = "Hello"; > echo "$foo?->bar world\n"; > > Because at the moment it doesn't: https://3v4l.org/nLv3l > > -Sara
Can't say I'm big on interpolation but I'd definitely expect this to work because why not? I think if it can be reasonably fixed it probably would make sense for consistency and WTF-avoidance if anything. Best, Jordi
-- Jordi Boggiano @seldaek - https://seld.be

Deleu

6 years ago
I like and make use of interpolation, but I can't think of a use case for this. Is there any valid use case that would benefit from this fix regardless of personal preference? In other words, where would one use string interpolation with an empty string being a valid case? On Sun, Aug 9, 2020, 20:34 Jordi Boggiano <j.boggiano@seld.be> wrote:

Mike Schinkel

6 years ago
> > On Aug 9, 2020 at 3:00 PM, <Deleu (mailto:deleugyn@gmail.com)> wrote: > > > > I like and make use of interpolation, but I can't think of a use case for this. Is there any valid use case that would benefit from this fix regardless of personal preference? In other words, where would one use string interpolation with an empty string being a valid case? > >
While I agree with Jordi and Nikita that language consistency is the important metric, here is a valid case I come across frequently; the need to output optional CSS classes since you ask, fwiw:
> > > > > > > <?php
$card_html = <<<HTML <div id="card-{$card->id}" class="card {$card?->css}"> {$card->content} </div> HTML; -Mike

Ilija Tovilo

6 years ago
Hi Mike
> $card_html = <<<HTML <div id="card-{$card->id}" class="card {$card?->css}"> {$card->content} </div> HTML;
Two things: 1. We're solely talking about string interpolation without braces {}. You're using braces in your example and this does indeed work right now. 2. The semantics of ?-> are different than you're depicting them to be in this example. ?-> will only short-circuit if $card is null, not when the property "css" is not defined. Thus, if $card was null your example would've already failed at $card->id. Ilija

Mike Schinkel

6 years ago
> > On Aug 10, 2020 at 11:02 AM, <Ilija Tovilo (mailto:tovilo.ilija@gmail.com)> wrote: > > > > Hi Mike > $card_html = <<<HTML <div id="card-{$card->id}" class="card {$card?->css}"> {$card->content} </div> HTML; Two things: 1. We're solely talking about string interpolation without braces {}. You're using braces in your example and this does indeed work right now. > > > > > > >
Thank you for clarifying. That was not obvious to me. If it was explicitly mentioned in the thread and I missed it, I apologize.
> > > 2. The semantics of ?-> are different than you're depicting them to be in this example. ?-> will only short-circuit if $card is null, not when the property "css" is not defined. Thus, if $card was null your example would've already failed at $card->id. > > > > > > >
Good point. I was remembering a frequent problem but did not convey the use-case correctly so please let me update it:
> > class="card {$card->attributes?->css}" > > > > > The only real information I was trying to convey was that when generating HTML there is a frequent need to output a value if one exists but output nothing otherwise. So hopefully this time I got the usage correct for this new feature.
-Mike P.S. I would have tested it before sending, but I do not have a local PHP install that I can test this syntax with yet.

Nikita Popov

6 years ago
On Sun, Aug 9, 2020 at 8:34 PM Jordi Boggiano <j.boggiano@seld.be> wrote:
> On 09/08/2020 00:17, Sara Golemon wrote: > > Do we expect this to work? > > > > $foo = new stdClass; > > $foo->bar = "Hello"; > > echo "$foo?->bar world\n"; > > > > Because at the moment it doesn't: https://3v4l.org/nLv3l > > > > -Sara > > Can't say I'm big on interpolation but I'd definitely expect this to > work because why not? > > I think if it can be reasonably fixed it probably would make sense for > consistency and WTF-avoidance if anything. > > Best, > Jordi >
Agree. I don't think the question of whether it is useful should come into this, it's a matter of language consistency. There could be some leeway here if we say that we have plans to deprecate the "$x->y" syntax in the future anyway and don't want to extend it anymore -- but I don't believe we have such plans at the present time. Nikita

Ilija Tovilo

6 years ago
Hi Nikita
> > I think if it can be reasonably fixed it probably would make sense for > > consistency and WTF-avoidance if anything. > > Agree. I don't think the question of whether it is useful should come into > this, it's a matter of language consistency. There could be some leeway > here if we say that we have plans to deprecate the "$x->y" syntax in the > future anyway and don't want to extend it anymore -- but I don't believe we > have such plans at the present time.
So for the sake of consistency let's merge this then. As mentioned, the BC break should be very very small. A few people have mentioned they didn't expect it to work but when asked again they didn't feel strongly about it. Unless there are objections I will merge this tomorrow. A review of the PR would also be welcome. Ilija

Björn Larsson

6 years ago
Hi Ilija, Den 2020-08-10 kl. 17:06, skrev Ilija Tovilo:
> Hi Nikita > >>> I think if it can be reasonably fixed it probably would make sense for >>> consistency and WTF-avoidance if anything. >> Agree. I don't think the question of whether it is useful should come into >> this, it's a matter of language consistency. There could be some leeway >> here if we say that we have plans to deprecate the "$x->y" syntax in the >> future anyway and don't want to extend it anymore -- but I don't believe we >> have such plans at the present time. > So for the sake of consistency let's merge this then. As mentioned, > the BC break should be very very small. A few people have mentioned > they didn't expect it to work but when asked again they didn't feel > strongly about it. > > Unless there are objections I will merge this tomorrow. A review of > the PR would also be welcome. > > Ilija
I second Nikitas opinion that consistency is important here. One shouldn't need to spend time as an PHP end user wondering why we have a special case that doesn't work like the rest! Good luck with merging. r//Björn L

Philip Hofstetter

6 years ago
Hi, On Sun, Aug 9, 2020 at 8:34 PM Jordi Boggiano <j.boggiano@seld.be> wrote:
> Can't say I'm big on interpolation but I'd definitely expect this to > work because why not?
A reason why not is because it will break backwards compatibility with existing (though admittedly unlikely) code which also can't be fixed by easy search and replace: $foo = "gnegg"; echo "$foo?->bar()" would be fine in PHP < 8 and would blow up with `Uncaught Error: Call to a member function bar() on string` with this change. I'm not saying this is a problem because code like this is unlikely to be written, but it *is* a BC break. Philip