Инкрементное выражение доступа к массиву без ключа - PullRequest
2 голосов
/ 25 апреля 2020

Почему это нормально в PHP (7.3)? Есть ли какой-либо вариант использования для этого?

<?php

$foo =  [10, 20, 30];
echo $foo[]++, "\n", ++$foo[], "\n", ++$foo[], "\n";

выходы:

php test.php

1
1

Я ожидал ошибку чтения, как показано ниже.

<?php

$foo = [10, 20, 30];
$foo[] += 1; // No error either
$foo[] = $foo[] + 1; //PHP Fatal error:  Cannot use [] for reading in

Ответы [ 2 ]

5 голосов
/ 25 апреля 2020

$foo[]++ сначала создает новую запись null в $foo, которая отображается как эхо, в результате чего появляется пустая строка (поскольку echo null; ничего не выводит). Новая запись в $foo затем увеличивается, поэтому null типа жонглируется до 0 как целое число, в результате чего значение 1.

++$foo[] создает еще один новый null запись в $foo, которая в данном случае увеличивается перед выводом, поэтому две строки с 1 в них.

Если вы измените свой код на использование var_dump вместо echo, вы можете увидеть это более четко:

$foo =  [10, 20, 30];
var_dump($foo[]++);
var_dump(++$foo[]);
var_dump(++$foo[]);
var_dump($foo);

Вывод:

NULL
int(1)
int(1)
array(6) {
  [0]=>
  int(10)
  [1]=>
  int(20)
  [2]=>
  int(30)
  [3]=>
  int(1)
  [4]=>
  int(1)
  [5]=>
  int(1)
}

Демонстрация на 3v4l.org

Обратите внимание, что в отличие от увеличения null, в результате 1, уменьшается null имеет нет эффекта (var_dump(--$foo[]) выводит null). Это поведение описано в руководстве .

2 голосов
/ 25 апреля 2020

Эта странная техника подталкивания - это то, что я не могу себе представить, нуждаясь в проекте, и с большой вероятностью могло бы смутить будущих читателей сценария.

Из 3v4l.org кажется, что это поведение согласуется с php7 .2 и выше.

Первый шаг - это постинкремент, поэтому перед его увеличением отображается начальный $foo[], равный null.

Вторые два приращения предварительные приращения, поэтому они отражают увеличенное значение.

При увеличении null создается 1, который отображается и сохраняется как 1. При уменьшении null создается null, который сохраняется как null и отображается как пустая строка.

Код: ( Демо )

$foo =  [10, 20, 30];
echo $foo[]++;
echo "\n---\n";
var_export($foo);
echo "\n---\n";
echo ++$foo[], "\n", --$foo[], "\n";
var_export($foo);
echo "\n===\n";
var_export(--$foo[]);

Вывод:

---
array (
  0 => 10,
  1 => 20,
  2 => 30,
  3 => 1,
)
---
1

array (
  0 => 10,
  1 => 20,
  2 => 30,
  3 => 1,
  4 => 1,
  5 => NULL,
)
===
NULL

Что-то, что изменилось с php7 .3, это то, что array_push() теперь будет принимать один параметр. ( Demo )

$foo = [];
array_push($foo);
var_export($foo);

Приведенный выше фрагмент не имеет эффекта - он не добавляет новый элемент. Счетчик остается нулевым, но предупреждение php7 .3.

не генерируется
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...