|
Вывод размера товара в корзине
Всем привет! В свободное от работы время изучаю PHP и тренируюсь в создании инет-магазина, и вот возник вопрос: добавляю в корзину ботинок Арт.10001 размер 20 из выпадающего списка, в корзине выводится этот ботинок с размером 20; затем добавляю в корзину этот же ботинок, но с размером 24 - а в корзине уже выводится этот последний ввод с размером 24, т.е размер 24 перезаписывает сверху размер 20. Вот как поменять код, какой применить принцип, чтобы в корзину добавлялся ботинок одного id, но с разными выбранными размерами? У размеров своя таблица в mysql, с id. Заранее благодарен.
Добавление товара в корзину: <form action="index.php" method="get"> <input type="hidden" name="view" value="add_to_cart"> <input type="hidden" name="id" value="<?=$product['id']?>"> <select name="size" > <?PHP $sql="SELECT * FROM sizes WHERE `sizes`.`id_boot`='$id' "; echo $sql.'<br>'; $a=mysql_query($sql); while ($b = mysql_fetch_array($a)) { echo "<option value='$b[2]' > $b[2] </option>"; } ?> </select> <input type="submit" value="Добавить в корзину"> </form> Это вывод в корзине: foreach ($_SESSION['cart'] as $id => $quantity): $product = get_product($id); $b['size'] = $_SESSION['cart_size'][$id]; if (!empty($_GET['size'])) {echo $_GET['size'];} ?> <tr> <td align="center"><?=$product['title']; ?></td> <td align="center"> <?=$b['size'];?> </td> <td align="center"> <?=number_format($product['price'],2); ?> руб</td> <td align="center"><input type="text" size="2" name="<?=$id; ?>" maxlength="2" value="<?=$quantity; ?>" /></td> <td align="center"> <?=number_format($product['price'] * $quantity ,2); ?> руб</td> </tr> И дальше коды связанные с добавлением в корзину: case('add_to_cart'): $id = $_GET['id']; $size = $_GET['size']; $_SESSION['cart_size'][$id] = $size; $add_item = add_to_cart($id, $size); $_SESSION['total_items'] = total_items($_SESSION['cart']); $_SESSION['total_price'] = total_price($_SESSION['cart']); header('Location:index.php?view=product&id='.$id); break; session_start(); if(!isset($_SESSION['cart'])) { $_SESSION['cart'] = array(); $_SESSION['total_items'] = 0; $_SESSION['total_price'] = '0.00'; } function add_to_cart($id) { if(isset($_SESSION['cart'][$id])) { $_SESSION['cart'][$id]++; return true; } else { $_SESSION['cart'][$id] = 1; return true; } return false; } |
Нужно менять представление корзины в сессии.
|
laimas, а не могли бы по подробнее??? А то так мне не понятно совсем...
|
Почитайте тут. Не обязательно Ajax, можно и без него. Там описана корзина, ее возможная структура и почему такая выбрана.
|
laimas, что то подобное я уже встречал, но как это применить к моей корзине - так и не понял.
|
Меняйте "свою" корзину, ее представление неудачное, почему, это по ссылке можно понять. Как вложить в вас "понимание", этого я не знаю. )
|
Цитата:
|
Я же только учусь, и очень тяжело "расшифровать" ваш код и понять
А вы хотите чтобы я писал код так же как вы? :) Ну понятно, что так: $_SESSION['total_items'] = total_items($_SESSION['cart']); $_SESSION['total_price'] = total_price($_SESSION['cart']); я делать не стану, и вот почему. Для программирования необходимо наличие логического мышления, но и не менее полезно уметь абстрагироваться от конкретных конструкций языка программирования. Можно даже сказать так - умение видеть задачу от общего к частному, это первично, а умение воплотить ее в конструкциях языка программирования, это уже вторично. Можно вызубрить наизусть все функции и конструкции языка, но так и не уметь написать что либо стоящее. А вот хорошее представление задачи как раз и позволяет выбрать необходимые инструменты в языке программирования для ее решения. С какой целью у вас количество товаров в корзине и общая их сумма присваивается двум отдельным переменным - $_SESSION['total_items'] и $_SESSION['total_price']? Это только кажется, что так будет удобно и выгодно, а на самом деле это избыток данных не несущих каких либо преимуществ. Представьте, что вы работаете в почтовом отделении и выполняете простую работу - нужно лизнуть марку и наклеить ее на конверт. Конверты с марками складывать отдельно. Изначально было выдано 1000 марок и 1000 конвертов. В конце рабочего дня нужно определить сколько осталось марок и конвертов осталось и запомнить. Не сложно, пересчитав конверты с марками, вычитаем это из 1000, получая нужное. Если код вашей корзину переложить на работу в почтовом отделении, то получается, что вы работали так - марки лежали в одном столе, конверты в другом, а конверты с наклеенными марками вообще относились в другую комнату. При этом нужно было взять марку в одном столе, лизнуть ее, пойти к другому столу, взять конверт, наклеить марку и бежать в другую комнату. Покупая в магазине товар, вы в уме будет считать общую их сумму, чтобы ориентироваться хватит ли у вас денег в кошельке (скоро считать в уме не надо будет, упаковки снабдят RFID-метками, и дисплей на тележке будет отображать просчитанную автоматически сумму). Всегда можно заглянуть в тележку, что-то убрать из нее, вернув на прилавок, что-то другое добавить, в общем "редактирование". Кассир на кассе также будет проверять товары в тележке, и только после того как товар оплачен, тележка будет пуста. На все время пока совершалась покупка - от выбора товара на прилавке, до оплаты товаров на кассе, всегда требовалась тележка, то есть, перекладывая это на язык на программирование можно сказать, что на всем этапе использовали один и тот же объект - корзину. На основе содержимого тележки можно всегда знать и характеристики товара, и их количество, и их цену, и общую сумму. А если представить, что вам "помогают" в покупке сестра и брат - сестра считает и записывает сумму за товары, но находится в отделе косметики, а брат катает тележку, но хочет приобрести перфоратор как месть перфоратору соседа и находится в отделе электрических товаров, а вы бегаете из продуктового отдела с товарами к ним, чтобы положить товар в тележку и узнать сколько же набрано. Понятное дело, что это помощь в кавычках, и сестра с братом лишние звенья. Ваш код как раз и есть покупка с "помощью" сестры и брата. ) Как и в реальном магазине, так и в виртуальном, корзина требуется на всем этапе приобретения товара - от выбора его, до оформления заказа. Корзина должна быть единственным объектом хранящем все данные о товарах, и на основе которых можно получать те или иные параметры корзины. Разбрасывать эти параметры по другим переменным, это распылять внимание и писать лишний код. По ссылке описано представление корзины, которое в вашем случае можно описать так: $_SESSION['cart'] = array( 209 => array( 'count' => 3, 'price' => 1500, array('size'=>array(42 => 2, 41 => 1), 'name' => 'Галоши') ), 150 => array( 'count' => 2, 'price' => 1000, array('size'=>array(40 => 1, 41 => 1), 'name' => 'Туфли') ) ); где 209 и 150, это уникальные идентификаторы товаров, первичный ключ в sql-таблице. Именно он, а не Арт.1001 или иной. Артикулы, это информация для продавцов и, если надо, то и покупателю. Ключ count - хранит количество набранного товара, price - его цену за 1 шт., а в массиве хранится детализация о выборе - название товара и размер как ключ, значением которого будет количество набранного для его покупки. Если Галош выбрали 2 шт. 42-го размера и 1 шт. 41-го, то count равен 3. Добавляя товар в корзину, нужно помещать его в корзину под его идентификатором, как ключом массива, а в массив детализации помещать размер как ключ, а выбранное количество размера как значение (нельзя запрещать покупать 42 размер в количестве более штуки). Если 42 размер уже был помещен в корзину в количестве 1 шт., а покупатель изменит количество на 2 или иное, то ключ 42 будет переписан с новым значением. Если покупатель выберет 0, или "удаление" 42-го размера, значит 0 он и есть 0, или удаляем. При всех таких изменениях суммируется значение ключа count. Узнать же всего товаров в корзине и сумму за них позволяют стандартные функции PHP - current, array_product, array_sum, array_map в функции totalBasket(), которая описана по ссылке на корзину. А для полного представления корзины уже нужно будет обходить корзину циклом выводя ее подробное описание в удобном для представления виде. |
laimas, сразу возникают вопросы. Например, до этого я вытаскивал данные о товаре в цикле из БД, а теперь, если применить этот код
$products = [23 => ['price'=>120, 'name'=>'Товар 1'], 245 => ['price'=>230, 'name'=>'Товар 2'], 39 => ['price'=>150, 'name'=>'Товар 3'], 109 => ['price'=>380, 'name'=>'Товар 4']];, то получается мне нужно так заполнить переменную $products на 1000 строчек, да ещё каждый раз в ручную редактировать изменения в товаре...... То же самое касается и этого кода: $_SESSION['cart'] = array( 209 => array( 'count' => 3, 'price' => 1500, array('size'=>array(42 => 2, 41 => 1), 'name' => 'Галоши') ), 150 => array( 'count' => 2, 'price' => 1000, array('size'=>array(40 => 1, 41 => 1), 'name' => 'Туфли') ) ); Я уже встречал примерно такое построение, но как это применить на практике - примеров не встретил... |
Вытаскивать данные из базы в цикле, это очень и очень плохо, и означает насиловать базу. Об этом методе нужно забыть сразу.
Я забыл добавить ключ массиву характеристик в корзине товаров, сделаем это, и пусть на текущий момент корзина, и имеет указанные товары: $_SESSION['cart'] = array( 209 => array( 'count' => 3, 'price' => 1500, 'prop' => array('size'=>array(42 => 2, 41 => 1), 'name' => 'Галоши') ), 150 => array( 'count' => 2, 'price' => 1000, 'prop' => array('size'=>array(40 => 1, 41 => 1), 'name' => 'Туфли') ) ); Если на страницах покупатель может выбрать количество товара, а также указывать его характеристики, в данном случае размер, то на сервер нужно отправлять массив описывающий такой выбор, в котором под первичным ключом хранится размер/размеры и набранное их количество. Допустим сервер получит заказ на новые товары, а также изменение количества товара ID209 для 41-го размера, и добавления 43-го размера с количеством 1 шт., и передается как $_POST['order']. Первоочередной задачей будет определить не туфту ли прислали в первичных ключах, обезопасить их для подстановки в запрос, а также определение тех товаров, которых еще нет в корзине, чтобы обратиться к базе для получения их наименования и цены, и уже потом добавить их в базу. А также вычленить товар, который уже есть в корзине, чтобы обновить его параметры. Вы читали о функция, ссылки на которые я дал? Даю еще на на семь, которые потребуются для решения выше указанных задач. Более ссылок я давать не буду, скачивайте руководство РНР, оно есть на русском, в удобном CHM формате, с примерами к функциям. Изучайте, уясняйте, тем более, что тип данных array, это тип с которым придется сталкиваться постоянно. А ковыряться в этом типе исключительно как for, foreach и т.п., это плодить многоэтажный код, в котором легко и заблудиться. И так, нам потребуется встроенные РНР функции - intval, implode, array_diff, array_diff_key, array_intersect_key, array_keys, array_flip. Обрабатываем полученный массив выбрасывая из него "пустышки" если такие есть, и если после этого вернется не пустой массив $order, то выполняем операции с корзиной: if($order = array_intersect_key($_POST['order'], array_flip(array_diff(array_map('intval', array_keys($_POST['order'])), array(0))))) { //работаем с корзиной } Допустим в результате получим такой массив: Array ( [209] => Array ( [42] => 3 [43] => 1 ) [186] => Array ( [37] => 1 ) [254] => Array ( [40] => 2 ) ) В нем два новых товара ID186 и ID254. Нужно из массива $order получить эти идентификаторы и получить информацию о них из базы, но не двумя запросами в цикле, а одним запросом используя sql-оператор IN(). Если в таблице поле идентификаторов имеет имя id, то запрос будет типа такого: $basket = &$_SESSION['cart']; //что такое ссылки, читать в руководстве $sql = 'SELECT id, name, price FROM table_name WHERE id IN('.implode(',', array_keys(array_diff_key($order, $basket))).')'; В итоге будет сделан всего один запрос к базе и возвращены данные о товарах ID186 и ID254. После этого их можно добавлять в корзину. Товары параметры которых в корзине нужно обновить получаются так: $upd = array_intersect_key($basket, $order); А теперь попробуйте сами, зная (желательно бы знать) о функции array_sum(), решить задачу обновления и добавления в массиве корзины. Нужно учиться на более простых примерах, а не хвататься сразу за написание магазинов. Я не стану укорять за написание магазина вами так - а работает и ладно, а на чем не важно. Но я и не стану вам помогать писать код в том ключе, как это вы делаете, мне это просто не интересно. И объяснять все детали подробно почему это у меня так, а не как у вас, я не буду. На данный момент я не располагаю временем, я и так написал более, чем следовало бы. |
Часовой пояс GMT +3, время: 11:02. |
|