Обработка запросов с помощью php

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

Внутри PHP-скрипта имеется несколько способов получения доступа к данным, переданным клиентом по протоколу HTTP. До версии PHP 4.1.0 доступ к таким данным осуществлялся по именам переданных переменных (напомним, что данные передаются в виде пар "имя переменной, символ "=", значение переменной"). Таким образом, если, например, было передано first_name=Nina, то внутри скрипта появлялась переменная $first_name со значением Nina. Если требовалось различать, каким методом были переданы данные, то использовались ассоциативные массивы $HTTP_POST_VARS и $HTTP_GET_VARS , ключами которых являлись имена переданных переменных, а значениями – соответственно значения этих переменных. Таким образом, если пара first_name = Nina передана методом GET , то $HTTP_GET_VARS["first_name"]="Nina".

Использовать в программе имена переданных переменных напрямую небезопасно. Поэтому было решено начиная с PHP 4.1.0 задействовать для обращения к переменным, переданным с помощью HTTP-запросов, специальный массив – $_REQUEST . Этот массив содержит данные, переданные методами POST и GET , а также с помощью HTTP cookies. Это суперглобальный ассоциативный массив, т.е. его значения можно получить в любом месте программы, используя в качестве ключа имя соответствующей переменной (элемента формы).

Пример 4.2. Допустим, мы создали форму для регистрации участников заочной школы программирования, как в приведенном выше примере. Тогда в файле 1.php, обрабатывающем эту форму, можно написать следующее:

<?php$str = "Здравствуйте, ".$_REQUEST["first_name"]. " ".$_REQUEST["last_name"]."! <br>";$str .="Вы выбрали для изучения курс по ".$_REQUEST["kurs"];echo $str;?>

Пример 4.2. Файл 1.php, обрабатывающий форму form.html

Тогда, если в форму мы ввели имя "Вася", фамилию "Петров" и выбрали среди всех курсов курс по PHP, на экране браузера получим такое сообщение:

Здравствуйте, Вася Петров! Вы выбрали для изучения курс по PHP

После введения массива $_REQUEST массивы $HTTP_POST_VARS и $HTTP_GET_VARS для однородности были переименованы в $_POST и $_GET соответственно, но сами они из обихода не исчезли из соображений совместимости с предыдущими версиями PHP. В отличие от своих предшественников, массивы $_POST и $_GET стали суперглобальными, т.е. доступными напрямую и внутри функций и методов.

Приведем пример использования этих массивов. Допустим, нам нужно обработать форму, содержащую элементы ввода с именами first_name, last_name, kurs (например, форму form.html, приведенную выше). Данные были переданы методом POST , и данные, переданные другими методами, мы обрабатывать не хотим. Это можно сделать следующим образом:

<?php$str = "Здравствуйте, ".$_POST ["first_name"]." ".$_POST ["last_name"] ."! <br>";$str .= "Вы выбрали для изучения курс по ". $_POST["kurs"];echo $str;?>

Тогда на экране браузера, если мы ввели имя "Вася", фамилию "Петров" и выбрали среди всех курсов курс по PHP, увидим сообщение, как в предыдущем примере:

Здравствуйте, Вася Петров! Вы выбрали для изучения курс по PHP

Для того, чтобы сохранить возможность обработки скриптов более ранних версий, чем PHP 4.1.0, была введена директива register_globals , разрешающая или запрещающая доступ к переменным непосредственно по их именам. Если в файле настроек PHP параметр register_globals=On, то к переменным, переданным серверу методами GET и POST , можно обращаться просто по их именам (т.е. можно писать $first_name ). Если же register_globals=Off, то нужно писать $_REQUEST["first_name"] или $_POST["first_name"], $_GET["first_name"], $HTTP_POST_VARS["first_name"], $HTTP_GET_VARS["first_name"]. С точки зрения безопасности эту директиву лучше отключать (т.е. register_globals=Off ). При включенной директиве register_globals перечисленные выше массивы также будут содержать данные, переданные клиентом.

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



<?echo getenv('REQUEST_METHOD'); // возвратит использованный методecho getenv ('REMOTE_ADDR'); // выведет IP-адрес пользователя, // пославшего запрос?>

Пример 4.3. Использование функции getenv()

Как мы уже говорили, если используется метод GET , то данные передаются добавлением строки запроса в виде пар "имя_переменной=значение к URL -адресу ресурса". Все, что записано в URL после знака вопроса, можно получить с помощью команды

getenv('QUERY_STRING');

Благодаря этому можно по методу GET передавать данные в каком-нибудь другом виде. Например, указывать только значения нескольких параметров через знак плюс, а в скрипте разбирать строку запроса на части или можно передавать значение всего одного параметра. В этом случае в массиве $_GET появится пустой элемент с ключом, равным этому значению (всей строке запроса), причем символ " + ", встретившийся в строке запроса, будет заменен на подчеркивание " _ ".

