Почему AjaxForm использует сессии?

Всем привет, давно не виделись!

Переодически почитываю новости на сайте и вот увидел ветку комментариев про хранение данных в сессии.

Казалось бы, совершенно заслуженный камень в мой огород, как автора дополнения. Зачем использовать сессии для ajax сниппетов, ведь сама по себе эта технология сессий не требует? Так-то оно так, но в мире MODX всё несколько сложнее.

Итак, у нас есть 2 основных варианта запустить какой-то сниппет через Ajax.

Вариант 1: отправить запрос на страницу с ним. Вполне рабочий, да, но не очень быстрый, потому что MODX выполнит все плагины и сниппеты, которые найдёт перед вашим сниппетом.

А если вы используете Fenom, то эти сниппеты еще и сразу выведут ответ через echo, потому что он не буферизирует результаты в переменную, а выводит сразу — что сломает ответ от вашего сниппета.

Не подходит.

Вариант 2 — отправлять запрос на отдельный PHP коннектор, который запустит нужный сниппет в облегчённом MODX_API режиме и получит от него ответ без дополнительных затрат.

Отличный, быстрый вариант. Но нам нужно запустить этот сниппет с какими-то параметрами, верно? А где их взять?
Доверить юзеру самому отправлять параметры для работы сниппета нельзя, иначе он вам через pdoResources вытащит все возможные данные из БД, а может еще и запишет чего через другой сниппет. Где хранить данные для запуска сниппета через коннектор?

Тут тоже 2 варианта: какой-то отдельный временный файл с настройками или сессия. При этом отдельный файл с настройками должен обновляться при изменении параметров вызова сниппета на странице, и не должен зависеть от id или группы юзера (иначе файлов будет несколько и особой разницы с сессией не получится) — это всё выглядит довольно сложно для реализации.

А вот сессии вполне рабочий вариант. Да, возможно не самый лучший, но другого я не придумал. По факту, из реально рабочих и универсальных вариантов, это единственный. Все же любят установить дополнение, и чтобы оно сразу работало без танцев с бубном, верно?

Поэтому — сессии.

Вот такая небольшая юбилейная (трёхсотая!!!) заметка с объяснениями, почему AjaxForm, mSearch2, minShop2 и другие мои сниппеты хранят свои параметры в сессиях, а не где-то ещё.

Если у кого есть идеи для более удобного вызова сниппетов через ajax с хранением их параметров не в сессии — буду рад прочитать.
Василий Наумкин
04 августа 2021, 10:03
modx.pro
1
2 643
+20

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

