|
|
|
| Кто нибать может проконсультировать / посоветовать источники по вопросу реализации многошаговых диалогов в вебе на php.
Поясню вопрос:
Требуется реализовать следующее:
Первый шаг – заполнить 1 форму жмешь «далее»
Если в форме ошибки – возвращаешься к форме, если все ОК – на второй шаг.
Второй шаг – на основе данных первой формы дополнительно что-то спрашивается во второй форме
в форме ошибки – возвращаешься ко 2-й форме, если все ОК – на третий шаг.
..и т.д.
---
Как это грамотно реализовывать?
Основные загвоздки
- Где и как хранить промежуточные результаты (временные таблицы, флаги в постоянных таблицах и проч.)
- Как сохранить единообразие и откат всех шагов в случае сбоя на одном из них
- Стоит ли разбить сценарий на несколько, соответственно шагам, или выполнять все в одном, но большом
---
В общем, хочется получить консультацию по цивилизованному решению таких проблем.
Как это принято делать, какие рекомендации и ограничения исходя из опыта народ может посоветовать? | |
|
|
|
|
|
|
|
для: Niko2
(22.01.2007 в 00:53)
| | Если требуется откат на предыдущие этапы с сохранением уже набранной информации в последующих этапах, то разумно помещать информацию в сессию - это пожалуй самый приемлемый вариант. | |
|
|
|
|
|
|
|
для: cheops
(22.01.2007 в 00:57)
| | Там могу быть большие блоки текста, и, возможно, загрузка файлов на сервер. Так что сессии не покатят.
Надо ли разбивать сценарий на части?
Что дешевле с точки зрения ресурсов сервера – выполнился один, записал что то в базу, и запустил второй, который согласно какомуто переданному ему параметру считал инфу обратно и т.д.
Или же следует сделать один сценарий на 10 прокруток текста, с кучей инклудов и переменных в памяти? | |
|
|
|
|
|
|
|
для: Niko2
(22.01.2007 в 01:04)
| | Дешевле и надежней первый вариант. | |
|
|
|
|
|
|
|
для: Niko2
(22.01.2007 в 01:04)
| | Если загружаете файлы, то волей не волей придётся использовать первый вариант. Однако если пользователь не заканчивает диалог - необходимо предусмотреть механизм удаления полу-завершённой анкеты. | |
|
|
|
|
|
|
|
для: Niko2
(22.01.2007 в 00:53)
| | Ответ родился, попробую сформулировать и пояснить непосредственно на примерах. Сразу извиняюсь за то, что будет много информации, которую Вы, возможно, знаете.
Попытался смоделировать абстрактную ситуацию и попробовать на почти всех типах "input"`ов.
Примечание: опущены теги "form" и "сабмиты" к формам, сессия УЖЕ запущена
Проблемы:
Где хранить
1)текстовые данные (input и textarea)
2)чекбоксы
3)радиокнопки
4)выбранные пункты в выпадающем списке
5)картинку
Как удалить:
6) картинку если юзер ушел
варианты с первого по четвертый решаются сессиями:
На каждом следующем шаге (при переходе к новой форме), переданные значения из POST`а дублируются в SESSION:
<?php
$_SESSION['что-то_где-то'] = $_POST['что-то_где-то'];
?>
|
1)Для организации "подстановки" уже вбитых значений в поля (input type=text) воспользуемся параметром "value" тега; для textarea все проще. Допустим, что мы раньше ввели эти значения и перевели их в сессионные переменные
<input type="text" name="login" value="<?=@$_SESSION['login']?>" />
<textarea name="about"><?=@$_SESSION['about']?></textarea>
|
2)
Чекбоксы можно хранить только в массивах, ибо если хранить только в переменных последнее значение затрет все предыдущие:
напр. ...&sport=1&sport=2... => sport = 2
следовательно импользуем массив:
напр. ...&sport[]=1&sport[]=2... => sport[0] => 1 и sport[1] = 2
Но есть одно "но" - если одна из галок не отмечена, то, например, выбрав 2-е, 5-е и 6-е значение, мы получим массив, но массив, не привязанный к самим галкам, следовательно, нужно создать новый массив, в котором ключами будут значения переменных в массиве предыдущем:
<?
foreach (@$_SESSION['sport'] as $key => $value)
{
$check_1[$value] = 'checked="true" ';
}
?>
|
после чего, подставим кое-что в саму форму.
Важное замечание: теперь мы привязаны к значениям самих чекбоксов, а это гуд! Значения ключей должны совпадать с значениями чекбоксов.
<input type="checkbox" name="sport[]" value="0" <?=@$check_1['0']?>/>
<input type="checkbox" name="sport[]" value="bla-bla" <?=@$check_1['bla-bla']?>/>
<input type="checkbox" name="sport[]" value="2" <?=@$check_1['2']?>/>
<input type="checkbox" name="sport[]" value="123" <?=@$check_1['123']?>/>
<input type="checkbox" name="sport[]" value="beer" <?=@$check_1['beer']?>/>
<input type="checkbox" name="sport[]" value="qwerty" <?=@$check_1['qwerty']?>/>
|
3) С радиокнопками все проще - там значение только одно, foreach не понадобится
<?
$radio_1[$_SESSION['sex']] = 'checked="true" ';
?>
|
Опять-таки, "проверяем" значение радиокнопки:
<input type="radio" name="sex" value="ma" <?=@$radio_1['ma']?> />
<input type="radio" name="sex" value="woman" <?=@$radio_1['woman']?> />
|
4) С select`ами все то же самое.
И наконец...
5) и 6)
Надо:
*создать папку для хранения загруженных картинок
*создать таблицу с тремя полями: `id` , `filename` и `timeupload`
*загруженную картинку назвать уникальным именем, напр.
<? md5(microtime(true) + mt_rand(0, 10000));
#для фаталистов-любителей, которые считают, что непременно произойдет коллизия одновременного обращения двух пользователей=)?>
|
*записать в таблицу имя файла, id(который автоинкрементный) использовать в новой сессионной переменной, а также записать туда время загрузки картинки на сервер
*если пользователь дойдет до последнего шага и зарегистрируется, то по id найти имя файла и записать имя файла в таблицу юзеров, картинку для верности отправить в другую папку, запись во временной таблице УДАЛИТЬ!
*если пользователь вернется к выбору картинки, предложить загрузить новую: если загрузит новую, то старую удалить, запись из таблицы удалить, новую картинку создать, новую запись в таблице создать, если загружать откажется, то работать со старой.
*при следующем обращении к скрипту регистрации (новый юзер) прочесть все оставшиеся записи во "временной" таблице (которая должна быть пустая, если все дошли до конца) и удалить картинки, которые загружены более 3-х часов назад (предостережение на случай одновременно регистрирующихся).
Все... Я выдохся...=)
На закуску: В аттаче находится форма, которая обращается к самой себе и передает значения из шести типов инпутов:
text
textarea
radio
select - одиночный
select - множественный
checkbox.
Все переданные значения "сохраняются"
На здоровье!=) | |
|
|
|
|
|
|
|
для: Niko2
(22.01.2007 в 00:53)
| | Ах да... Чуть не забыл. По поводу ветвлений.
Допустим структура такова:
форма 1 -> форма 2 (вар1) или форма 2(вар2) -> форма 3 -> закончить регистрацию
Например, сначала спрашиваем пол, в зависимости от пола - у мужиков спрашиваем про пиво и рыбалку, у прекрасных дам про моду и гламур, в конце просим загрузить аватарку и всё.
Вариант реализации:
Форма 1 (form1.inc):
<form action="form.php?step=2" method="post">
...
</form>
|
Форма 2-мужская (form2m.inc)
<form action="form.php?step=3" method="post">
...
</form>
|
Форма 2-женская (form2w.inc)
<form action="form.php?step=3" method="post">
...
</form>
|
Форма 3 (form3.inc)
<form action="form.php?step=register" method="post">
...
</form>
|
Самый главный файл (form.php):
<?
if (!@$_GET['step'] || @$_GET['step'] ==1)
{
include "form1.inc";
}
elseif(@$_GET['step'] == 2)
{
if ($_POST['sex'] == "m")
{
include "form2m.inc";
}
elseif($_POST['sex'] == "w")
{
include "form2w.inc";
}
else
{
//Ошибочка вышла - забыли куазать пол
}
}
elseif(@$_GET['step'] == 3)
{
include "form3.inc";
}
elseif(@$_GET['step'] == "register")
{
//Начинаем регистрацию
}
else
{
//Передали не тот параметр - выводим начало
include "form1.inc";
}
?>
|
Причем, данные каждого шага будут храниться в массивах с соответствующими названиями, напр.
<?
$_SESSION['step1']['sex'] = "m";
$_SESSION['step2']['beer'] = "Много";
?>
|
| |
|
|
|