Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.05.2015, 07:52
Аспирант
Отправить личное сообщение для arhat78 Посмотреть профиль Найти все сообщения от arhat78
 
Регистрация: 06.04.2015
Сообщений: 52

Вывод размера товара в корзине
Всем привет! В свободное от работы время изучаю 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;
}

Последний раз редактировалось arhat78, 15.05.2015 в 14:03.
Ответить с цитированием
  #2 (permalink)  
Старый 15.05.2015, 09:14
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Нужно менять представление корзины в сессии.
Ответить с цитированием
  #3 (permalink)  
Старый 15.05.2015, 09:18
Аспирант
Отправить личное сообщение для arhat78 Посмотреть профиль Найти все сообщения от arhat78
 
Регистрация: 06.04.2015
Сообщений: 52

laimas, а не могли бы по подробнее??? А то так мне не понятно совсем...
Ответить с цитированием
  #4 (permalink)  
Старый 15.05.2015, 09:30
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Почитайте тут. Не обязательно Ajax, можно и без него. Там описана корзина, ее возможная структура и почему такая выбрана.
Ответить с цитированием
  #5 (permalink)  
Старый 15.05.2015, 13:54
Аспирант
Отправить личное сообщение для arhat78 Посмотреть профиль Найти все сообщения от arhat78
 
Регистрация: 06.04.2015
Сообщений: 52

laimas, что то подобное я уже встречал, но как это применить к моей корзине - так и не понял.
Ответить с цитированием
  #6 (permalink)  
Старый 15.05.2015, 14:16
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Меняйте "свою" корзину, ее представление неудачное, почему, это по ссылке можно понять. Как вложить в вас "понимание", этого я не знаю. )
Ответить с цитированием
  #7 (permalink)  
Старый 15.05.2015, 23:35
Аспирант
Отправить личное сообщение для arhat78 Посмотреть профиль Найти все сообщения от arhat78
 
Регистрация: 06.04.2015
Сообщений: 52

Сообщение от laimas Посмотреть сообщение
Меняйте "свою" корзину, ее представление неудачное, почему, это по ссылке можно понять. Как вложить в вас "понимание", этого я не знаю. )
Но нужно же понять, что именно не правильно, и как грамотно нужно поменять этот код. Я же только учусь, и очень тяжело "расшифровать" ваш код и понять, как его применить в моём случае.... Надеюсь, подскажете в каком направлении и как двигаться
Ответить с цитированием
  #8 (permalink)  
Старый 16.05.2015, 06:54
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Я же только учусь, и очень тяжело "расшифровать" ваш код и понять

А вы хотите чтобы я писал код так же как вы? Ну понятно, что так:

$_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, 16.05.2015 в 07:27.
Ответить с цитированием
  #9 (permalink)  
Старый 16.05.2015, 10:17
Аспирант
Отправить личное сообщение для arhat78 Посмотреть профиль Найти все сообщения от arhat78
 
Регистрация: 06.04.2015
Сообщений: 52

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' => 'Туфли')
	   )
	);


Я уже встречал примерно такое построение, но как это применить на практике - примеров не встретил...
Ответить с цитированием
  #10 (permalink)  
Старый 16.05.2015, 15:12
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

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

Я забыл добавить ключ массиву характеристик в корзине товаров, сделаем это, и пусть на текущий момент корзина, и имеет указанные товары:
$_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(), решить задачу обновления и добавления в массиве корзины.

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

Последний раз редактировалось laimas, 16.05.2015 в 15:19.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как проверить, что есть поле селект у товара borus Общие вопросы Javascript 12 23.04.2014 22:14
Вывод выбранных данных и проверка checkbox MasterHrust Javascript под браузер 3 28.09.2011 17:44
вывод jquery cookie как вывести данные из куки klubnichkaaa AJAX и COMET 2 12.08.2011 13:45
Вывод переменных MasterHrust Javascript под браузер 4 03.08.2011 15:41
Вывод данных в Друпал 6 из MySQL, небольшая работа torquemada Работа 1 22.05.2011 17:05