为什么在这个数组中递减NULL而不是负数?

mrs*_*vas 30 php

我试过这段代码

$a = array_fill(0, 4, NULL);
$a[0]++;
++$a[1];
$a[2]--;
--$a[3];
var_dump($a);
Run Code Online (Sandbox Code Playgroud)

结果:

array(4) {
    [0]=> int(1)
    [1]=> int(1)
    [2]=> NULL
    [3]=> NULL
}
Run Code Online (Sandbox Code Playgroud)

为什么2和3指数的值不是负数?

fvu*_*fvu 22

奇怪,但记录递增/递减运算符PHP文档页面上:

注意:递增/递减运算符不会影响布尔值.递减NULL值也没有效果,但递增它们会产生1.

  • 记录 - >不是错误;-) (9认同)
  • @zerkms但至少可以说是对[最小惊讶原则]的严重违反(https://en.wikipedia.org/wiki/Principle_of_least_astonishment) (5认同)

Ja͢*_*͢ck 15

使用来源,卢克

像往常一样,答案在于源头.PHP在内部使用以下两个函数来执行递增和递减操作:

ZEND_API int increment_function(zval *op1)

ZEND_API int decrement_function(zval *op1)

这些操作op1根据类型(NULL类型)修改参数; increment_function()你可以在里面看到代码中的以下分支:

case IS_NULL:
    ZVAL_LONG(op1, 1);
    break;
Run Code Online (Sandbox Code Playgroud)

上面的代码将类型更改op1为数字并将其值设置为1.

相反,不decrement_function()提供此类分支,因此将执行默认操作:

default:
    return FAILURE;
Run Code Online (Sandbox Code Playgroud)

运行此代码实际上不会产生任何可观察到的失败,因为返回值在Zend VM中被吸收,但变量肯定也不会更新.

这不是一个bug(tm)

您可能会惊讶地发现此行为(包括布尔值的行为)实际上已记录在案:

注意:递增/递减运算符不会影响布尔值.递减NULL值也没有效果,但递增它们会导致1.

关于布尔值:

$a = true;
var_dump($a--); // true
$a = false;
var_dump($a++); // false
Run Code Online (Sandbox Code Playgroud)

关于字符串:

$letter = 'A';
var_dump(++$letter); // B
var_dump(--$letter); // B
Run Code Online (Sandbox Code Playgroud)

  • 它不是一个bug,因为它有记录? (11认同)
  • @soc [什么是软件错误?](http://en.wikipedia.org/wiki/Software_bug):软件错误是计算机程序或系统中产生错误或*的错误,缺陷,失败或错误*意外的**结果,或导致它以**非预期的方式表现.但是,由于它已被记录,因此它是**预期的**和**预期**行为. (3认同)