Необходимо отменить установку определенного сессионного массива

#php #session #multidimensional-array

#php #сессия #многомерный массив

Вопрос:

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

Это код, который хранит переменные сеанса:

 $_SESSION['product'][] = array(
        'product_id' => $part_id,
        'title' => $title,
        'price' => $price,
        'default_img' => $default_img,
        'quantity' => $quantity);
  

И вот код, который отключает сеанс:

 if (isset($_POST['removeItem'])) {
    $prodId=$_SESSION['prodItemId'];
    foreach($_SESSION['product'] as $item) {
        if ($_GET["partid"] == $item['product_id']) {
            unset($_SESSION["product"]);    
        }
  

Проблема, с которой я сталкиваюсь, заключается в том, что вместо того, чтобы просто отключить один экземпляр сеанса, он отключает весь сеанс. Я пытался unset($_SESSION["product"][$item]);

Ответ №1:

Вы указываете коду отменить настройку всего сеанса, что он и делает.

Включите ключ в foreach и отмените установку конкретного ключа, который вам нужно отменить.

 foreach($_SESSION['product'] as $key => $item) {
        if ($_GET["partid"] == $item['product_id']) {
            unset($_SESSION["product"][$key]);    
        }
}
  


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

 if (isset($_POST['removeItem'])) {
    $prodId=$_SESSION['prodItemId'];
    $key = array_search($_GET["partid"], array_column($_SESSION['product'], 'product_id'));
    if($key !== false) unset($_SESSION["product"][$key]);
}
  

Array_search выполняет поиск GET partid и, если он найден, возвращает ключ о том, где он находится, в противном случае он возвращает false.


Если у вас есть несколько элементов массива, которые необходимо удалить, приведенный выше метод array_search удалит только первый.
Однако вы можете выполнить цикл array_search, чтобы получить их все.

 if (isset($_POST['removeItem'])) {
    $prodId=$_SESSION['prodItemId'];
    $prodID = array_column($_SESSION['product'], 'product_id'); // creates a flat array that can be searched
    while($key = array_search($_GET["partid"], $prodID)){
        unset($_SESSION["product"][$key]);
    }
}
  

Здесь мы ищем, есть ли соответствующее значение, если есть, мы удаляем ключ, затем цикл while выполняет поиск снова.
Если новое совпадающее значение равно forum, оно удаляется, если нет, array_search вернет false и прервет цикл while.


Четвертый метод заключается в том, чтобы практически сохранить имеющийся у вас код таким, какой он есть, но зациклить массив по ссылке на amp; и отменить настройку элемента.

 foreach($_SESSION['product'] as amp;$item) { // notice the amp;
        if ($_GET["partid"] == $item['product_id']) {
            unset($item); //because we used amp;, we can now unset $item
        }
}
  


Пятый метод заключается в использовании array_diff и array_intersect.
Этот метод является самым медленным и не должен использоваться на больших массивах, его можно использовать с очень небольшой разницей на меньших массивах (менее 50-100 элементов).

 if (isset($_POST['removeItem'])) {
    $prodId=$_SESSION['prodItemId'];
    $_SESSION['product'] = array_intersect_key($_SESSION['product'], array_diff(array_column($_SESSION['product'], 'product_id'), $_GET["partid"]));
}
  

Для того, чтобы объяснить это, мне нужно объяснить это в порядке, обратном тому, что вы прочитали, поскольку оно вложенное.
Я начинаю с создания плоского массива с помощью array_column.
Этот массив содержит только productid.
Я использую array_diff для возврата только тех элементов, которые не соответствуют $_GET[«partid»].
Мы получаем плоский массив, содержащий только productid. Это может показаться бесполезным, и это так, но ключи полезны.
Ключи соответствуют тому, что находится в массиве сеанса.
Итак, если мы используем array_intersect_key и используем $_SESSION[‘product’] в качестве основного массива и ключи из array_diff, то результатом будут элементы в $ _SESSION[‘product’], которые не соответствуют $_GET[«partid»].

Это сложно в фоновом режиме, но это просто в лайнере.

Комментарии:

1. Все упомянутые вами методы работают хорошо, но как вы думаете, какой способ достижения этого является предпочтительным? самым простым, по-видимому, является четвертый метод….

2. Зависит от того, есть ли у вас несколько элементов, которые необходимо удалить, или нет. Но четвертый способ довольно прост. И хорошо бы начать использовать цикл по ссылке, когда вам это нужно.

3. Если у вас есть только один элемент, который необходимо удалить, вы можете добавить break; после отмены установки внутри foreach.