За последние 24 часа нас посетили 20436 программистов и 1094 робота. Сейчас ищут 410 программистов ...

заменить хранение в SESSION на COOKIE

Тема в разделе "Сделайте за меня", создана пользователем thctps, 11 окт 2016.

  1. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    привет.

    в общем есть плагин и модуль на joomla.
    выводит последние просмотренные товары. но хранит инфу о них в сессии и при закрытии браузера или при обновлении сессии скидывает инфу.
    если бы он хранил всё в кукисах, то пользователь (теоретически), мог бы увидеть что просматривал год назад.
    нужен хотя бы совет (стаковерфлоу - не справился).

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

    PHP:
    1. defined('_JEXEC') or die;
    2.  
    3. class plgJshoppingproductsJshopping_last_visit_product extends JPlugin {
    4.  
    5.     function onBeforeDisplayProductView($view) {
    6.         $session = JFactory::getSession();
    7.         $last_visited_products = $session->get('last_visited_products', array());
    8.         if (isset($last_visited_products[$view->product->product_id])) {
    9.             unset($last_visited_products[$view->product->product_id]);
    10.         }
    11.         $product = new stdClass();
    12.         $product->name = $view->product->name;
    13.         $product->orig_image = $view->product->image;
    14.         $product->image = $view->product->image;
    15.         $product->product_thumb_image = $view->product->product_thumb_image;
    16.         $product->product_id = $view->product->product_id;
    17.         $product->currency_id = $view->product->currency_id;
    18.         $product->tax_id = $view->product->product_tax_id;
    19.         $product->orig_product_price = $view->product->product_price;
    20.         $product->product_price = $view->product->product_price;
    21.         $product->product_old_price = $view->product->product_old_price;
    22.         $product->min_price = $view->product->min_price;
    23.         $product->different_prices = $view->product->different_prices;
    24.         $product->product_manufacturer_id = $view->product->product_manufacturer_id;
    25.         $product->vendor_id = $view->product->vendor_id;
    26.         $product->delivery_times_id = $view->product->delivery_times_id;
    27.         $product->label_id = $view->product->label_id;
    28.         $product->category_id = $view->category_id;
    29.         $last_visited_products[$product->product_id] = $product;
    30.         $session->set('last_visited_products', $last_visited_products);
    31.     }
    32.  
    33. }

    PHP:
    1. defined( '_JEXEC' ) or die;
    2.  
    3. if (!file_exists(JPATH_SITE.'/components/com_jshopping/jshopping.php')){
    4.     JError::raiseError(500,"Please install component \"joomshopping\"");
    5. }
    6.  
    7. require_once JPATH_SITE.'/components/com_jshopping/lib/factory.php';
    8. require_once JPATH_SITE.'/components/com_jshopping/lib/functions.php';  
    9. JSFactory::loadCssFiles();
    10. JSFactory::loadLanguageFile();
    11. $jshopConfig = JSFactory::getConfig();
    12. $session = JFactory::getSession();
    13.  
    14. $count = $params->get('count_products', 5);
    15. $show_image = $params->get('show_image',1);
    16. $show_name = $params->get('show_name',1);
    17. $show_price = $params->get('show_price',1);
    18. $show_manufacturer = $params->get('show_manufacturer',1);
    19. $show_module = $params->get('show_module',1);
    20.  
    21. $products = array();
    22. $last_visited_products = array_reverse($session->get('last_visited_products', array()));
    23. $curent_product_id = JFactory::getApplication()->input->getInt('product_id');
    24. foreach($last_visited_products as $product){
    25.     if ($product->product_id == $curent_product_id) {
    26.         continue;
    27.     }
    28.     $product->product_price = $product->orig_product_price;
    29.     $product->image = $product->orig_image;
    30.     if (count($products) < $count) {
    31.         $products[] = $product;
    32.     } else {
    33.         break;
    34.     }
    35. }
    36. if (!count($products)) {
    37.     return;
    38. }
    39. listProductUpdateData($products, 1);
    40.  
    41. if (isset($jshopConfig->noimage)) {
    42.     $noimage = $jshopConfig->noimage;
    43. } else {
    44.     $noimage = 'noimage.gif';
    45. }
    46.  
    47. require JModuleHelper::getLayoutPath($module->module, $params->get('layout', 'default'));

    з.ы. всю инфу в кукисы прятать не надо (было такое предложение), достаточно спрятать $product_id, а по нему достать всё остальное.
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Можно просто увеличить время жизни cookie которая отвечает за сессии и чтобы её файла на сервере по дольше не удалялись, ещё вариант перенести сессии из файлов в базу и тоже жизнь cookie с идентификатором сессии увеличить
     
  3. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    1. увеличить время жизни cookie которая отвечает за сессии и чтобы её файла на сервере по дольше не удалялись,
    какой будет нагрузка на сервер при 500-1000 просмотров/день?
    2. перенести сессии из файлов в базу
    это лучше или проще просто кукисов?
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Возможно с этим и утюг справится.

    это проще так как ты хочешь скрыть
    https://secure.php.net/manual/en/session.customhandler.php
    https://secure.php.net/manual/en/function.session-set-save-handler.php
    https://github.com/sprain/PHP-MySQL-Session-Handler
     
  5. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    значит я подставка для утюга.
    что на что поменять надо?
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Я про то что сервер даже слабый выдержит 500-1000 запросов в день.

    ага, но долго объяснять, я дал ссылки, по идее в них всё есть,
    логика такая, ты изменяешь поведение сессии, горя ей работать через твой класс,
    как это прописать и готовый код, всё по ссылкам, там есть example на github
     
  7. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    я думал ветка называется «сделайте за меня»?!
    почему
    - найти ссылку
    - прислать
    - научить пользоваться
    - рассказать где лежит пример
    - обсудить сервер
    проще, чем изменить код (когда это «так просто»)?..

    вопросов с этими ссылками больше чем ответов!
     
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    и будут годовалые сессии стадом лежать в папочке. Не профит
    Лучше авторизованному юзеру привязать инфу с бд что и почем а в куки хранить индификатор
     
  9. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    и заставлять всех регаться??
    эта тема для их удобства - типа, че я там смотрел только что? или - ого они запомнили что я смотрел прошлый раз!

    никто не будет для такого регаться - куки
     
  10. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    этот чем вариант не угодил или проигнорировали?
     
  11. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    ну так ещё не нашёл человек который сделает, я пока облегчил задачу и описал варианты с готовым кодом

    ну можно чистить, в базе легче это делать
     
  12. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    нет. просто не уверен что понял смысл усложнения.

    насколько у меня получилось разобраться там будет один сплошной список, один для всех. каждый своим визитом/просмотром будет его только продлевать. но это насколько получилось. весьма вероятно что суть и не уловил. а еще - смутило, что автор сам лично этим не пользуется, т.к. решение толи старо, толи
     
  13. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    мы переносим сессии в базу, которая лучше работает с диском и эффективнее нагружает его.
    смело можно увеличить жизнь сессии, в базе можно хранить миллионы записей и всё быстро будет работать.
    удалить записи из базу у которых нет
    можно будет 1 запросом и хоть каждый час.

    у тебя там вроде joomla, поищи компонент например для joomla session in mysql или настройку в самой joomla, при включении которой это делается из коробки
    --- Добавлено ---
    оно на mysqli которое поддерживается до сих пор, этого достаточно как минимум, определить как автор часто использует, можно спросить его
     
  14. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    опять вопрос, ответьте пожалуйста (!!!), всё это проще обычных кукисы? Или кукисы очень сложно тут реализовать?
    просто глядя на документацию по кукисам и сессиям, у них есть точки пересечения...
     
  15. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    сложнее, так как нужно будет писать код, а тут уже есть готовый, максимум один SQL запрос и поменять настройки сессии.

    Сессия хранится на сервере и к информации её есть доступ только у сервера, у пользователя в браузере только хранится cookie с идентификатором сессии и всё.
    Cookie хранятся у пользователя и всё содержимое ему доступно.

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

    Так что проще сессии перенести в базу(код уже готов в example.php), увеличить срок их жизни и написать SQL запрос который будет удалять пустые сессии например.
     
  16. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    кукисы это кукисы, сессии vs DB
     
  17. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    1000 записей в день и их надо хранить хотя бы 30 дней.
     
  18. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    @thctps 30.000 записей которые будут грубо говоря выбраться по id, то это совсем мало, чайник осилит.
     
  19. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    видимо ты очень требовательный заказчик )))

    хочется хранить в куке — храни. только имей в виду ограниченный размер куки. искусственно ограничивай длинну списка перед сохранением.
    расписывать бцквально по буквам не буду, оставлю радость творчества тебе.
    --- Добавлено ---
    @denis01если вопрос будет ставиться так, что список посещенных мест нужен не только пользователю, но и администрации, то конечно нужна база. а так, это лишняя зависимость, имхо. это персональные данные, которые нам нафиг не нужны.
     
  20. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    это надо в js перекинуть и хранить в хранилище
     
  21. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    Мужички, вопрос опять открыт.
    Его надо решать.

    Поменял немного код, получилось сохранить всё в базу, код ниже:
    PHP:
    1. class plgJshoppingproductsJshopping_last_visit_product extends JPlugin {
    2.  
    3.     function onBeforeDisplayProductView($view) {
    4.         $product_id = (int) $view->product->product_id;
    5.  
    6.         $session = JFactory::getSession();
    7.         $last_visited_products = $session->get('last_visited_products', array());
    8.         if (isset($last_visited_products[$view->product->product_id])) {
    9.             unset($last_visited_products[$view->product->product_id]);
    10.         }
    11.         $product = new stdClass();
    12.         $product->name = $view->product->name;
    13.         $product->product_thumb_image = $view->product->product_thumb_image;
    14.         $product->product_id = $view->product->product_id;
    15.         $product->orig_product_price = $view->product->product_price;
    16.         $product->product_price = $view->product->product_price;
    17.         $product->product_old_price = $view->product->product_old_price;
    18.         $product->label_id = $view->product->label_id;
    19.         $last_visited_products[$product->product_id] = $product;
    20.         $session->set('last_visited_products', $last_visited_products);
    21.  
    22.         $db = JFactory::getDbo();
    23.  
    24.         $query = "INSERT INTO `oewi4_jmb_jshopping_last_seen_products` (`product_id`, `time`, `data`)"
    25.             . " VALUES ($product_id, NOW(), " . $db->quote(json_encode($last_visited_products)) . ")"
    26.             . " ON DUPLICATE KEY UPDATE `time` = VALUES(`time`), `data` = VALUES(`data`)";
    27.  
    28.         $db->setQuery($query);
    29.         $db->execute();
    30.     }
    31.  
    32. }

    Теперь при каждом новом просмотре появляется новая запись с $product_id, как связать ее с определенным пользователем???
     
    #21 thctps, 29 ноя 2016
    Последнее редактирование: 29 ноя 2016
  22. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    Куки добавляешь пользователю идентификатор $product_id при добалвении новой записи в бд, а дальше при каждом вызове скрипта проверяешь по условию, если отсутствует или нету в БД строки, то добавляем новую запись и "то что в начале писал"
     
  23. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    ок!

    PHP:
    1. $patch = "/";
    2. if (JURI::base(true) != ""){
    3. $patch = JURI::base(true);
    4. }
    5. setcookie('last_visited_products', session_id(), time() + 3600*24*30, $patch);
    что дальше?
     
  24. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    а дальше "дальше" прочти o_O
     
  25. thctps

    thctps Новичок

    С нами с:
    11 окт 2016
    Сообщения:
    15
    Симпатии:
    0
    Хорошо сказано!

    код:

    PHP:
    1. class plgJshoppingproductsJshopping_last_visit_product extends Plugin {
    2.  
    3.     function onBeforeDisplayProductView($view) {
    4.         $session = JFactory::getSession();
    5.         $last_visited_products = $session->get('last_visited_products', array());
    6.         if (isset($last_visited_products[$view->product->product_id])) {
    7.             unset($last_visited_products[$view->product->product_id]);
    8.         }
    9.         $product = new stdClass();
    10.         $product->name = $view->product->name;
    11.         $product->product_thumb_image = $view->product->product_thumb_image;
    12.         $product->product_id = $view->product->product_id;
    13.         $product->product_price = $view->product->product_price;
    14.         $product->product_old_price = $view->product->product_old_price;
    15.         $product->label_id = $view->product->label_id;
    16.         $last_visited_products[$product->product_id] = $product;
    17.         $session->set('last_visited_products', $last_visited_products);
    18.  
    19.         $patch = "/";
    20.         if (JURI::base(true) != ""){
    21.             $patch = JURI::base(true);
    22.         }
    23.         setcookie('last_visited_products', session_id(), time() + 3600*24*30, $patch);
    24.  
    25.         $inputCookie  = JFactory::getApplication()->input->cookie;
    26.         $cookie_id = $inputCookie->get('last_visited_products', null);
    27.         $cookieExists = ($cookie_id === null);
    28.  
    29.         $db = JFactory::getDbo();
    30.  
    31.         $query = "INSERT INTO `oewi4_jmb_jshopping_last_seen_products` (`product_id`, `time`, `data`)"
    32.             . " VALUES (" . $db->escape($cookie_id) . ", NOW(), " . $db->quote(json_encode($last_visited_products)) . ")"
    33.             . " ON DUPLICATE KEY UPDATE `time` = VALUES(`time`), `data` = VALUES(`data`)";
    34.  
    35.         $db->setQuery($query);
    36.         $db->execute();
    37.     }
    38.  
    39. }

    результат:

    ОШИБКА: 1054
    Unknown column 'e9e066639d0d05e13cca3fcfdbf04a73' in 'field list' SQL=INSERT INTO `#__jmb_jshopping_last_seen_products` (`product_id`, `time`, `data`) VALUES (e9e066639d0d05e13cca3fcfdbf04a73, NOW(), '{\"310\":{\"name\":

    что дальше?