Doc #81511 [Nab]: Evaluation order for . operator should be specified
Edit report at https://bugs.php.net/bug.php?id=81511&edit=1
ID: 81511
User updated by: dean at omnivisiontechnology dot com
Reported by: dean at omnivisiontechnology dot com
Summary: Evaluation order for . operator should be specified
Status: Not a bug
Type: Documentation Problem
Package: Unknown/Other Function
Operating System: n/a
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Well obviously. But I did say *concise* code!
Also I rather suspect there's lots of code like my example out in the wild, which would break
if the . operator didn't evaluate LHS first.
You read strings left-to-right (in most languages), so psychologically I think programmers expect
and assume it's going to work that way, much more than for other (non-string) operators.
Previous Comments:
------------------------------------------------------------------------
[2021-10-07 18:04:28] requinix@php.net
if ($a) {
$s = "option A";
} else if ($b) {
$s = "option B";
} else if ($c) {
$s = "option C";
} else {
$v = expensiveFunction();
$s = "Value is: {$v} other stringy stuff {$v}";
}
------------------------------------------------------------------------
[2021-10-07 10:25:23] dean at omnivisiontechnology dot com
If evaluation order might change, then there's nothing to be done.
But I'd note that "clever" or not, this idiom can be very useful in writing concise
code, for example buried deep inside nested ternaries, where you can only put an expression and not
a statement block, e.g.
$s = ($a ? "option A" : ($b ? "Option B" : ($c ? "Option C" :
'Value is: '.($v = expensiveFunction())." other stringy stuff ".$v)));
vs
if (!($a||$b||$c)) $v = expensiveFunction();
$s = ($a ? "option A" : ($b ? "Option B" : ($c ? "Option C" :
'Value is: '.$v." other stringy stuff ".$v)));
which apart from being longer, also contains the same condition check in two places (and in two
different formats), leading to potential bugs if one is changed and the other is not.
------------------------------------------------------------------------
[2021-10-07 08:26:41] requinix@php.net
It isn't specified because it isn't guaranteed. It's generally left to right, sure,
but the exact behavior may change in the future if PHP alters how it parses and executes code. Not
guaranteeing behavior also potentially allows caching or optimization extensions more freedom in the
benefits they can offer.
It's a bad idiom. Don't use it. "Clever" code doesn't benefit anyone.
------------------------------------------------------------------------
[2021-10-07 06:56:50] dean at omnivisiontechnology dot com
Description:
------------
---
From manual page: https://php.net/language.operators.string
---
In general, PHP doesn't specify the order of evaluation for operators.
However, order of evaluation for the string concatenation operator specifically, does always seem
to be left then right.
If this can indeed be guaranteed, then it should be specified in the documentation, because it
enables the very common coding idiom:
$string = 'something'.($complicatedSubstring = 'something else').'more
stuff'.$complicatedSubstring;
Test script:
---------------
$s = '[Very bad!]'
$x = 'bar '.($s = 'foo').' bar bar '.$s.' bar';
Expected result:
----------------
$x should be 'bar foo bar bar foo bar'.
It'd be very unexpected for it to be 'bar foo bar bar [Very bad!] bar',
But that's what could happen if the . operator evaluated the RHS first... which fortunately it
doesn't appear to.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81511&edit=1
Thread (6 messages)