Я, честно говоря, понятия не имею, как сформулировать эту загадку - PullRequest
3 голосов
/ 27 марта 2012

Итак, вот что я вижу в этом коде:

  • Создан массив
  • Цикл повторяется 10 раз
    • Создается новый массив
    • Ссылка на этот новый массив сохраняется в первом массиве
  • 10 массивов теперь находятся в исходном массиве со значениями 0, 1, 2, 3 ...

Что на самом деле происходит:

  • WTF?

Код:

<?php

header('Content-type: text/plain');

$arrays = array();

foreach(range(0, 10) as $i)
{
    $arr = array();
    $arr[0] = $i;

    $arrays[] = &$arr;
}

print_r($arrays);

Вывод:

Array
(
    [0] => Array
        (
            [0] => 10
        )

    [1] => Array
        (
            [0] => 10
        )

    [2] => Array
        (
            [0] => 10
        )

    [3] => Array
        (
            [0] => 10
        )

    [4] => Array
        (
            [0] => 10
        )

    [5] => Array
        (
            [0] => 10
        )

    [6] => Array
        (
            [0] => 10
        )

    [7] => Array
        (
            [0] => 10
        )

    [8] => Array
        (
            [0] => 10
        )

    [9] => Array
        (
            [0] => 10
        )

    [10] => Array
        (
            [0] => 10
        )

)

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

Также, если кто-то, кто не просто думает WTF (как я) хотел бы отредактировать заголовок, не стесняйтесь.

Ответы [ 4 ]

3 голосов
/ 27 марта 2012

Линия

$arr = array();

не создает новый массив, а назначает пустой массив уже существующей ссылке. Если вы хотите, чтобы имя переменной «указывало» на другой массив в памяти, вы должны сначала unset() (или «отключить») его, прежде чем назначить ему пустой массив:

foreach(range(0, 10) as $i)
{
    unset($arr);
    $arr = array();
    $arr[0] = $i;

    $arrays[] = &$arr;
}

Это потому, что единственными операциями, которые могут заставить переменную указывать на что-то другое, является присвоение ссылки (=&) и unset().

1 голос
/ 27 марта 2012

Здесь происходит следующее: вставляя ссылку в $arr внутри $arrays, вы фактически добавляете один и тот же массив 10 раз - и каждой ссылке на массив присваивается последнее значение к нему (то есть тот, который получается, когда $i равен 10).

Непонятно, чего вы намерены достичь, вставляя ссылку в каждую итерацию - либо удаление &, либо помещение unset($arr) в начале цикла даст вам ожидаемое поведение. Что вы пытаетесь достичь?

0 голосов
/ 27 марта 2012

Думайте об этом так.Вы делаете $arrays[] = &$arr; 10 раз.Здесь хранится ссылка на локальную переменную $arr 10 раз.Поскольку это одна и та же переменная (область действия переменной - вся функция), она хранит одну и ту же ссылку все 10 раз.Таким образом, почему вы должны ожидать, что 10 элементов будут разными?

Ссылка, которую вы храните, не имеет ничего общего с значением из $arr;это просто связано с переменной $arr.Когда вы печатаете ссылку, в это время печатается значение $arr.

0 голосов
/ 27 марта 2012

Это потому, что вы сохраняете ссылку на массив, на который $arr указывает в массиве.И вы продолжаете перезаписывать этот массив последним номером.Все ссылки в $arr будут указывать на один и тот же массив в конце.

Я не знаю, что вы ожидаете получить от этого в конце, но избавление от & должно исправить это поведение.

...