Я пробовал этот код
$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 не является отрицательным?
Используйте источник, Люк
Как обычно, ответ лежит в источнике. 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, но переменная определенно не обновляется.
Это не ошибка ™
Вы можете быть удивлены, узнав, что это поведение, в том числе и для логических значений, действительно документировано :
Примечание. Операторы increment / decment не влияют на логические значения. Уменьшение значений
NULL
также не влияет, но приращение их приводит к1
.
Что касается булевых:
$a = true; var_dump($a--); // true $a = false; var_dump($a++); // false
Что касается строк:
$letter = 'A'; var_dump(++$letter); // B var_dump(--$letter); // B
Странно, но задокументировано на странице «Приращения / сокращения» php doc:
Примечание. Операторы increment / decment не влияют на логические значения. Уменьшение значений NULL также не влияет, но приращение их приводит к 1.
Странный. Я не знаю их решающего фактора для этого, но, глядя на исходный код , вы увидите, что если он имеет дело с NULL, он устанавливает его в 1 (не приращение).
case IS_NULL: ZVAL_LONG(op1, 1); break;
Функция декремента вообще не имеет отношения к NULL и идет прямо к ошибке:
default: return FAILURE;
Как уже упоминалось, это документировано .
Примечание. Операторы increment / decment не влияют на логические значения. Уменьшение значений
NULL
также не влияет, но приращение их приводит к1
.