6

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

 3 years ago
source link: https://www.laruence.com/2020/02/23/1990.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

一个问题, 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. function foo($a, $b, $c) {
  3.         var_dump($a + $b + $c);
  4. $parameters = array (1, 2, 3);
  5. foo(...$parameters);
  6. ?>

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK