如影随形

影子是一个会撒谎的精灵,它在虚空中流浪和等待被发现之间;在存在与不存在之间....

您现在的位置是:首页>技术文章>详情

var_dump(1...9)输出什么?

发布时间:2020-07-27文章类型:转载浏览(5636)




原文地址:https://www.laruence.com/2020/02/23/1990.html

    一个问题, var_dump(1...9)输出什么?

    动手验证下:

    1. php -r “var_dump(1...9)”;
    2. string(4) ”10.9“

    输出10.9, 乍一看这个var_dump的输出很奇怪是不是? 为什么呢?

    这里教大家,如果看到一段PHP代码感觉输出很奇怪,第一反应是看下这段代码生成的opcodes是啥,虽然这个问题其实是词法分析阶段的问题,不过还是用phpdbg分析下吧(一般为了防止opcache的影响,会传递-n):

    1. phpdbg -n -p /tmp/1.php
    2. function name: (null)
    3. L1-35 {main}() /tmp/1.php - 0x7f56d1a63460 + 4 ops
    4. L2 #0 INIT_FCALL<1> 96 "var_dump"
    5. L2 #1 SEND_VAL "10.9" 1
    6. L2 #2 DO_ICALL
    7. L35 #3 RETURN<-1> 1

    所以这么看来,早在生成opcode之前,1...9就变成了常量10.9,考虑到这是字面量,我们现在去看看zend_language_scanner.l, 找到这么一行:

    1. DNUM ({LNUM}?"."{LNUM})|({LNUM}"."{LNUM}?)

    这个是词法分析定义的浮点数的格式,到这里也就恍然大悟了:
    1...9 会被依次接受为: 1. (浮点数1), 然后是 . (字符串连接符号) 然后是.9(浮点数0.9)

    所以在编译阶段就会直接生成 “1” . “0.9” -> 字符串的字面量”10.9”

    好了,到这里,这个小“谜题”就解释清楚了。

    当然这个也不仅仅是PHP会这么定义了,几乎所有的语言都会定义这种缩写浮点数都形式. C语言中有的时候我们为了输入一个浮点型的整形,就可以采用比如 1. 来告诉编译器这是个浮点数.

    只不过,一来刚好在PHP中.号还有另外一层含义就是字符串连接,二来...在PHP5.6之后是个新的操作符叫做Splat operator, 可以用来定义可变参数函数,或者解数组,比如,

    1. <?php
    2.  
    3. function foo($a, $b, $c) {
    4.         var_dump($a + $b + $c);
    5. }
    6.  
    7.  
    8. $parameters = array (1, 2, 3);
    9.  
    10. foo(...$parameters);
    11. ?>
    12.  

    所以, 乍一看才会导致了这个看起来很困惑的结果, 🙂

关键字词:var_dump(1...9)输出什么?