PHP автовивификация - PullRequest
8 голосов
/ 11 мая 2011

Обновление. Первоначально я хотел выяснить, есть ли в PHP эта функция. Это было потеряно в фокусе ответов на скалярной проблеме. Пожалуйста, посмотрите новый вопрос: «Есть ли в PHP автовивификация?» Этот вопрос оставлен здесь для справки.

Согласно Википедии , PHP не имеет автовивификации, но этот код работает:

$test['a']['b'] = 1;
$test['a']['c'] = 1;
$test['b']['b'] = 1;
$test['b']['c'] = 1;

var_dump($test);

Выход:

array
  'a' => 
    array
      'b' => int 1
      'c' => int 1
  'b' => 
    array
      'b' => int 1
      'c' => int 1

Я обнаружил, что этот код тоже работает:

$test['a'][4] = 1;
$test['b'][4]['f'] = 3;

Но добавление этой строки вызывает предупреждение («Предупреждение: невозможно использовать скалярное значение в качестве массива»)

$test['a'][4]['f'] = 3;

Что здесь происходит? Почему происходит сбой при добавлении ассоциативного элемента после индекса? Это «настоящая» Perl-подобная автовивификация или какая-то ее разновидность или что-то еще?

Редактировать: о, теперь я вижу ошибку со скаляром, упс! Эти работы, как и ожидалось:

$test['a'][4]['a'] = 1;
$test['a'][4]['b'] = 2;
$test['a'][5]['c'] = 3;
$test['a'][8]['d'] = 4;

Итак, у php есть автовификация? Поиск в Google по запросу "php autovivification" не приводит к каноническому ответу или его примеру.

Ответы [ 3 ]

7 голосов
/ 11 мая 2011

Из руководства по PHP в синтаксисе в квадратных скобках:

$arr[] = value;

Если $arr еще не существует, он будет создан, так что это также альтернативный способ создания массива

На вашем примере:

$test['a'][4] = 1;

Поскольку $test и $test['a'] в настоящее время не существует; они оба созданы как массивы.

$test['b'][4]['f'] = 3;

$test['b'] и $test['b'][4] в настоящее время не существуют; они оба созданы как массивы.

$test['a'][4]['f'] = 3;

$test['a'][4] существует , но это целое число (1). Это «скалярное значение», которое нельзя использовать в качестве массива. Вы не можете использовать квадратную скобку [] синтаксис для числовых значений; он не преобразует существующее значение в массив.

2 голосов
/ 11 мая 2011

По результатам PHP имеет автовивификацию.Ошибка возникает из-за того, как она работает.

Когда вы говорите: $ a [1] [2] = 55, PHP хочет вставить 55 в $ a [1] как [2] => 55.Поскольку $ a [1] не существует, PHP автоматически создает пустой узел , cca.$ a [1] = Array ().Но когда узел уже существует, PHP не создает $ a [1], он просто выполняет [2] => 55, что является ошибкой, если $ a [1] не похож на массив (массив, объект).

Последний язык, который я видел, где узлы могут иметь значение, а также потомки, это MUMPS.Была также функция с именем $ DATA (), которая сообщала, есть ли у узла дочерний элемент (10), значение (1) или оба (11), или он не существует (0).Я думаю, что это правильная обработка ассоциативных массивов.

(Во всяком случае, мне нравится такое поведение PHP.)

1 голос
/ 11 мая 2011

С:

$test['b'][4]['f'] = 3;

Вы не добавляете элемент к

$test['a'][4]

потому что он не инициализирован как массив.

Если вы напишите:

$test['a'][4] = array(1);

Тогда это будет работать.

С:

$test['a']['b'] = 1;
$test['a']['c'] = 1;
$test['b']['b'] = 1;
$test['b']['c'] = 1;

Вы неявно инициализируете $test['a'] и $test['b'] как массив. Но $test['a']['b'] (и т. Д.) Как int

...