Методом POST данные передаются только с помощью форм, и пользователь ( клиент ) не видит, какие именно данные отправляются серверу. Чтобы их увидеть, хакер должен подменить нашу форму своей. Тогда сервер отправит результаты обработки неправильной формы не туда, куда нужно. Чтобы этого избежать, можно проверять адрес страницы, с которой были посланы данные. Это можно сделать опять же с помощью функции getenv() :

getenv('HTTP_REFERER');

Пример обработки запроса с помощью PHP

Нужно написать форму для регистрации участников заочной школы программирования и после регистрации отправить участнику сообщение. Мы назвали это сообщение универсальным письмом, но оно будет немного отличаться от того письма, которое мы составили на предыдущей лекции. Здесь мы также не будем отправлять что-либо по электронной почте, дабы не уподобляться спамерам, а просто сгенерируем это сообщение и выведем его на экран браузера. Начальный вариант формы регистрации мы уже приводили выше. Изменим его таким образом, чтобы каждый регистрирующийся мог выбрать сколько угодно курсов для посещения, и не будем подтверждать получение регистрационной формы.

<h2>Форма для регистрации студентов</h2><form action="1.php" method=POST>Имя <br><input type=text name="first_name" value="Введите Ваше имя"><br>Фамилия <br><input type=text name="last_name"><br>E-mail <br><input type=text name="email"><br><p> Выберите курс, который вы бы хотели посещать:<br><input type=checkbox name='kurs[]' value='PHP'>PHP<br><input type=checkbox name='kurs[]' value='Lisp'>Lisp<br><input type=checkbox name='kurs[]' value='Perl'>Perl<br><input type=checkbox name='kurs[]' value='Unix'>Unix<br><P>Что вы хотите, чтобы мы знали о вас? <BR><textarea name="comment" cols=32 rows=5></textarea><input type=submit value="Отправить"><input type=reset value="Отменить"></form>

Листинг 4.4. form_final.html

Здесь все достаточно просто и понятно. Единственное, что можно отметить, – это способ передачи значений элемента checkbox. Когда мы пишем в имени элемента kurs[], это значит, что первый отмеченный элемент checkbox будет записан в первый элемент массива kurs, второй отмеченный checkbox – во второй элемент массива и т.д. Можно, конечно, просто дать разные имена элементам checkbox, но это усложнит обработку данных, если курсов будет много.

Скрипт, который все это будет разбирать и обрабатывать, называется 1.php (форма ссылается именно на этот файл, что записано в ее атрибуте action ). По умолчанию используется для передачи метод GET , но мы указали POST . По полученным сведениям от зарегистрировавшегося человека, скрипт генерирует соответствующее сообщение. Если человек выбрал какие-то курсы, то ему выводится сообщение о времени их проведения и о лекторах, которые их читают. Если человек ничего не выбрал, то выводится сообщение о следующем собрании заочной школы программистов (ЗШП).

<?// создадим массивы соответствий курс-время его // проведения и курс-его лектор$times = array("PHP"=>"14.30","Lisp"=>"12.00", "Perl"=>"15.00","Unix"=>"14.00");$lectors = array("PHP"=>"Василий Васильевич", "Lisp"=>"Иван Иванович", "Perl"=>"Петр Петрович", "Unix"=>"Семен Семенович");define("SIGN","С уважением, администрация"); // определяем подпись письма как константуdefine("MEETING_TIME","18.00"); // задаем время собрания студентов$date = "12 мая"; // задаем дату проведения лекций //начинаем составлять текст сообщения$str = "Здравствуйте, уважаемый " . $_POST["first_name"] . " " . $_POST["last_name"]."!<br>";$str .= "<br>Сообщаем Вам, что ";$kurses = $_POST["kurs"]; // сохраним в этой переменной // список выбранных курсовif (!isset($kurses)) { // если не выбран ни один курс $event = "следующее собрание студентов"; $str .= "$event состоится $date ". MEETING_TIME . "<br>";} else { // если хотя бы один курс выбран $event = "выбранные Вами лекции состоятся $date <ul>"; //функция count вычисляет число элементов в массиве $lect = ""; for ($i=0;$i<count($kurses);$i++){ // для каждого выбранного курса $k = $kurses[$i]; // запоминаем название курса $lect = $lect . "<li>лекция по $k в $times[$k]"; // составляем сообщение $lect .= " (Ваш лектор, $lectors[$k])"; } $event = $event . $lect . "</ul>"; $str .= "$event";}$str .= "<br>". SIGN; // добавляем подписьecho $str; // выводим сообщение на экран?>

Листинг 4.5. Скрипт 1.php, обрабатывающий форму form_final.html

PHP. Лекция 5

Наши рекомендации