Пошаговая форма + кеширование промежуточных данных

О пошаговых html формах написано не мало и в общем то ни чего особенного в реализации нет. Обычное дело для получения от посетителя объемных и связанных данных, многим не раз приходилось решать такую задачу.

Чуть более сложнее обстоит дело с реализацией, если пользователю необходимо предоставить возможность возврата на предыдущие шаги формы, с сохранением заполненных ранее данных (отмечу, что речь идет о форме в которой каждый шаг — отдельная страница). Когда требовалась такая функциональность и было не много данных (полей формы) я пришел к следующему решению:

На каждом шаге проверяются данные в специальных hidden input-ах и при наличии используются при подстановке значений полей формы
Каждый следующий шаг принимает POST данные с предыдущего(их) шагов, сериализует и добавляет в специальные hidden input-ы
Action формы меняется динамически (js) в зависимости от нажатия кнопки «Вперед» или «Назад», т.е. либо url следующего шага, либо предыдущего
После чего также с помощью js производиться submit формы

Но такой подход имеет проблему с потерей введенных ранее данных при переходе по прямому url (без submit-а) на любой шаг.

Усложняем задачу

Сравнительно недавно понадобилось решить похожую задачу, но она имела более жесткие требования:

Форма разбита на 3-и шага
Посетитель может начать с любого из первых 2-х
На 3-й (подтверждение) может попасть только после заполнения данных на первых 2-х
Возможен большой объем данных, до 50 текстовых полей (в моем случае кредитная форма)
Заполненные данные желательно хранить определенное кол-во времени, т. е. пользователь может уйти с сайта, вернуться и продолжить работу с формой

Где хранить?

Основной вопрос, который встал перед реализацией: где хранить промежуточные данные?
Cookie и Session?
Да, можно, но как-то много данных могло быть, да и вроде некоторые желательно обезопасить.

Пришла идея хранить промежуточные данные первых двух шагов в файловом кеше. Для этого подойдет любой класс или набор функций реализующих кеширование, например Zend_Cache. Проект писался на API Битрикс-а, поэтому использовал класс CPHPCache.

Функциональность кеширования должна предоставлять следущий минимум:

Формировать кеш с заданным идентификатором
Получать данные из кеша по заданному идентификатору
Проверять существование кеша с заданным идентификатором
Определять истек ли срок действия кеша
Удалять кеш по заданному идентификатору

Схема и описание

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

Для первых 2-х шагов будем использовать обработчики (HANDLER1, HANDLER2). Данные формы будут передаваться обработчикам ajax-ом. Для этого мне пришелся по душе jQuery плагин Ajax Form (думаю многие знакомы).

Также для 1-го и 2-го шагов необходимо предопределить идентификаторы кеша, с привязкой к определенному посетителю, чтобы исключить путаницы в данных. В моем случае заполнять форму могли только авторизованные пользователи, поэтому в идентификаторе кеша использовался ID пользователя. В других случаях думаю можно привязаться к идентификатору сессии.

Итак:
Step1_{userId} -для первого шага
Step2_{userId} -для второго шага
где {userId} — идентификатор авторизованного пользователя

Шаг 1:

Перед выводом формы (FORM 1) проверяется существование кеша Step1_{userId}
Если кеш существует и не истек период жизни, извлекаем данные и выводим форму с данными из кеша
Если нет, то выводим форму со значениями по умолчанию
Пользователь либо заполняет форму новыми данными, либо редактирует данные полученные из кеша
По нажатию NEXT данные формы ajax-ом передаются обработчику HANDLER 1
HANDLER 1 проверяет корректность переданных данных
Проверяет существует ли кеш с идентификатором Step1_{userId}
Если кеш существует удаляет его
Формирует кеш с идентификатором Step1_{userId} и данными переданными из FORM 1
Возвращает в качестве ответа на ajax запрос статус выполненной операции
Если статус OK, браузер перенаправляет пользователя на следующий шаг (js)
Если статус ERROR выводит сообщение об ошибке

Шаг 2: Аналогично 1-му

Шаг 3:

Проверяется существование кеша Step1_{userId}
Если кеш не существует, то перенаправляем посетителя на 1-й шаг, в противном случае извлекаем данные из кеша
Проверяем существование кеша Step2_{userId}
Если кеш не существует, то перенаправляем посетителя на 2-й шаг, в противном случае извлекаем данные из кеша
Формируем страницу с результирующими данными и формой (FORM 3) содержащей сериализованные данные в hidden input-ах
По submit-у формы FORM 3 отправляем данные для дальнейших операций
Удаляем кеш с идентификаторами: Step1_{userId}, Step2_{userId}

Время жизни кеша каждый может определить по своим требованиям у меня был 12 часов, также перед отправкой данных обработчикам (HANDLER 1, HANDLER 2), использовал валидацию формы с помощью js (jQuery).

Данный способ тоже не без изъянов. Возникает проблема с устаревшим кешем, если кто либо заполнит данные на двух шагах, но не закончит действия на 3-м шаге, где очищается кеш, то будут копиться кеш файлы. Для этого необходимо предусмотреть некий «сборщик мусора», если используемый класс кеширования не предоставляет данного функционала.

Конечно функциональность кеширования используется не по прямому назначению, но получилось рабочее решение. Не понятно на сколько усилиться нагрузка на сервер (файловые операции, чтение/запись кеша) при большом количестве пользователей одновременно работающих с формой и какие еще подводные камни могут всплыть. Пока проект в разработке и не тестировался должным образом…

Хочется услышать конструктивные комментарии.
Добавлено: 23 Августа 2013 02:22:15 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...