Почему AjaxForm использует сессии?
Всем привет, давно не виделись!
Переодически почитываю новости на сайте и вот увидел ветку комментариев про хранение данных в сессии.
Казалось бы, совершенно заслуженный камень в мой огород, как автора дополнения. Зачем использовать сессии для ajax сниппетов, ведь сама по себе эта технология сессий не требует? Так-то оно так, но в мире MODX всё несколько сложнее.
Итак, у нас есть 2 основных варианта запустить какой-то сниппет через Ajax.
Вариант 1: отправить запрос на страницу с ним. Вполне рабочий, да, но не очень быстрый, потому что MODX выполнит все плагины и сниппеты, которые найдёт перед вашим сниппетом.
А если вы используете Fenom, то эти сниппеты еще и сразу выведут ответ через echo, потому что он не буферизирует результаты в переменную, а выводит сразу — что сломает ответ от вашего сниппета.
Не подходит.
Вариант 2 — отправлять запрос на отдельный PHP коннектор, который запустит нужный сниппет в облегчённом MODX_API режиме и получит от него ответ без дополнительных затрат.
Отличный, быстрый вариант. Но нам нужно запустить этот сниппет с какими-то параметрами, верно? А где их взять?
Доверить юзеру самому отправлять параметры для работы сниппета нельзя, иначе он вам через pdoResources вытащит все возможные данные из БД, а может еще и запишет чего через другой сниппет. Где хранить данные для запуска сниппета через коннектор?
Тут тоже 2 варианта: какой-то отдельный временный файл с настройками или сессия. При этом отдельный файл с настройками должен обновляться при изменении параметров вызова сниппета на странице, и не должен зависеть от id или группы юзера (иначе файлов будет несколько и особой разницы с сессией не получится) — это всё выглядит довольно сложно для реализации.
А вот сессии вполне рабочий вариант. Да, возможно не самый лучший, но другого я не придумал. По факту, из реально рабочих и универсальных вариантов, это единственный. Все же любят установить дополнение, и чтобы оно сразу работало без танцев с бубном, верно?
Поэтому — сессии.
Вот такая небольшая юбилейная (трёхсотая!!!) заметка с объяснениями, почему AjaxForm, mSearch2, minShop2 и другие мои сниппеты хранят свои параметры в сессиях, а не где-то ещё.
Если у кого есть идеи для более удобного вызова сниппетов через ajax с хранением их параметров не в сессии — буду рад прочитать.
Переодически почитываю новости на сайте и вот увидел ветку комментариев про хранение данных в сессии.
Казалось бы, совершенно заслуженный камень в мой огород, как автора дополнения. Зачем использовать сессии для ajax сниппетов, ведь сама по себе эта технология сессий не требует? Так-то оно так, но в мире MODX всё несколько сложнее.
Итак, у нас есть 2 основных варианта запустить какой-то сниппет через Ajax.
Вариант 1: отправить запрос на страницу с ним. Вполне рабочий, да, но не очень быстрый, потому что MODX выполнит все плагины и сниппеты, которые найдёт перед вашим сниппетом.
А если вы используете Fenom, то эти сниппеты еще и сразу выведут ответ через echo, потому что он не буферизирует результаты в переменную, а выводит сразу — что сломает ответ от вашего сниппета.
Не подходит.
Вариант 2 — отправлять запрос на отдельный PHP коннектор, который запустит нужный сниппет в облегчённом MODX_API режиме и получит от него ответ без дополнительных затрат.
Отличный, быстрый вариант. Но нам нужно запустить этот сниппет с какими-то параметрами, верно? А где их взять?
Доверить юзеру самому отправлять параметры для работы сниппета нельзя, иначе он вам через pdoResources вытащит все возможные данные из БД, а может еще и запишет чего через другой сниппет. Где хранить данные для запуска сниппета через коннектор?
Тут тоже 2 варианта: какой-то отдельный временный файл с настройками или сессия. При этом отдельный файл с настройками должен обновляться при изменении параметров вызова сниппета на странице, и не должен зависеть от id или группы юзера (иначе файлов будет несколько и особой разницы с сессией не получится) — это всё выглядит довольно сложно для реализации.
А вот сессии вполне рабочий вариант. Да, возможно не самый лучший, но другого я не придумал. По факту, из реально рабочих и универсальных вариантов, это единственный. Все же любят установить дополнение, и чтобы оно сразу работало без танцев с бубном, верно?
Поэтому — сессии.
Вот такая небольшая юбилейная (трёхсотая!!!) заметка с объяснениями, почему AjaxForm, mSearch2, minShop2 и другие мои сниппеты хранят свои параметры в сессиях, а не где-то ещё.
Если у кого есть идеи для более удобного вызова сниппетов через ajax с хранением их параметров не в сессии — буду рад прочитать.
Комментарии: 23
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Если работа сниппета зависит от каких-то динамических параметров (id юзера или группа), то точно так же замусорит базу данных. При этом, насколько я помню, возможностей по расширению логики работы там поменьше, чем у modSession.
Да и взять и разом почистить modRegistry из админки нельзя.
В коде AjaxForm меняем логику генерации хеша:
и потом добавляем новую запись в базу если такого хеша еще нет. При обработке запроса AjaxForm берем данные по хешу из базы а не из сессии.
Сессии — это просто инструмент. Всё зависит от того, как им пользоваться. Вот из коробки в сессии пишутся группы ресурсов и группы пользователей. В итоге возникает проблема консистентности данных после изменения этих настроек. Это плохое использование сессий. А в ajaxForm использование сессий вполне обосновано.
И это глобально никак не влияет на разрастание таблицы сессий.
По большей части проблема или в неправильной настройке сборщика мусора (не зависит от MODX) или в ботах (о чём писал Алексей в своей статье), ибо каждый запрос бота вызывает создание новой записи в таблице. С гостями особой проблемы нет — запись создаётся только один раз и будет использоваться в течение 7 дней, потом будет удалена и создана другая (разговор про один браузер и стандартные настройки). Пример как игнорировать ботов и не создавать для них сессии есть у меня на сайте.
Т.е. если для 98% пользователей решение отлично подходит, но для 2-х% нет, то его нужно выбросить в пропасть. Ибо это оскорбляет эти 2%. Это не они должны адаптировать решение, а остальные 98%.
А ещё можно в догонку спросить? Сколько дополнений Вы создали?
П.С. Я спрашиваю абсолютно по-дружески. )
Вопрос по AjaxForm. В описании сказано, используются jQuery.Form и jQuery.jGrowl.
То есть, ему нужен jQuery. Можно ли обойтись без него?
github.com/bezumkin/AjaxForm/blob/master/assets/components/ajaxform/js/default.js
Извините, что вопрос не по теме.
Github pdoTools github.com/bezumkin/pdoTools — архивирован вами, кто теперь будет им заниматься и будут ли? Или вы кому-то его передали уже?
Спасибо.
Архивация репозитория означает, что лично я им заниматься не буду, только и всего.
В modstore.pro/packages/utilities/pdotools ссылка на github ведет на вас, у вас последний релиз версии 2.12.3
А на modstore последняя версия pdoTools — 2.12.10
Можно ли тогда обновить ссылку в описании pdoTools на актуальный github?
В репозитории та же версия, что и на modstore.
А если хранить данные в отдельной таблице? А через ajax передать только id нужной нам формы. И сниппет уже не нужен будет.
Но тут сразу второй вопорос — каждое дополнение будет устанавливать собственную такую таблицу? Или они все должны использовать какую-то общую? Если общую — как дополнениям об этом договориться, требовать какую-то зависимость, типа нового дополнения AjaxSettingsDB?
И если у вызова сниппета будет какой-то уникальный параметр, типа id юзера, то количество записей в такой БД будет ровно тем же, что и у таблицы сессий. Еще встаёт вопрос еще об очистке этой таблицы — сколько дней хранить в ней настройки?
Но, повторюсь, этот вариант мне нравится и в былые времена я мог бы переписать свои дополнения на хранение настроек в одной общей таблице. Кто сейчас это будет делать — вопрос.
Проблемы надо решать по мере их поступления. Вот Алексей споткнулся об гигабайтную таблицу и предложил решение. Но опять же, оно нужно не всем, а только тем, у кого аналогичная проблема. Остальным можно не париться.
Ну а отдельная таблица — это явный оверхед. Тогда уж лучше передавать в форму зашифрованные данные из параметров сниппета в скрытый инпут. В этом случае оверхеда будет гораздо меньше.