Веб-разработка на PHP
Теория: Модифицирующие формы
Формы, которые изменяют данные, устроены сложнее как с клиентской стороны, так и с серверной. Для уверенной работы с ними необходимо разбираться в следующих вопросах:
- Знание соответствующих HTML-тегов
- Понимание того, как отправляются формы по HTTP
- Обработка на стороне сервера
- Валидация и вывод ошибок
Начнем с того, что за вывод формы и ее обработку должны отвечать два разных обработчика, значит, это разные маршруты. Ниже пример маршрутов для создания нового пользователя:
- GET /users/new — страница с формой, которую заполняет пользователь. Эта форма отправляет POST-запрос на адрес /users, указанный в атрибуте
action - POST /users — маршрут, обрабатывающий данные формы
Подобная схема именования рекомендуется и автоматически создается многими фреймворками, такими как Rails. Она хорошо ложится на REST-архитектуру, о которой мы еще поговорим.
Форма
Каждое имя определяется как ключ в массиве user. Такой способ определения имен — необязательный, но он удобен для массовой обработки значений формы. Их изоляция в одном массиве позволяет избежать потенциальных пересечений с другими данными. В поисковых формах эта схема тоже удобна, если количество элементов больше одного.
С точки зрения HTTP не существует способа передавать массивы. Если не указано иного, то данные формы кодируются в теле запроса как application/x-www-form-urlencoded. Чисто технически это выглядит как строка запроса с парами ключ-значение, объединенные символом &:
POST /users HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 42
key=value&key2=value2&user%5Bname%5D%3Djohn
В конце тела закодирован ключ user[name]. Превращение таких ключей в массив идет на уровне интерпретатора в случае PHP. Либо на уровне самого фреймворка в случае остальных языков.
Обработка данных
Обработка данных формы начинается с извлечения данных из тела запроса. Это можно сделать двумя способами, похожими на то, как мы извлекаем параметры запроса:
getParsedBody()— извлекает все данныеgetParsedBodyParam($name, $defaultValue)— извлекает значение конкретного параметра. Вторым параметром принимает значение по умолчанию
Далее нужно убедиться в том, что данные введены верно. Этот процесс называется валидацией.
Slim не предоставляет механизмов для валидации. Ее можно получить из сторонних библиотек. В нашем случае валидация реализуется классом с одним методом validate(), который проверяет данные формы. Также он возвращает специальный массив $errors. В нем ключ — это название поля, а значение — текст ошибки, который нужно вывести в форме:
Если ошибок нет, то данные формы сохраняются, например, в базу данных. Об этом подробнее в следующем уроке. После сохранения выполняется перенаправление (HTTP redirect). За перенаправление отвечает заголовок Location и статусы с кодом 3XX:
Если в процессе обработки возникли ошибки, выполняется рендеринг формы из шаблона, который мы использовали для /users/new. В этот шаблон передаются как данные формы, так и список ошибок.
Редиректа не происходит, в адресной строке остается адрес /users. Если попробовать в этот момент нажать f5, то браузер выдаст предупреждение о том, что мы пытаемся повторно отправить данные. Это сообщение предупреждает о том, что метод POST не идемпотентен, и повторная отправка формы может привести к повторному созданию пользователя:
Вернемся к нашей форме и изменим ее так, чтобы в нее подставлялись возникающие ошибки и значения полей, введенные пользователем:
Такое изменение формы требует изменения обработчика /users/new. Чтобы избежать ошибок, нужно передать в шаблон пустой массив $errors и массив $user. В последнем необходимо задать значения по умолчанию для соответствующих полей формы. Так в шаблоне не придется выполнять проверку данных формы на существование:
Форма увеличилась. На практике она будет еще больше из-за дополнительного оформления, например, отступов и подсветки ошибок. С опытом станет понятно, что так невозможно работать. Ради простейшей обработки придется писать много идентичного кода в HTML. Эту работу нужно автоматизировать.
Для генерации форм используются специальные билдеры. Микрофреймворки не имеют встроенных билдеров, поэтому придется искать их самостоятельно.
Довольно популярны формы из фреймворка Symfony. В этом компоненте каждая форма представлена своим классом. Компонент поддерживает валидацию, имеет встроенные механизмы защиты от некоторых атак и многое другое.
Рекомендуемые программы
Завершено
0 / 28

