- URL: https://www.laruence.com/en/2020/02/23/1990.html
- Please include attribution when republishing.
A question: what does var_dump(1...9) output?
Let's verify by hand:
php -r “var_dump(1...9)”; string(4) ”10.9“
It outputs 10.9. At first glance this var_dump output looks pretty strange, doesn't it? Why?
Here's a tip: when you see a piece of PHP code whose output feels very strange, your first reaction should be to look at the opcodes that code generates. Although this problem is actually a lexical-analysis-stage issue, let's still analyze it with phpdbg (we usually pass -n to avoid the influence of opcache):
phpdbg -n -p /tmp/1.php
function name: (null)
L1-35 {main}() /tmp/1.php - 0x7f56d1a63460 + 4 ops
L2 #0 INIT_FCALL<1> 96 "var_dump"
L2 #1 SEND_VAL "10.9" 1
L2 #2 DO_ICALL
L35 #3 RETURN<-1> 1
So it looks like, long before the opcode was generated, 1...9 had already become the constant 10.9. Given that this is a literal, let's now go look at zend_language_scanner.l, where we find this line:
DNUM ({LNUM}?"."{LNUM})|({LNUM}"."{LNUM}?)
This is the floating-point format defined by the lexical analyzer. And now it suddenly all makes sense:
1...9 is consumed in turn as: 1. (the float 1), then . (the string concatenation operator), then .9 (the float 0.9).
So at compile time it directly generates "1" . "0.9" -> the string literal "10.9".
And with that, this little "puzzle" is explained.
Of course, this isn't something only PHP defines this way — almost every language defines this abbreviated float form. In C, when we want to write a floating-point value that looks like an integer, we can use something like 1. to tell the compiler it's a float.
It's just that, first, in PHP the . character also carries another meaning — string concatenation — and second, since PHP 5.6 ... is a new operator called the Splat operator, which can be used to define variadic functions or to unpack arrays. For example,
<?php
function foo($a, $b, $c) {
var_dump($a + $b + $c);
}
$parameters = array (1, 2, 3);
foo(...$parameters);
?>
So at first glance this leads to a result that looks very confusing. 🙂
Be First to Comment