30

我试过这段代码

$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 索引的值不是负数?

4

3 回答 3

22

很奇怪,但记录在 Incrementing/Decrementing Operators php 文档页面上:

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

于 2013-07-11T11:51:48.483 回答
16

使用来源,卢克

像往常一样,答案在于源头。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;

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

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

default:
    return FAILURE;

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

这不是错误(tm)

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

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

关于布尔值:

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

关于字符串:

$letter = 'A';
var_dump(++$letter); // B
var_dump(--$letter); // B
于 2013-07-12T02:55:20.380 回答
3

奇怪的。我不知道他们对此的决定因素,但查看源代码,您会发现如果它正在处理 NULL,它会将其设置为 1(而不是递增)。

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

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

default:
    return FAILURE;

正如其他人所提到的,它已记录在案

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

于 2013-07-11T23:54:08.717 回答