PHP: замена массива не остается после цикла foreach - PullRequest
12 голосов
/ 20 июля 2011

Я изменяю значение в многомерном массиве, и оно не выходит за пределы цикла foreach, который используется для его обхода.

Мой массив изначально выглядит примерно так:

Array
{
  [0] => Array
   {
     [name] => Bob
     [age] => 33
     [state] => CA
     [visited] => 0
   }
   ...
}

Мой PHP входит в него следующим образом:

foreach ($people as $person){
 echo $person['name']
 ....
 logic for the visited variable
 ...
 $person['visited'] = $calculated_visit_value;
}

Если я

print_r($person)

в конце (но внутри) цикла foreach, все выглядит хорошо, значение дляПосещение установлено.Однако, если I print_r($people) вне цикла, $person['visited'] не устанавливается.Я не знаю, что я делаю не так.

Помощь приветствуется.

Ответы [ 4 ]

37 голосов
/ 20 июля 2011

Вы создаете новую переменную с именем $person внутри цикла for, и ваш массив никогда не увидит область действия этой новой переменной.

Вы можете попробовать передать его по ссылке, например так:

foreach ($people as &$person){
 echo $person['name'];
 ....
 logic for the visited variable
 ...
 $person['visited'] = $calculated_visit_value;
}
3 голосов
/ 20 июля 2011

Из документации foreach :

Если на массив не ссылаются, foreach работает с копией указанный массив, а не сам массив. foreach имеет какую-то сторону влияние на указатель массива. Не полагайтесь на указатель массива во время или после foreach без сброса.

Это означает, что ваша переменная $ person является копией того, что было в массиве, по сути аналогично этому коду (обратите внимание, что этот код предназначен только для понимания и неверен на многих уровнях, в действительности вы должны использовать сброс (), current () и next () - функция для правильного зацикливания массива, см. здесь ):

for ($i = 0; $i < count($people); $i++) {
  $person = $people[$i];
  // code inside your foreach ...
}

Поэтому, если вы измените содержимое $ person, вы на самом деле не измените содержимое массива $ people

Чтобы решить эту проблему, вы можете использовать ссылку foreach:

foreach ($people as &$person) { // note the &
  $person = $calculated_visit_value; // $person is now a reference to the original value inside $people and thus this will work as intended
}

Обратите внимание, что refence не очищается, когда цикл foreach заканчивается, поэтому в конце его $ person по-прежнему ссылается на последний элемент $ people. Если вы не знаете, что такое ссылки, пожалуйста, обратитесь к документации для получения дополнительной информации.

Или используйте ключ для доступа к исходному массиву:

foreach ($people as $person_index => $person) {
  $people[$person_index] = $calculated_visit_value;
}

Для вашей информации, вы можете использовать оба вместе

foreach ($people as $person_index => &$person { ...
0 голосов
/ 17 октября 2013

Как уже было сказано, «вы создаете новую переменную с именем $ person из цикла for, и ваш массив никогда не увидит область действия этой новой переменной».:

foreach ($people as $key => $person)
{
  echo $person['name']; 

  //logic for the visited variable

  $people[$key]['visited']=$calculated_visit_value;
}
0 голосов
/ 20 июля 2011

Массив $person создается на каждой итерации, поэтому установка этого значения в любом случае будет перезаписана на следующем проходе.

Но даже в этом случае этот массив существует только во время цикла.Вы должны создать еще один массив перед циклом и поместить свои значения в этот массив во время цикла.

...