Как искать в многомерных массивах множество совпадающих пар ключ-значение

#php #arrays #e-commerce #cart

#php #массивы #электронная коммерция #Корзина

Вопрос:

В настоящее время я создаю пользовательскую корзину покупок на PHP.

У каждого товара, который можно добавить в корзину, есть 2 переменные: pid для идентификатора товара в базе данных и did для уникального идентификатора дизайна. Все мои продукты сделаны на заказ, поэтому это 2 основные переменные, которые мне требуются.

Когда пользователь добавляет товар в пустую корзину, выполняется $_SESSION с многомерным массивом, называемым cart_array. Когда добавляется один и тот же элемент, я могу выполнить поиск в cart_array для совпадающей пары ключ-значение и увеличить количество, а не добавлять новый массив. Однако я могу сопоставить только 1 пару значений. Мне нужно найти массив, в котором есть одна пара ключ-значение (pid = опубликованный pid), а затем посмотреть, есть ли в том же массиве другая совпадающая пара ключ-значение (did = опубликованный did).

 <?php 
if (isset($_POST['pid'])) {
$pid = $_POST['pid'];
$did = $_POST['did'];
$wasFound = false;
$i = 0;

// If the cart session variable is not set or cart array is empty
if (!isset($_SESSION["cart_array"]) || count($_SESSION["cart_array"]) < 1) { 
// RUN IF THE CART IS EMPTY OR NOT SET
    $_SESSION["cart_array"] = array(1 => array("item_id" => $pid, "did" => $did, "quantity" => 1));
} else {

// RUN IF THE CART HAS AT LEAST ONE ITEM IN IT
    foreach ($_SESSION["cart_array"] as $each_item) { 
$i  ;
if (array_key_exists("pid", $each_item) amp;amp; $pid == $each_item["pid"]) {
        // That item is in cart already so let's adjust its quantity using array_splice()
        array_splice($_SESSION["cart_array"], $i-1, 1, array(array("did" => $did, "item_id" => $pid, "quantity" => $each_item['quantity']   1)));
        $wasFound = true;
} // close if condition
} // close foreach loop

if ($wasFound == false) {
array_push($_SESSION["cart_array"], array("item_id" => $pid, "did" => $did, "quantity" => 1));
}
}
header("location: cart.php");
exit();
}
?>
  

Надеюсь, я ясно выразился. Я знаю, что код для настройки, вероятно,;

 if (array_key_exists("pid", $each_item) amp;amp; $pid == $each_item["pid"]) {
  

Мне нужно добавить что-нибудь, чтобы убедиться, что массивы, найденные с соответствующим $ pid, также имеют соответствующий $ did

Ответ №1:

Используйте Quadtree.

По сути, это похоже на двоичное дерево, реализованное дважды

Для каждого нового элемента вы должны спросить, является ли его product_id большим или меньшим, чем предыдущий элемент, и является ли его design_id большим или меньшим, чем предыдущий элемент, а затем соответствующим образом разместить новый элемент.

Относительно легко хранить и очень легко найти.

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

1. Спасибо, что дали мне что-то новое для исследования. Это может быть возможно, но я разработчик-самоучка, и мне придется изучить это. Спасибо

Ответ №2:

Здесь есть пара проблем. Я думаю, что первый элемент в сеансе должен начинаться с индекса 0, а не 1. Итак, поменяйте местами это:

 $_SESSION["cart_array"] = array(1 => array("item_id" => $pid, "did" => $did, "quantity" => 1));
  

к следующему. Я тоже немного переработал это, предлагаю вам сделать то же самое — это значительно повышает читаемость:

 $_SESSION["cart_array"] = array(
    array("item_id" => $pid, "did" => $did, "quantity" => 1, )
);
  

Кроме того, если вам нужно выполнить приращение, это означает, что элемент массива уже существует, поэтому вам не нужно делать array_splice , насколько я могу судить. Просто найдите это в своей сессии таким образом:

 foreach ($_SESSION["cart_array"] as $index => $each_item) { 
    if (array_key_exists("pid", $each_item) amp;amp; $pid == $each_item["pid"]) {
        // That item is in cart already so let's increment its quantity
        $_SESSION["cart_array"][$index]['quantity']  ;
        $wasFound = true;
    }
}
  

Как вы можете видеть, это также устраняет необходимость в $i .

(Помимо: вы принимаете пользовательский ввод для pid и did и добавляете их в свою структуру данных, не повреждая их. Впоследствии это может привести к проблемам безопасности. Если они являются целыми числами, приведите их к (int) для безопасности).

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

1. Спасибо, что нашли время ответить на мои вопросы наполовину, ваши комментарии помогли. Я подумал, что на это будет легче ответить, и подумал, что, возможно, будет предложено другое условие «если» или «пока». Я собираюсь просто создать новую переменную, добавив вместе $ did и $ pid, поэтому мне нужно проверить только 1 пару ключ-значение в массиве.

2. Не беспокойся, @Lil, рад, что помог.

Ответ №3:

Новая переменная:

 $doubleCheck = "$pip,$did";
  

Создана новая корзина:

 $_SESSION["cart_array"] = array(1 => array("item_id" => $pid, "did" => $did, "doubleCheck" => $doubleCheck, "quantity" => 1));
  

Добавлен повторяющийся элемент:

 if (array_key_exists("doubleCheck", $each_item) amp;amp; $doubleCheck = $each_item["doubleCheck"]) {
  

Добавлен новый элемент:

 array_splice($_SESSION["cart_array"], $i-1, 1, array(array("did" => $did, "item_id" => $pid, "doubleCheck" => $doubleCheck, "quantity" => $each_item['quantity']   1)));
  

Кажется, работает именно так, как мне нужно. Очистка переменных происходит немного позже в коде.