Подтвердить что ты не робот

PHP: заменить значение массива не остается после цикла foreach

Я изменяю значение в многомерном массиве и не остаюсь вне цикла 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;
}

Если I

print_r($person)

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

От документация foreach:

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

Это означает, что ваша переменная $person является копией того, что было в массиве, аналогично поведению этого кода (обратите внимание, что этот код предназначен только для понимания и неправильный на многих уровнях, на самом деле вы бы использовали reset(), 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 { ...

Ответ 3

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

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

Ответ 4

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

Я нахожу это решение более надежным:

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

  //logic for the visited variable

  $people[$key]['visited']=$calculated_visit_value;
}