Обработчики запросов — Веб-разработка на PHP
Главная содержательная часть в файле index.php — обработчик запроса:
$app = AppFactory::create(); // Обработчик $app->get('/', function ($request, $response) return $response->write('Welcome to Slim!'); >);
Общий принцип работы любого веб-фреймворка отражает архитектуру HTTP. На каждый адрес задается обработчик (функция, handler), который выполняет необходимые действия и возвращает ответ.
В Slim все приложение представлено объектом класса Slim\App . Этот объект содержит методы на каждый глагол HTTP: get , post , put и так далее. Эти методы принимают на вход два параметра:
- Адрес или маршрут, для которого вызовется обработчик
- Обработчик. Лямбда-функция с двумя параметрами $request и $response
Во фреймворках принято определять маршрут как комбинацию метода HTTP и адреса. Это соответствует идеям REST . То есть GET /users и POST /users с точки зрения большинства фреймворков — разные маршруты со своими обработчиками. В этом достаточно просто убедиться, если определить соответствующие маршруты и выполнить к ним запросы с помощью curl:
$app = AppFactory::create(); $app->get('/users', function ($request, $response) return $response->write('GET /users'); >); $app->post('/users', function ($request, $response) return $response->write('POST /users'); >); $app->run();
-XPOST localhost:8080/users POST /users
Перед тем как двигаться дальше, обязательно попробуйте повторить примеры выше в вашей локальной среде. Это важно для понимания дальнейшего контента.
Первое, что бросается в глаза, — у нас всего один входной файл для всех адресов. Пользователь может запрашивать сколь угодно сложный адрес /companies/3/photos5. Всё сведется к запуску файла index.php, а сам адрес становится лишь значением $_SERVER[‘REQUEST_URI’] :
Такой подход имеет название FrontController в противовес подходу, когда каждый адрес фактически отображался на конкретный файл файловой системы — PageController.
В интернете до сих пор встречаются сайты, построенные по этой модели, но она давно вышла из употребления. Заметить ее легко. Если есть адреса наподобие /users.php , то почти наверняка в корне сайта лежит файл users.php, который отвечает за обработку этой страницы:
Во FrontController процесс поиска нужного обработчика называется диспетчеризацией, по аналогии с тем как это слово используется в оффлайн жизни. Пошагово он выглядит так:
До входа во фреймворк:
- Клиент выполняет запрос к веб-серверу, расположенному на сервере. Клиент — это не обязательно браузер, в примере выше клиентом выступает программа curl
- Веб-сервер перенаправляет запрос на index.php и устанавливает правильные параметры запроса
После входа в сам PHP (именно это и есть диспетчеризация):
- Фреймворк анализирует параметры запроса и пытается сопоставить маршруты, добавленные в объект $app (как в примерах в начале урока) с тем, что пришло. Он сравнивает комбинацию метода запроса и сам адрес. Этот процесс называется роутингом или маршрутизацией. А место, где внутри хранятся все добавленные маршруты, называют роутером
- Если в процессе роутинга был найден соответствующий маршрут, то вызывается его обработчик
- Ответ, сформированный обработчиком, отправляется обратно клиенту
Рассмотрим конкретный пример. Возьмем за основу следующий код:
$app = AppFactory::create(); $app->get('/', function ($request, $response) return $response->write('GET /'); >); $app->get('/companies', function ($request, $response) return $response->write('GET /companies'); >); $app->post('/companies', function ($request, $response) return $response->write('POST /companies'); >); $app->run();
После запуска этого кода формируется роутер, который содержит в себе три маршрута:
Теперь предположим, что клиент выполнил такой запрос:
-XPOST localhost:8080/companies
Веб-сервер запустил index.php, который проинициализировал объект $app . Затем фреймворк сопоставил маршруты и нашел, что за этот запрос отвечает POST /companies. Далее фреймворк вызвал обработчик, который вернул клиенту ответ: POST /companies.
Если фреймворк не обнаружит соответствия, например, клиент запросит страницу /comments, то он возьмет управление на себя по умолчанию и автоматически отдаст браузеру ответ 404. Так он говорит о том, что страница не найдена.
Всегда нужно внимательно смотреть, какие делаются запросы и есть ли подходящие под них ответы, чтобы не думать о том, почему браузер ничего не показывает. Проще всего увидеть ответ от сервера через консоль разработчика браузера:
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Отправка данных формы
Сама форма обычно предназначена для получения от пользователя информации для дальнейшей пересылки её на сервер, где данные формы принимает программа-обработчик. Такая программа может быть написана на любом серверном языке программирования вроде PHP, Perl и др. Адрес программы указывается в атрибуте action тега , как показано в примере 1.
Пример 1. Отправка данных формы
HTML5 IE Cr Op Sa Fx
Данные формы
В этом примере данные формы, обозначенные атрибутом name ( login и password ), будут переданы в файл по адресу /example/handler.php. Если атрибут action не указывать, то передача происходит на адрес текущей страницы.
Передача на сервер происходит двумя разными методами: GET и POST, для задания метода в теге используется атрибут method , а его значениями выступают ключевые слова get и post . Если атрибут method не задан, то по умолчанию данные отправляются на сервер методом GET. В табл. 1 показаны различия между этими методами.
GET | POST | |
---|---|---|
Ограничение на объём | 4 Кб | Ограничения задаются сервером. |
Передаваемые данные | Видны сразу всем. | Видны только при просмотре через расширения браузера или другими методами. |
Кэширование | Страницы с разными запросами считаются различными, их можно кэшировать как отдельные документы. | Страница всегда одна. |
Закладки | Страницу с запросом можно добавить в закладки браузера и обратиться к ней позже. | Страницы с разными запросами имеют один адрес, запрос повторить нельзя. |
Какой метод используется легко определить по адресной строке браузера. Если в ней появился вопросительный знак и адрес стал похож на этот, то это точно GET.
Уникальное сочетание параметров в адресной строке однозначно идентифицирует страницу, так что страницы с адресами ?q=node/add и ?q=node считаются разными. Эту особенность используют системы управления контентом (CMS, Content management system) для создания множества страниц сайта. В реальности же используется один файл, который получает запрос GET и согласно ему формирует содержимое документа.
Ниже перечислены типовые области применения этих методов на сайтах.
GET
Передача небольших текстовых данных на сервер; поиск по сайту.
Поисковые системы, формы поиска по сайту всегда отправляются методом GET, это позволяет делиться результатами поиска с друзьями, слать ссылку по почте или выкладывать её на форуме.
POST
Пересылка файлов (фотографий, архивов, программ и др.); отправка комментариев; добавление и редактирование сообщений на форуме, блоге.
Работа с формой по умолчанию происходит в текущей вкладке браузера, при этом допустимо при отправке формы изменить этот параметр и открывать обработчик формы в новой вкладке или во фрейме. Такое поведение задаётся через «имя контекста», которое выступает значением атрибута target тега . Популярные значения это _blank для открытия формы в новом окне или вкладке, и имя фрейма, которое задаётся атрибутом name тега (пример 2).
Пример 2. Открытие формы во фрейме
HTML5 IE Cr Op Sa Fx
В данном примере при нажатии на кнопку «Отправить» результат отправки формы открывается во фрейме с именем area .
Элементы формы традиционно располагаются внутри тега , тем самым определяя те данные, которые будут передаваться на сервер. В то же время в HTML5 есть возможность отделить форму от её элементов. Это сделано для удобства и универсальности, так, сложный макет может содержать несколько форм, которые не должны пересекаться меж собой или к примеру, некоторые элементы выводятся с помощью скриптов в одном месте страницы, а сама форма находится в другом. Связь между формой и её элементами происходит в таком случае через идентификатор формы, а к элементам следует добавить атрибут form со значением, равным этому идентификатору (пример 3).
Пример 3. Связывание формы с полями
HTML5 IE Cr Op Sa Fx
Форма .
В этом примере тег однозначно отождествляется через идентификатор auth , а к полям, которые следует отправить с помощью формы, добавляется form=»auth» . При этом поведение элементов не меняется, при нажатии на кнопку логин и пароль пересылаются на обработчик handler.php.
Хотя параметры передачи формы традиционно указываются в теге , их можно перенести и в кнопки отправки формы ( и ). Для этого применяется набор атрибутов formaction , formmethod , formenctype и formtarget , которые являются аналогами соответствующих атрибутов без приставки form. В примере 4 показано использование этих атрибутов.
Пример 4. Отправка формы
HTML5 IE Cr Op Sa Fx
Отправка формы
Все новые атрибуты форм не поддерживаются некоторыми браузерами, в частности, Internet Explorer и Safari.
Класс SessionHandler
SessionHandler это специальный класс, который может использоваться для дополнения внутреннего обработчика сессий PHP путём создания дочерних классов от этого. Существует семь методов, которые являются обёртками над семью внутренними обработчиками хранения данных сессии ( open , close , read , write , destroy , gc и create_sid ). По умолчанию этот класс оборачивает все внутренние обработчики хранения сессии, определённые в опции конфигурации session.save_handler. Эта опция по умолчанию имеет значение files . Другие внутренние обработчики сессий предоставляются PHP-модулями, такими как SQLite ( sqlite ), Memcache ( memcache ) и Memcached ( memcached ).
Экземпляр класса SessionHandler может устанавливаться в качестве обработчика сессии посредством вызова функции session_set_save_handler() . В этом случае он станет обёрткой существующего внутреннего обработчика. Классы, расширяющие SessionHandler позволят переопределить методы обработчика сессии или перехватить/отфильтровать их путём вызова родительских методов-обёрток внутреннего обработчика сессий PHP.
Это позволит вам, к примеру, перехватить методы read и write для шифровки/дешифровки данных сессии и передачи результата родительскому классу и от него. Или, к примеру, вы можете полностью переопределить такой метод как callback-функция сборщика мусора ( gc ).
Так как SessionHandler является обёрткой над стандартным внутренним обработчиком сессии, то пример, приведённый выше про шифровку данных может быть применён к любому внутреннему обработчику сессии даже без понимания внутреннего устройства процесса работы сессии.
Для использования этого класса, во-первых, установите обработчик, который вы хотите дополнить используя session.save_handler. Далее передайте экземпляр класса SessionHandler или одного из классов, расширяющих его функции session_set_save_handler() .
Обратите внимание, что callback-методы этого класса предназначены для внутреннего вызова PHP и не предназначены для вызова из кода пользовательского пространства. Возвращаемые значения одинаково обрабатываются внутри PHP. Дополнительную информацию о работе с сессией можно узнать из описания функции session_set_save_handler() .
Handler php что это
В основном для передаче параметров из форс используются методы POST и GET. Главное отличие методов POST и GET заключается в способе передачи информации. В методе GET параметры передаются через адресную строку (URL), т.е. в HTTP-заголовке запроса, в то время как в методе POST параметры передаются через тело HTTP-запроса и никак не отражаются в адресной строке.
1. Кнопки — Тег
Тег создает на веб-странице кнопки и по своему действию напоминает результат, получаемый с помощью тега (с параметром type=»button | reset | submit»). В отличие от этого тега, предлагает расширенные возможности по созданию кнопок. Например, на подобной кнопке можно размещать любые элементы HTML, в том числе изображения. Используя стили можно определить вид кнопки путем изменения шрифта, цвета фона, размеров и других параметров.
Теоретически, тег должен располагаться внутри формы, устанавливаемой элементом . Тем не менее, браузеры не выводят сообщение об ошибке и корректно работают с тегом , если он встречается самостоятельно. Однако, если необходимо результат нажатия на кнопку отправить на сервер, помещать в контейнер обязательно. Закрывающий тег обязателен.
• disabled — блокирует доступ и изменение элемента.
• type — тип кнопки
• value — Значение кнопки, которое будет отправлено на сервер или прочитано с помощью сприптов.
Параметр DISABLED Блокирует доступ и изменение кнопки. Она в таком случае отображается серой и недоступной для активации пользователем. Кроме того, такая кнопка не может получить фокус путем нажатия на клавишу Tab, мышью или другим способом. Тем не менее, такое состояние кнопки можно изменять через скрипты.
Параметр TYPE Определяет тип кнопки, который устанавливает ее поведение в форме. По внешнему виду кнопки разного типа никак не различаются, но у каждой такой кнопки свои функции. Значение по умолчанию: button.
button — Обычная кнопка.
reset — Кнопка для очистки введенных данных формы и возвращения значений в первоначальное состояние.
Submit — Кнопка для отправки данных формы на сервер.
Параметр VALUE Определяет значение кнопки, которое будет отправлено на сервер. На сервер отправляется пара «имя=значение», где имя задается параметром name тега , а значение — параметром value. Значение может, как совпадать с текстом на кнопке, так быть и самостоятельным. Также параметр value применяется для доступа к данным через скрипты.
1.1. Кнопка (input type=button)
1.2. Кнопка с изображением (input type=image)
Кнопки с изображениями аналогичны по действию кнопке Submit, но представляют собой рисунок. Для этого задаем type=image и src=»image.gif».
Когда пользователь щелкнет где-нибудь на изображении, соответствующая форма будет передана на сервер с двумя дополнительными переменными — sub_x и sub_y. Они содержат координаты нажатия пользователя на изображение. Опытные программисты могут заметить, что на самом деле имена переменных, отправленных браузером, содержат точку, а не подчеркивание, но PHP автоматически конвертирует точку в подчеркивание.
1.3. Кнопка отправки формы (input type=submit)
Служит для отправки формы сценарию. При создании кнопки для отправки формы необходимо указать 2 атрибута: type=»submit» и value=»Текст кнопки». Атрибут name необходим, если кнопка не одна, а несколько и все они созданы для разных операций, например кнопки «Сохранить», «Удалить», «Редактировать» и т.д. После нажатия на кнопку сценарию передается строка имя=текст кнопки.
РНР-сценарий не требуется.
1.4. Массив кнопок (submit) для выбора варианта действий
2. Кнопка сброса формы (Reset)
При нажатии на кнопку сброса (reset), все элементы формы будут установлены в то состояние, которое было задано в атрибутах по умолчанию, причем отправка формы не производиться.
РНР-сценарий не требуется.
3. Флажок (checkbox)
Флажки checkbox предлагают пользователю ряд вариантов, и разрешает произвольный выбор (ни одного, одного или нескольких из них).
Белый
Зеленый
Синий
Красный
Черный
$go) < echo $index." - >".$go."
"; >; >;
4. Переключатель(radio)
Переключатели radio предлагают пользователю ряд вариантов, но разрешает выбрать только один из них.
Белый
Зеленый
Синий
Красный
Черный
// первый набор кнопок
// второй набор кнопок
// третий набор кнопок
\n"; ?>
5. Текстовое поле (text)
При создании обычного текстового поля размером size и максимальной допустимой длины maxlength символов, атрибут type принимает значение text. Если указан параметр value, то поле будет отображать указанный в переменной value. При создании поля не забывайте указывать имя поля, т.к. этот атрибут является обязательным.
6. Поле для ввода пароля (password)
Полностью аналогичен текстовому полю, за исключением того, что символы, набираемые пользователем, не будут отображаться на экране.
7. Скрытое текстовое поле (hidden)
Позволяет передавать сценарию какую то служебную информацию, не отображая её на странице.
8. Выпадающий список (select)
Тэг представляет собой выпадающий или раскрытый список, при этом одновременно могут быть выбраны одна или несколько строк. Но будет передано значение последней выбранной кнопке.
Список начинается с парных тегов . Теги позволяют определить содержимое списка, а параметр value определяет значение строки. Если в теге указан параметр selected, то строка будет изначально выбранной. Параметр size задает, сколько строк будет занимать список. Если size равен 1, то список будет выпадающим. Если указан атрибут multiple, то разрешено выбирать несколько элементов из списка. Но эта схема практически не используется, а при size = 1 не имеет смысла.
; ?>
Если необходимо создать выпадающий с предсказуемой последовательностью. Например, список с годами с 2000 по 2050. То используется следующий прием.
; ?>
9. Многострочное поле ввода текста (textarea)
Многострочное поле ввода текста позволяет отправлять не одну строку, а сразу несколько. При необходимости можно указать атрибут readonly, который запрещает редактировать, удалять и изменять текст, т.е. текст будет предназначен только для чтения. Если необходимо чтобы текст был изначально отображен в многострочном поле ввода, то его необходимо поместить между тэгами .
Существует параметр wrap – задание переноса строк. Возможные значения:
off — отключает перенос строк;
virtuals — показывает переносы строк, но отправляет текст как он введен;
physical — переносы строк оставляются в исходном виде.
По умолчанию тег создает пустое поле шириной в 20 символов и состоящее из 2 строк.
Первоначально вставленный текст
—>
Для того, чтобы в многострочном текстовом поле соблюдалось html-форматирование (перенос строк по средством тега или ), то используйте функцию nl2br():
10. Кнопка для загрузки файлов (browse)
Служит для реализации загрузки файлов на сервер. При создании текстового поля также необходимо указать тип поля type как «file».
Загрузить файл:
СПОСОБЫ ОБЩЕНИЯ БРАУЗЕРА С СЕРВЕРОМ
Способов, предоставляемых протоколом HTTP, немного. Это важная информация. Никаких других способов нет. На практике используются два: GET — это когда данные передаются в адресной строке, например, когда пользователь жмет ссылку. POST — когда он нажимает кнопку в форме.
Метод GET
Чтобы передать данные методом GET не надо создавать на HTML-странице форму (использовать формы для запросов методом GET вам никто не запрещает — но это тупость) — достаточно ссылки на документ с добавлением строки запроса которая может выглядеть как переменная=значение пары объединяются с помощью амперсанда & а к URL страницы строка присоединяется с помощью вопросительного знака «?».
Но можно не использовать пары ключ=значение если надо передать всего одну переменную для этого надо после знака вопроса написать ЗНАЧЕНИЕ (не имя) переменной.
Преимущество передачи параметров таким способом заключается в том что клиенты которые не могут использовать метод POST (например, поисковые машины) все же смогут просто пройдя по ссылке передать параметры скрипту и получить содержимое.
Недостаток в том, что просто изменив параметры в адресной строке пользователь может повернуть ход сценария непредсказуемым образом, это создает огромную дыру в безопасности в сочетании с неопределенными переменными и register_globals on или кто-нибудь может узнать значение важной переменной (например ID-сеcсии) просто посмотрев на экран монитора.
Для чего следует использовать:
— для доступа к общедоступным страницам с передачей параметров (повышение функциональности)
— передача информации не влияющей на уровень безопасности
Для чего не следует использовать:
— для доступа к защищенным страницам с передачей параметров
— для передачи информации влияющей на уровень безопасности
— для передачи информации не подлежащей модифицированию пользователем (некоторые передают текст SQL-запросов.
Метод POST
Передать данные методом POST можно только с помощью формы на HTML странице. Основное отличие POST от GET в том, что данные передаются не в заголовке запроса а в теле, следовательно пользователь их не видит. Модифицировать может только изменив саму форму.
Преимущество:
— большая безопасность и функциональность запросов с помощью форм методом POST.
Для чего следует использовать:
— для передачи большого объема информации (текст, файлы..);
— для передачи любой важной информации;
— для ограничения доступа (например, использовать для навигации только форму — возможность доступная не всем программам-роботам или грабберам-контента).
Для чего не следует использовать:
Загрузка файлов методом POST
PHP способен принимать файл, загружаемый при помощи любого браузера,. Это дает возможность загружать как текстовые, так и бинарные файлы. Вместе с PHP-аутентификацией и функциями для работы с файловой системой вы получаете полный контроль над тем, кому разрешено загружать файлы, и над тем, что делать с файлом после его загрузки.
Страница для загрузки файлов может быть реализована при помощи специальной формы, которая выглядит примерно так:
//Форма для загрузки файлов
В приведенном выше примере «_URL_» необходимо заменить ссылкой на PHP-скрипт. Скрытое поле MAX_FILE_SIZE (значение необходимо указывать в байтах) должно предшествовать полю для выбора файла, и его значение является максимально допустимым размером принимаемого файла. Также следует убедиться, что в атрибутах формы вы указали enctype=»multipart/form-data», в противном случае загрузка файлов на сервер выполняться не будет.
Внимание
Опция MAX_FILE_SIZE является рекомендацией браузеру, даже если бы PHP также проверял это условие. Обойти это ограничение на стороне браузера достаточно просто, следовательно, вы не должны полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Тем не менее, ограничение PHP касательно максимального размера обойти невозможно. Вы в любом случае должны добавлять переменную формы MAX_FILE_SIZE, так как она предотвращает тревожное ожидание пользователей при передаче огромных файлов, только для того, чтобы узнать, что файл слишком большой и передача фактически не состоялась.
Как определить метод запроса?
getenv('REQUEST_METHOD');
вернет GET или POST.
Какой способ следует применять?
• Если форма служит для запроса некой информации, например — при поиске, то ее следует отправлять методом GET. Чтобы можно было обновлять страницу, можно было поставить закладку и или послать ссылку другу.
• Если же в результате отправки формы данные записываются или изменяются на сервере, то следует их отправлять методом POST, причем обязательно после обработки формы надо перенаправить браузер методом GET. Так же, POST может понадобиться, если на сервер надо передать большой объём данных (у GET он сильно ограничен), а так же, если не следует «светить» передаваемые данные в адресной строке (при вводе логина и пароля, например).
В любом случае, после обработки POST надо всегда перенаправить браузер на какую-нибудь страницу, пусть ту же самую, но уже без данных формы, чтобы при обновлении страницы они не записывались повторно.
Как передать данные в другой файл непосредственно из тела PHP-программы методом GET и POST?
Пример, для демонстрации отправки данных методом POST и GET одновременно и получения ответа от сервера.
fclose($fp); > ?>
В этом примере файл file.php получил переменные:
GET var=»23″ и var2=»54″
POST var3=»test» и var4=»еще тест»
Внимание, данные передаваемые через POST или GET всегда передаются строкой (string), независимо от того, через форму они передаются или через скрипт. Поэтому передавая число, помните, что в скрипт оно попадет как string.
Как перейти на другую страницу сайта из тела программы?
На новую страницу
На предыдущую с обновлением:
Через генерацию JavaScript-кода:
На предыдущую с обновлением:
echo "\n";
На предыдущую без обновления:
echo "\n";
Перезагрузить текущую страницу:
echo "\n";
Через PHP-функцию:
header("Location: http://”.$url); exit;
На предыдущую страницу с обновлением:
header("Location: ".$_SERVER['HTTP_REFERER']); exit;
На текущую страницу с обновлением и генерацией полного url-адреса:
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); exit;
Самое главное, что надо помнить: сервер по своей инициативе обратиться к клиенту не может. Мы можем только по факту запроса выдать что-то браузеру — либо страницу, либо команду запросить другой ресурс.
ПРИМЕРЫ НЕОБЫЧНОГО ИСПОЛЬЗОВАНИЯ ФОРМ
Эти примеры показывают, что PHP-программу обработки ввода можно отделить от HTML-текста можно расположить на одной странице.
Пример 1. Задание номера карточки.
Пример обработки ввода ' method='post'>Номер карточки:
Здесь отсутствует кнопка передачи данных, т.к. форма, состоящая из одного поля, передается автоматически при нажатии клавиши Enter.
Пример 2. Навигация по массиву (списку) по средством формы.
break; case 'next': if($index != $last) <$index++;>break; case 'last': $index = $last; break; >; echo 'Выбран элемент['.$index.'] = '.$array[$index].''; switch ($index) < case $first: echo ' lt;font color=red>(первый)'; break; case $last: echo ' (последний)'; break; >; ?>
В этом примере осуществляется перемещение по списку (массиву) элементов с отражением его номера (ключа) и значения элемента в массиве с помощью кнопок и скрытой строки с передачей навигационного параметра.
ПРОВЕРКА КОРРЕКТНОСТИ ДАННЫХ ИЛИ ДОПУСТИМОСТИ ВВОДИМЫХ ДАННЫХ
На любом современном сайте используются всевозможные HTML-формы, которые пользователь должен заполнить и отправить данные на сервер. Это может быть гостевая книга, форум, форма обратной связи, подписка на рассылку и т.д.
Данные, вводимые пользователем в форму и отправляемые в файл-обработчик, необходимо проверять на корректность. Причем проверке корректности данных, вводимых пользователем необходимо уделять достаточно большое внимание, поскольку необработанные ошибки, возникающие при вводе неправильном вводе данных, приводят к ошибкам в работе скрипта, зачастую катастрофическим. Предположим, вы создаете форму для отправки пользователем письма, при этом адрес электронной почты необходимо вводить пользователю. В этом случае, для корректной работы программы вы должны сделать, по крайней мере, две вещи:
• Проверить, что поле, в которое заносится электронный адрес непустое (поскольку пользователь может просто забыть ввести адрес, и, если этот случай необработан, возникнет ошибочная ситуация);
• Проверить соответствие введенного адреса с помощью регулярного выражения.
Email обязательно должен содержать символ @, быть по длине не менее 8 символов, есть также регулярное выражение, по которому можно проверить данные на предмет соответствия адресу электронной почты.
Встает вопрос, как проинформировать пользователя о том, что он неправильно ввел данные? Один из вариантов решения этой проблемы — через сессионные переменные.
Пусть есть страница form.php, на которой расположена наша форма, и есть файл send.php, который является обработчиком данных формы в файле form.php.
В обоих файлах должна быть запущена сессия функцией session_start() в начале сценария до отправки заголовков документа.
Пусть отправляется переменная email методом POST в файле send.php, то делаем:
1. Проверку на длину:
if(strlen($_POST[«email»])
2. Проверку корректности адреса электронной почты
Такая проверка осуществляется зачастую с помощью регулярных выражений. Как известно, у адреса две составляющие — имя пользователя и имя домена, которые разделены знаком @. В имени пользователя могут присутствовать заглавные и прописные буквы цифры, знаки подчеркивания и минуса, точки. Для проверки разделителя между именем пользователя и именем домена в выражение требуется добавить +@.
Также не забывайте, что электронный ящик может находиться на поддомене xxx@xxx.xxx.com, или даже на домене четвертого, пятого уровня (как вариант, реально эта ситуация крайне редка, но отбрасывать эти адреса не стоит). Поэтому в регулярном выражении не забывайте использовать точку (экранированную «\.«) для указания того, что часть адреса после «@» может содержать точку как разделитель доменных имен.
Таким образом, регулярное выражение, проверяющее имя пользователя и наличие разделителя имеет следующий вид:
"/^[-A-Za-z0-9_\.]+@[-A-Za-z0-9^\.]
Для проверки доменного имени первого уровня учитываем, что его длина уже составляет не только 2 символа (.ru) или 3 символа (.com), но и 4 символа — .info, и даже 6 символов. Поэтому добавляем такое выражение:
Объединяя эти шаги, получаем следующее регулярное выражение для проверки адресов электронной почты:
"/^[-A-Za-z0-9_\.]+@[-A-Za-z0-9^\.]+\.[a-z]$/i"
Проверка осуществляется по этому шаблону с применением функции preg_match():
function check_email ($email) // Проверка корректности адреса e-mail < if(!preg_match('|^[-0-9A-Za-z_\.]+@[-0-9A-Za-z^\.]+\.[a-z]$|i',$email)) < return false; >return true; >
Эта пользовательская функция check_email возвращает true, если переданное значение переменной $email соответствует шаблону и false в противном случае.
В итоге проверка на корректность будет выглядеть так:
if(!check_email ($_POST[«email»]))
Соответственно в файле form.php перед формой прописываем следующее:
if(!empty($_SESSION["error"])) < $error=$_SESSION["error"]; unset($_SESSION["error"]); >else < $error=""; >echo $error;
Соответственно, если ошибка была, то она будет напечатана пользователю перед формой. Таким же методом можно сохранять данные в заполненных полях формы, чтобы пользователь по несколько раз не вводил одно и то же.
ДРУГИЕ ПРОВЕРКИ НА КОРРЕКТНОСТЬ ВВЕДЕННЫХ ДАННЫХ
Каждый web-мастер должен уметь не только писать скрипты, но и грамотно организовывать защиту своих творений. Одним из важнейших навыков является умение правильно фильтровать всю информацию, поступающую от пользователя.
Кроме чистых ошибок пользователя, необходимо также исключить ситуации, в которых возможно злонамеренное введение некорректных данных, к примеру, различных скриптов. Для этого вводимый пользователем текст необходимо обработать функциями удаления HTML-тегов (для исключения возможности написания скриптов на JavaScript и Visual Basic) и обратных слешей (для исключения возможности написания скриптов на Perl). Т. о. минимальный набор действий, необходимый для проверки корректности данных, вводимых пользователем, включает следующие этапы:
• проверка того, что пользователь ввел данные
• проверка допустимости вводимых пользователем данных (как правило, осуществляется при помощи регулярных выражений)
• обработка текста, введенного пользователем функцией htmlspecialchars для удаления HTML-тегов
• обработка текста, введенного пользователем функцией stripslashes для удаления обратных слешей
ФИЛЬТРАЦИЯ ДАННЫХ
Прежде всего, следует фильтровать данные, которые передает пользователь осознанно — в основном, это данные различных форм. Это может быть пара логин-пароль для входа, пункт голосования и т.п. Например, такая форма
После нажатия кнопки «OK» передаст скрипту index.php два значения — $login и $pass. Как их можно отфильтровать? Пример для переменной $login:
Вводимый пользователем текст необходимо обработать функциями удаления HTML-тегов (для исключения возможности написания скриптов на JavaScript и Visual Basic) и обратных слешей (для исключения возможности написания скриптов на Perl). К примеру, если переменная $login содержит текст с именем пользователя, то обработка этого текста выглядит так:
if($login) < $login = htmlspecialchars((stripslashes($login)), ENT_QUOTES); $login = str_replace("/","",$login); $login = str_replace(".","",$login); $login = str_replace("`","",$login); >else
В первой строке мы проверяем существование переменной $login, если она существует — идем дальше, если нет — выводим сообщение об ошибке. Затем с помощью функции htmlspecialchars заменяем в этой переменной спецсимволы на их HTML-мнемоники. Функция stripslashes вырезает знак обратного слеша ‘\‘. Далее с помощью str_replace вырезаем знак прямого слеша, точку (иногда бывает полезно) и обратную кавычку.
Если вы знакомы с регулярными выражениями, то предыдущий пример можно записать гораздо короче:
if($login) < if (preg_match("/[0-9a-z_]/i", $login)) < /* … действия над логином … */>else < echo "Логин введен неверно!"; >> else
Этот фрагмент кода будет проверять введенный логин на соответствие регулярному выражению ‘/[0-9a-z_]/i‘, которое означает: все цифры + все латинские буквы в любом регистре + знак подчеркивания. Если логин содержит другие символы, то будет показано сообщение об ошибке.
Аналогично фильтруются переменные, получаемые скриптом через URL. В движках сайтов можно встретить что-то вроде таких ссылок:
http://www.site.com/index.php?module=news
Если не фильтровать переменную $module (или $_GET[`module`], если register_globals отключен), то над сайтом могут вытворяться не очень хорошие вещи, вроде XSS. Нужно применять первый приведенный мной скрипт-чистильщик, разумеется, убрав сообщения об ошибках.
ПРОВЕРКА НА ПУСТОТУ ПОЛЯ
Проверка того, что пользователь ввел данные, может осуществляться, к примеру, с помощью функции isset:
Вы забыли ввести ваше имя
else < … >?>
Для этой же цели можно использовать функцию empty:
Вы забыли ввести ваше имя else < … >?>
На практике удобно сначала проверить, не пустой ли action формы, а потом уже проверять различные его составляющие: поле имя, e-mail и т. д. К примеру:
if (!empty($email)) < // код, для случая, когда не введен e-mail >// дальнейший код скрипта > if (empty($action)) < ?> ?>
ТАБЛИЦА СРАВНЕНИЯ ТИПОВ В PHP
Следующая таблица демонстрируют работу PHP с типами переменных и операторами сравнения, как в случае свободного, так и в случае строгого сравнения. Также эта информация относится к разделу документации по приведению типов.
Замечание: HTML-формы не передают тип переменной: они всегда передают строки. Для проверки является ли строка числом, используйте функцию is_numeric().
Замечание: Использование if ($x) пока $x не определена сгенерирует ошибку E_NOTICE. Вместо этого используйте функцию empty() или isset() и/или инициализируйте переменную.