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

时间:2013-07-11 11:46:31

标签: php

我试过这段代码

$a = array_fill(0, 4, NULL);
$a[0]++;
++$a[1];
$a[2]--;
--$a[3];
var_dump($a);

结果:

array(4) {
    [0]=> int(1)
    [1]=> int(1)
    [2]=> NULL
    [3]=> NULL
}

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

3 个答案:

答案 0 :(得分:22)

很奇怪,但documented在增量/减少运算符php文档页面上:

  

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

答案 1 :(得分:15)

使用来源,Luke

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

ZEND_API int increment_function(zval *op1)

ZEND_API int decrement_function(zval *op1)

这些操作根据其类型修改op1参数(NULL是一种类型);在increment_function()内,您可以看到以下分支in the code

case IS_NULL:
    ZVAL_LONG(op1, 1);
    break;

上述代码会将op1的类型更改为数字,并将其值设置为1

相反,decrement_function()不提供此类分支,因此default action将会执行:

default:
    return FAILURE;

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

这不是错误(tm)

您可能会惊讶地发现此行为(包括布尔值的行为)实际上是documented

  

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

关于布尔值:

$a = true;
var_dump($a--); // true
$a = false;
var_dump($a++); // false

关于字符串:

$letter = 'A';
var_dump(++$letter); // B
var_dump(--$letter); // B

答案 2 :(得分:3)

奇怪。我不知道他们的决定因素,但是看source code,你会看到如果它处理的是NULL,它会将它设置为1(不是递增)。

case IS_NULL:
    ZVAL_LONG(op1, 1);
    break;

decrement函数根本不处理NULL并直接进入FAILURE:

default:
    return FAILURE;

正如其他人所说,它是documented

  

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