Иван Бочкарев
04 августа 2021, 10:07
+6
Приятно видеть тебя. Пиши еще :)
    Павел Гвоздь
    04 августа 2021, 10:14
    0
    modRegistry не подойдёт? Свои особенности, но всё же. Я в своё время тоже написал костыль, но думаю, что на перечисленных дополнениях он будет не уместен.
      Василий Наумкин
      04 августа 2021, 10:18
      0
      Тот же вариант, что и настройки в файлах, только в БД.

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

      Да и взять и разом почистить modRegistry из админки нельзя.
        Andrey Grachov
        07 августа 2021, 18:37
        0
        Можно сохранять настройки вызова AjaxForm в таблицу такой структуры
        CREATE TABLE `modx_ajax_form_properties` (
          `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
          `hash` varchar(32) NOT NULL,
          `properties` json NOT NULL,
          PRIMARY KEY (`id`),
          UNIQUE KEY `hash` (`hash`)
        )
        В коде AjaxForm меняем логику генерации хеша:
        ksort($scriptProperties);
        $hash = md5(http_build_query($scriptProperties));
        и потом добавляем новую запись в базу если такого хеша еще нет. При обработке запроса AjaxForm берем данные по хешу из базы а не из сессии.
          Максим
          18 августа 2021, 20:32
          0
          Сессии modx хранит в базе… поэтому тут всё равно будет БД и куча записей (как я понимаю).
            Сергей Шлоков
            18 августа 2021, 20:49
            0
            Может так случится, что в параметрах будет уникальное значение для каждого юзера. А значит таблица будет разрастаться как в случае с сессиями, только механизма удаления и чистки этой таблицы нет. Но как алтернативный вариант сойдёт, если уникальных данных нет.
              Andrey Grachov
              26 августа 2021, 12:29
              0
              В случае с уникальными данными (что бывает не очень часто) будет добавляться по одной записи в этой таблице, в то время как в варианте с сессиями набор свойств будет дублироваться в сессии каждого пользователя который зашел на страницу. То есть вариант с сессиями увеличивает размер базы быстрее, но, конечно, как вы правильно упомянули, там есть механизмы очистки.
          Сергей Шлоков
          04 августа 2021, 10:41
          +3
          увидел ветку комментариев про хранение данных в сессии. Казалось бы, совершенно заслуженный камень в мой огород, как автора дополнения.
          А вот спроси этого человека как сделать без сессий проще, лучше и чтоб работало из коробки у всех, ответит что-нибудь в духе «не моё дело, я с MODX не работаю». Главное сказать, что сессии — зло. Почему и чем так они страшны? Думаю, объективного ответа не дождёмся.

          Сессии — это просто инструмент. Всё зависит от того, как им пользоваться. Вот из коробки в сессии пишутся группы ресурсов и группы пользователей. В итоге возникает проблема консистентности данных после изменения этих настроек. Это плохое использование сессий. А в ajaxForm использование сессий вполне обосновано.
          И это глобально никак не влияет на разрастание таблицы сессий.

          По большей части проблема или в неправильной настройке сборщика мусора (не зависит от MODX) или в ботах (о чём писал Алексей в своей статье), ибо каждый запрос бота вызывает создание новой записи в таблице. С гостями особой проблемы нет — запись создаётся только один раз и будет использоваться в течение 7 дней, потом будет удалена и создана другая (разговор про один браузер и стандартные настройки). Пример как игнорировать ботов и не создавать для них сессии есть у меня на сайте.
            Иван
            04 августа 2021, 18:44
            0
            В сессиях обычно хранится уникальная информация пользователя. А форма чаще всего используется не персонально для пользователя, а для групп пользователей (боты входят в анонимную группу). Можно было просто создавать записи в БД для группы пользователей, использование сессии здесь не нужно. Можно так же получать массив параметров сниппетов, но для сохранения написать свою одну функцию (+ свой коннектор). Это просто как вариант. Возможно, есть и другие. Я не критикую, а просто высказываю мнение. Никого не хотел обидеть) Возможно, если бы я писал такое дополнение, то тоже выбрал бы лёгкий путь, всё наперёд просчитать сложно, это я понимаю.
              Иван
              04 августа 2021, 19:01
              0
              Кстати, использование механизма кэширования (в файлах) это тоже хорошее решение. Ключ к кэшу может создать сам пользователь (разработчик конкретного сайта), а по умолчанию использовать группу пользователя.
                Сергей Шлоков
                04 августа 2021, 21:12
                +1
                В сессиях обычно хранится уникальная информация пользователя.
                Вот у меня только один вопрос — у Вас большой опыт программирования? Вы можете гарантировать, что в форме не будет уникальной информации, как написал Василий? Ой, это второй вопрос.

                Т.е. если для 98% пользователей решение отлично подходит, но для 2-х% нет, то его нужно выбросить в пропасть. Ибо это оскорбляет эти 2%. Это не они должны адаптировать решение, а остальные 98%.

                Можно было просто создавать записи в БД для группы пользователей, использование сессии здесь не нужно.
                А ещё можно в догонку спросить? Сколько дополнений Вы создали?

                П.С. Я спрашиваю абсолютно по-дружески. )
              Anton
              04 августа 2021, 13:17
              0
              Василий, рад видеть!

              Вопрос по AjaxForm. В описании сказано, используются jQuery.Form и jQuery.jGrowl.
              То есть, ему нужен jQuery. Можно ли обойтись без него?
                Наумов Алексей
                04 августа 2021, 13:49
                1
                +6
                Даже я отвечу: конечно можно, переписываете вот этот файл без сторонних библиотек и все будет работать
                github.com/bezumkin/AjaxForm/blob/master/assets/components/ajaxform/js/default.js
                  Василий Наумкин
                  06 августа 2021, 15:32
                  +2
                  В описании сказано, используются jQuery.Form и jQuery.jGrowl.
                  То есть, ему нужен jQuery.
                  Можно ли обойтись без него?
                  Я даже не буду ничего отвечать, и процитирую самого автора:
                  Самый клоунский комментарий, который вызывает улыбку :)))
                  Scorp Satex
                  04 августа 2021, 14:37
                  0
                  Здравствуйте Василий.

                  Извините, что вопрос не по теме.

                  Github pdoTools github.com/bezumkin/pdoTools — архивирован вами, кто теперь будет им заниматься и будут ли? Или вы кому-то его передали уже?

                  Спасибо.
                    Василий Наумкин
                    04 августа 2021, 17:51
                    0
                    Ничего передавать не нужно, это Open Source — любой человек может сделать форк и выпускать свои версии с любыми исправлениями.

                    Архивация репозитория означает, что лично я им заниматься не буду, только и всего.
                      Scorp Satex
                      04 августа 2021, 18:01
                      0
                      А кто тогда выпускает новые версии и выкладывает их на modstore?

                      В modstore.pro/packages/utilities/pdotools ссылка на github ведет на вас, у вас последний релиз версии 2.12.3

                      А на modstore последняя версия pdoTools — 2.12.10

                      Можно ли тогда обновить ссылку в описании pdoTools на актуальный github?
                        Василий Наумкин
                        04 августа 2021, 18:05
                        0
                        Наверное, я просто не так часто пользовался вкладкой releases.

                        В репозитории та же версия, что и на modstore.
                          Scorp Satex
                          04 августа 2021, 18:13
                          0
                          Ясно, спасибо за объяснение.
                    Иван
                    04 августа 2021, 18:28
                    0
                    Казалось бы, совершенно заслуженный камень в мой огород
                    Василий, я ни в коем случае не хотел кидать в ваш огород камень. Просто указал, что проблема существует и её нужно решать, а не делать костыли. Вы выбрали самый просто способ, но есть и другие. Как минимум можно не сохранять параметры в сессии для ботов, думаю можно найти библиотеку для фильтрации по юзер агенту и т.п. (или написать самому). Не хотел Вас задеть). Уважаю за проделанную работу и полезные дополнения.
                      Aleksandr Huz
                      04 августа 2021, 23:16
                      0
                      Привет, Василий!

                      Где хранить данные для запуска сниппета через коннектор?
                      А если хранить данные в отдельной таблице? А через ajax передать только id нужной нам формы. И сниппет уже не нужен будет.
                        Василий Наумкин
                        05 августа 2021, 04:18
                        +1
                        Да, если брать за уникальный id хэш от параметров сниппета и получать его потом из запроса юзера — рабочий вариант. Даже, пожалуй, хороший.

                        Но тут сразу второй вопорос — каждое дополнение будет устанавливать собственную такую таблицу? Или они все должны использовать какую-то общую? Если общую — как дополнениям об этом договориться, требовать какую-то зависимость, типа нового дополнения AjaxSettingsDB?

                        И если у вызова сниппета будет какой-то уникальный параметр, типа id юзера, то количество записей в такой БД будет ровно тем же, что и у таблицы сессий. Еще встаёт вопрос еще об очистке этой таблицы — сколько дней хранить в ней настройки?

                        Но, повторюсь, этот вариант мне нравится и в былые времена я мог бы переписать свои дополнения на хранение настроек в одной общей таблице. Кто сейчас это будет делать — вопрос.
                          Сергей Шлоков
                          05 августа 2021, 06:50
                          +2
                          И придётся придумывать всё то, что уже есть в сессии. Вообще, в чём проблема-то? В сессии эти данные занимают байты. Ну пусть для всех пользователей это будет килобайты. Ну если уж у тебя большой сайт, то десятки МБ. И то при условии, что все ломятся на страницу с формой. А у большинства это какая-нибудь страница с обратной связью.

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

                          Ну а отдельная таблица — это явный оверхед. Тогда уж лучше передавать в форму зашифрованные данные из параметров сниппета в скрытый инпут. В этом случае оверхеда будет гораздо меньше.
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          23