UNSET не удаляет/сбрасывает значения массива навсегда

У меня есть следующий скрипт для приложения карт Google. Информация о конкретном месте отправляется через ajax в массив $array, который затем добавляется в $SESSION['infomarker']. Эта часть работает нормально. Но пользователь также должен иметь возможность удалить место (если он пожалеет о вводе).

Это обрабатывается функцией removeElementWithValue(), которая принимает значения lat и lng в качестве аргументов ($val1 и $val2 в этом примере скрипта). Затем массив, содержащий значения 'val1' и 'val2', исчезает, как и должно быть. Но когда я изменяю переменные $val1 и $val2 на «val3» и «val4», массив, содержащий «val1» и «val2», возвращается, а массив, содержащий «val3» и «val4», не устанавливается.

Я думал, что unset() «сбросил» рассматриваемый массив навсегда, или мне нужно сделать что-то еще?

<?php
session_start();


if(isset($_POST['lat']) && !empty($_POST['lat']) ) {
$array = array(
                'titel' => $_POST['titel'], 
                'comment' => $_POST['comment'], 
                'lat' => $_POST['lat'], 
                'lng' => $_POST['lng'] 
                );


$_SESSION['infomarker'][] = $array;


   }    

  $val1 = 'val1';

  $val2 = 'val2';


  $newarray = removeElementWithValue($_SESSION['infomarker'], "titel", "comment", $val1, $val2);

 function removeElementWithValue($array, $key1, $key2, $value1, $value2){
 foreach($array as $subKey => $subArray){
      if($subArray[$key1] == $value1) {
      if($subArray[$key2] == $value2) 

         unset($array[$subKey]);

      }

   }
return $array;

}

print_r($newarray);

person user1009453    schedule 08.01.2013    source источник


Ответы (2)


Вы изменяете $array, который передается вашему методу removeElementWithValue. Вы передаете массив $_SESSION в метод.

unset делает то, что должен, удаляя значение из $array. Но ваш метод фактически получает копию переменной $_SESSION, поскольку PHP будет передавать массивы по значению, а не по ссылке.

Вы можете префиксировать переменную $array в объявлении функции с помощью символа амперстенда (&), который сообщит PHP о необходимости передать эту переменную в функцию по ссылке и приведет к тому, что любые изменения, внесенные в массив внутри функции, изменят исходный код. массив ($_SESSION).

Уточнение:

Вызов функции создает область в «стеке» для этого метода. PHP по умолчанию передает все по значению (для тех, кто хочет утверждать, что объекты передаются по ссылке - это не так. Ссылка на объект передается по значению).

Что это значит? Что ж, это проще, чем кажется. Возьмите код ниже:

function myfunc($value) {
  $value = $value + 1;
}

$testing = 1;
myfunc($testing);
var_dump($testing);

Это выведет int(1). Обратите внимание, что хотя мы увеличиваем значение внутри функции, результат не изменяет переменную $testing. Это связано с тем, что переменная $testing была объявлена ​​в другой области внутри стека. Насколько PHP видел, когда мы вызывали метод, мы фактически вызывали это myfunc(1) (обратите внимание на число вместо переменной). Значение переменной было взято из памяти и передано в метод.

Вот где передача по ссылке пригодится. Вы можете указать PHP передавать по ссылке, добавляя к любому аргументу в определении функции префикс амперстанда, так что вы получите следующее:

function myfunc(&$value) {
  $value = $value + 1;
}

$testing = 1;
myfunc($testing);
var_dump($testing);

Добавление простого амперсанда теперь заставит этот код напечатать int(2).

Так в чем разница? Ну, вы помните, что я сказал, что в первый раз мы в основном звоним myfunc(1). Во второй раз мы фактически вызываем myfunc(0xff940ac4), где 0xff940ac4 — адрес памяти для переменной $testing. Теперь любые изменения, которые мы вносим в $value внутри метода, изменят данные по адресу памяти 0xff940ac4 вместо значения, которое было «скопировано» в область видимости для этого метода.

person Colin M    schedule 08.01.2013
comment
Хорошо, не совсем уверен, что вы имеете в виду, но я добавил амперсанд, и это помогло. Я должен буду прочитать об этом! Спасибо большое однако! - person user1009453; 08.01.2013
comment
Хорошо, не совсем уверен, что это значит, но я добавил амперсанд, и это помогло. Я должен буду прочитать об этом! Большое спасибо! - person user1009453; 08.01.2013
comment
Просто добавил большое объяснение - дайте мне знать, если это поможет. - person Colin M; 08.01.2013
comment
Очень хорошее объяснение, даже я теперь понимаю разницу :) Спасибо, что нашли время, чтобы объяснить это! - person user1009453; 09.01.2013

Это потому, что в PHP по умолчанию массивы передаются не по ссылке, а по значению. Таким образом, функция, которую вы используете, удалит значения из $array внутри функции. Но это не изменит функцию. Если вы хотите иметь такое поведение, PHP должен передавать значение by-reference< /а>.

Вы можете сделать это, изменив определение функции следующим образом:

function removeElementWithValue(&$array, $key1, $key2, $value1, $value2)
{ ... }
person kokx    schedule 08.01.2013