PHP Manual

Багаторічна форма

16. 09. 2019

Іноді нам потрібно розбити форму на кілька частин (сторінок), обробити їх окремо, а потім зібрати в один результат.

Ця стаття описує методи та шаблони проектування для цього.

Примітка: Примітка:.

Питання розбиття форми на декілька кроків є дуже складним, особливо якщо ви хочете зробити це якісно. У своєму житті я зустрічався з багатьма підходами, про які тут розповім. Деякі підходи виглядають привабливо, але є наївними і працюють лише в окремих випадках. Для кожного підходу я описую, коли він має сенс, а коли не має сенсу.

Розробка теоретичного рішення

Зазвичай мета полягає в тому, щоб отримати основні дані з першої форми на першій сторінці, валідизувати їх, потім зберегти "десь" і вивести на екран наступну сторінку.

Коли користувач доходить до останньої сторінки, необхідно заповнити загальну форму та обробити введені дані.

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

Впровадження самих форм

Ми можемо або реалізувати окремі форми самостійно на чистому HTML, а потім обробляти їх на PHP, або скористатися готовими рішеннями, такими як Nette forms.

Приклад з життя

Дуже часто мені пишуть програмісти-початківці і задають, здавалося б, прості питання, на які є готове рішення. Наприклад, конкретно про обробку форм на PHP.

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

Тому що люди не знають, що вони не знають, що вони не знають і тому замість того, щоб інвестувати 1 годину часу у вивчення готового рішення 99,99% проблем, вони вважають за краще обирати власне рішення, на налагодження якого витрачають десятки годин, і все одно є випадки, коли форми не працюють, викидають помилки, мають уразливості в безпеці, не захищають введені дані.

Тому метою цього кроку є реалізація декількох сторінок за різними URL-адресами, які будуть містити порожні форми.

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

Державний трансферт

При обробці першої форми ми хочемо спочатку перевірити отримані дані і якщо вони правильні, то перенаправити користувача на другий крок. Це гарна ідея обробляти перенаправлення як HTTP-перенаправлення, тому що легко може статися так, що дані не є дійсними, і в цьому випадку ми хочемо повернути користувача до першої форми, а не до наступного кроку.

В принципі, ми можемо зберігати стани 4 способами:

Не рекомендується:.

  • Ніде не зберігати і повністю передавати в URL-адресі. Це має той недолік, що користувач може змінити дані, які вже надіслані в URL-адресі, і таким чином підробити вхідні дані. Крім того, ми можемо розкрити конфіденційну інформацію, таку як паролі в URL-адресі.
  • Безперервно додавати до сесій**, тобто поетапно вставляти в поле щойно отримані дані за ключем. Це має той недолік, що якщо додаток робить помилку, то користувач застряє в сесії і не може ніяк вирішити помилку (крім видалення cookies, що для більшості людей вкрай складно), плюс при незаповненій формі є ризик, що дані залишаться попередньо заповненими і можуть бути побачені кимось іншим. Однак, набагато гірший випадок виникає, якщо сесія має дуже короткий термін дії (скажімо, 5 хвилин) і користувач втрачає дані з першого кроку під час заповнення останнього кроку... це може бути досить дратівливим.

Рекомендовано:** Рекомендовано:*

  • Внесення в базу даних та передача ідентифікатора**. При першому заповненні форми ми зберігаємо всі зібрані дані в таблиці бази даних і генеруємо випадковий ідентифікатор (скажімо, рядок довжиною 10 символів), який передається між сторінками як параметр. Перевагою цього є те, що при обробці будь-якої форми ми можемо записати щойно отримані та перевірені дані безпосередньо в таблицю, а в разі збою ми маємо фізичні резервні копії розібраних форм і можемо діяти за ними. Наприклад, якщо замовлення є незавершеним, ми можемо надіслати користувачеві електронного листа про те, що він його не завершив, і збільшити шанс продажу.
  • Зберегти в обліковий запис користувача** працює точно так само, як і пересилання через ID, за винятком того, що замість випадкового ідентифікатора (токена) використовується сесія до ID користувача, що увійшов в даний момент в систему (якщо такий є). Перевага полягає в тому, що ми можемо довільно показувати користувачеві попередньо заповнені дані в майбутньому.

Висновок

Жодне з наведених рішень не є ідеальним і єдино правильним. Я сам поєдную кілька підходів, коли працюю над багатокроковими рішеннями. Зазвичай, наприклад, я вирішую кошик як таблицю бази даних, якій присвоюю вже зібрані мною дані і прив'язую її або до користувача (якщо він авторизований), або до сесії (якщо він не авторизований і ми ще не знайомі).

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
3.
Status:
All systems normal.
2024