#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.