Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
119
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

462 Глава 11

Выпадающий список для выбора позиции создается на лету из значений, записан+ ных в массив $position_array, который создается в начале функции:

for($i=0; $i < count($position_array); $i++) { if(!isset($userposition) && $i == 0) {

echo "<OPTION SELECTED VALUE=\"". $position_array[$i] . "\">" . $position_array[$i] . "</OPTION>\n";

}else if($userposition == $cposition_array[$i]) {

echo "<OPTION SELECTED VALUE=\"". $position_array[$i] . "\">" . $position_array[$i] . "</OPTION>\n";

}else{

echo "<OPTION VALUE=\"". $position_array[$i] . "\">" . $position_array[$i] . "</OPTION>\n";

}

}

?>

Далее выводятся другие поля формы:

</select></td>

</tr>

<tr>

<th width="30%" nowrap>Email</th>

<td width="70%"><input type="text" name="useremail" size="20" </td>

</tr>

<tr>

<th width="30%" nowrap>Профиль</th>

<td WIDTH="70%"><textarea rows="5" cols="40" name="userprofile"></textarea></tr>

</tr>

<tr>

<th width="30%" colspan="2" nowrap> <input type="submit" value="Отправить">

<input type="reset" value="Очистить"></th> </tr>

</table>

</center></div>

</form>

<?php

}

Функция create_account()

Функция create_account() вставляет новую запись в таблицу user. Эта функция может быть вызвана только в случае, если была нажата кнопка Отправить, созданная в функции register_form(). В результате массив $_POST будет заполнен значения+ ми, которые затем можно будет использовать:

function create_account() { $userid = $_POST['userid']; $username = $_POST['username'];

$userpassword = $_POST['userpassword']; $userpassword2 = $_POST['userpassword2']; $userposition = $_POST['userposition']; $useremail = $_POST['useremail']; $userprofile = $_POST['userprofile'];

global $default_dbname, $user_tablename;

Использование PHP для управления информацией в базах данных MySQL 463

Введенные пользователем значения проверяются:

if(empty($userid)){

error_message("Введите желаемый идентификатор!");

}

if(empty($userpassword)){ error_message("Введите желаемый пароль!");

}

if(strlen($userpassword) < 4 ){ error_message("Короткий пароль!");

}

if(empty($userpassword2)) {

error_message("Введите пароль снова для проверки!");

}

if(empty($username)){

error_message("Введите свое полное имя!");

}

if(empty($useremail)){

error_message("Введите свой e-mail-адрес!");

}

if(empty($userprofile)){ $userprofile = "Введите профиль.";

}

if($userpassword != $userpassword2){

error_message("Повторно введенный пароль не совпадает с первоначально введенным!");

}

Затем создается подключение к базе данных и вызывается функция in_use() для проверки уникальности введенного пользователем идентификатора (так как иденти+ фикатор используется в качестве первичного ключа):

$link_id = db_connect($default_dbname);

if(in_use($userid)){

error_message("Идентификатор $userid уже используется. Пожалуйста, выберите другой идентификатор.");

}

При вставке данных нового пользователя в поле usernumber передается NULL, чтобы увеличить последнее значение в этом поле на 1. Кроме того, используется сер+ верная функция password() для шифрования введенного пользователем пароля:

$query = "INSERT INTO user VALUES(NULL, '$userid', password('$userpassword'), '$username', '$userposition', '$useremail', '$userprofile')";

$result = mysql_query($query); if(!$result){

error_message(sql_error());

}

С помощью функции mysql_insert_id() определяется только что созданный номер пользователя:

$usernumber = mysql_insert_id($link_id); html_header();

?>

После этого выводится HTML+таблица, содержащая регистрационную информа+ цию пользователя:

464 Глава 11

<center><h3>

Создана учетная запись для пользователя <?php echo $username ?> </h3></center>

<div align="center"><center><table border="1" width="90%">

<tr>

<th width="30%" nowrap>Номер пользователя</TH> <td width="70%"><?php echo $usernumber ?></td>

</tr>

<tr>

<th width="30%" nowrap>Идентификатор</th> <td width="70%"><?php echo $userid ?></td>

</tr>

<tr>

<th width="30%" nowrap>Пароль</th>

<td width="70%"><?php echo $userpassword ?></td> </tr>

<tr>

<th width="30%" nowrap>Полное имя</th>

<td width="70%"><?php echo $username ?></td> </tr>

<tr>

<th width="30%" nowrap>Позиция</th>

<td width="70%"><?php echo $userposition ?></td> </tr>

<tr>

<th width="30%" nowrap>E-mail</th>

<td width="70%"><?php echo $useremail ?></td> </tr>

<tr>

<th width="30%" nowrap>Профиль</th>

<td width="70%"><?php echo htmlspecialchars($userprofile) ?></td> </tr>

</table>

</center></div>

<?php html_footer();

}

Выбор следующего действия

Наконец используется параметр action для определения того, какую функцию необходимо вызвать. В случае если массив $_POST не заполнен, параметру action следует присвоить значение по умолчанию, которое приводит к вызову функции registеr_form():

if (empty($_POST)){ $_POST['action'] = "";

}

switch($_POST['action']) {

case "register": create_account(); break;

default: html_header(); register_form(); html_footer();

break;

}

?>

Использование PHP для управления информацией в базах данных MySQL 465

Рассмотрим работу данного сценария в действии. Сначала функция register_form() выводит HTML+форму (рис. 11.7), в которую пользователь вводит свои данные.

Рис. 11.7.

Затем пользователь может ввести свои данные, если сочтет нужным. На последнем этапе сценарий отображает сообщение о создании учетной записи и таблицу, в кото+ рой показана введенная пользователем информация, использованная для создания учетной записи. На рис. 11.8 показана страница с сообщением о создании учетной за+ писи для пользователя Darren.

Следует признать, что отображение пароля после создания учетной записи ++++++ не очень хорошая идея. Относительно безопасный способ подтвердить данную инфор+ мацию ++++++ включить ее в e+mail+сообщение, которое отправляется пользователю, соз+ давшему учетную запись.

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

Теперь рассмотрим протоколирование пользовательской активности на сайте.

466 Глава 11

Рис. 11.8.

Создание сценария для протоколирования посещений страниц

Чтобы отслеживать активность пользователей на сайте, нужно знать, кто сделал тот или иной запрос. Для этого пользователей необходимо регистрировать. Регист+ рация дает возможность идентифицировать пользователей, запрашивающих какие+ либо Web+страницы.

Самый удобный способ аутентификации пользователей заключается в том, чтобы присвоить каждому пользователю уникальный идентификатор и пароль. Когда поль+ зователь входит в защищенную паролем область сайта, все что нужно сделать, это сверить введенные пользователем значения (имя пользователя и пароль) со значе+ ниями, хранящимися в базе данных.

Следующий сценарий для аутентификации пользователя выполняет запрос к таб+ лице user. Код начинается с подключения файла common_db.inc и создания ссылки на страницу регистрации:

<?php

include_once "./common_db.inc"; $register_script = "./register.php";

Использование PHP для управления информацией в базах данных MySQL 467

Файл auth_user.php

Затем определяются функции auth_user()и login_form(), которые рассмат+ риваются позднее, но основная часть сценария начинается с вызова функции session_start(). Необходимо сохранить введенные пользователем значения иден+ тификатора и пароля, а также переменные сеанса, чтобы избавить пользователя от необходимости заново вводить эти значения каждый раз при посещении других страниц сайта.

Если переменная $_POST['userid'] не была проинициализирована, то вызыва+ ется функция login_form(), отображающая форму входа на сайт, в которую пользо+ ватель может ввести свой идентификатор и пароль:

if(!isset($_POST['userid'])) { login_form();

exit;

Если переменная $userid определена (а это возможно в том случае, когда сцена+ рий был вызван из формы входа), то переданные пользователем значения для иден+ тификатора (в HTML+форме поле userid) и пароля (userpassword) регистрируют+ ся как переменные сеанса для дальнейшего использования и передаются в качестве аргументов функции auth_user():

}else{ session_start();

session_register("userid", "userpassword");

$username = auth_user($_POST['userid'], $_POST['userpassword']);

Функция auth_user() может возвращать одно из двух значений:

имя пользователя, которое хранится в таблице user; оно возвращается, только если переданные значения идентификатора и пароля совпадают со значения+ ми, сохраненными в определенной записи таблицы;

если совпадение не найдено, то функция возвращает 0.

Возвращенное функцией auth_user() значение сохраняется в переменной $username и используется для формирования ответа:

if(!$username) {

$PHP_SELF = $_SERVER['PHP_SELF']; session_unregister("userid");

session_unregister("userpassword"); echo "Попытка авторизации неудачна. " .

"Вы должны ввести правильный идентификатор пользователя и пароль. " . "Чтобы попытаться снова, щелкните следующую ссылку.<BR>\n";

echo "<A HREF=\"$PHP_SELF\">Вход в систему</A><BR>";

echo "Если Вы еще не зарегистрированы, для регистрации щелкните следующую ссылку." .

"<BR>\n";

echo "<A HREF=\"$register_script\">Зарегистрироваться</A>"; exit;

}else{

echo "Добро пожаловать, $username!";

}

 

}

 

Если попытка аутентификации оказалась неудачной, необходимо разрегистрировать переменные сеанса, и гарантировать, таким образом, что в случае, когда неавторизо+ ванный пользователь попытается войти в защищенную паролем область сайта, будет

468 Глава 11

вызвана функция login_form(). Функция login_form() представляет собой HTML+ таблицу, которая позволяет пользователю ввести идентификатор и пароль, чтобы впоследствии эти значения можно было использовать в функции auth_user():

function login_form() { global $PHP_SELF;

?>

<html>

<head>

<title>Вход в систему</title> </head>

<body>

<form method="post" action="<?php echo "$PHP_SELF"; ?>">

<div align="center"><center>

<h3>Для просмотра запрашиваемой страницы необходимо зарегистрироваться.</h3>

<table border="1" width="200" cellpadding="2">

<tr>

<th width="18%" align="right" nowrap>Идентификатор</th> <td width="82%" nowrap>

<input type="text" name="userid" size="8"> </td>

</tr>

<tr>

<th width="18%" align="right" nowrap>Пароль</th> <td width="82%" nowrap>

<input type="password" name="userpassword" size="8"> </td>

</tr>

<tr>

<td width="100%" colspan="2" align="center" nowrap> <input type="submit" value="Отправить" name="login">

</td>

</tr>

</table>

</center></div>

</form>

</body>

</html>

<?

}

Основа сценария находится в функции auth_user(), которая принимает два ар+ гумента ++++++ переменные $userid и $userpassword ++++++ и сверяет их значения со зна+ чениями, сохраненными в таблице user:

function auth_user($userid, $userpassword)

{

global $default_dbname, $user_tablename;

$link_id = db_connect($default_dbname);

После подключения к базе данных выбирается запись, в которой значения полей userid и password соответствуют значениям, введенным пользователем, и извлека+ ется значение поля username этой записи:

$query = "SELECT username FROM $user_tablename WHERE userid = '$userid' AND userpassword = password('$userpassword')";

$result = mysql_query($query);

Использование PHP для управления информацией в базах данных MySQL 469

Если ни в одной из записей нет обоих совпадающих критериев, то возвращается 0; в противном случае выбирается и возвращается имя пользователя:

if(!mysql_num_rows($result)){ return 0;

}else{

$query_data = mysql_fetch_row($result); return $query_data[0];

}

}

Необходимо удостовериться, что значение $userpassword зашифровано до срав+ нения со значением в таблице user, для того чтобы сравнивать два зашифрованных значения, возвращенных одним и тем же процессом, и, следовательно, идентичных. Не все типы шифрования позволяют это сделать, но алгоритм шифрования в MySQL является односторонним. Иначе говоря, две идентичных строки при данном алго+ ритме всегда дают две идентично зашифрованные строки.

На рис. 11.9 показано, как должен выглядеть интерфейс.

Рис. 11.9.

Когда пользователь успешно входит в систему, появляется приветствие (рис. 11.10).

Файл access_logger.php

Последний сценарий можно улучшить так, чтобы он авторизовал пользователей и про+ токолировал их визиты на Web+страницы сайта. Назовем эту модифицированную версию access_logger.php. Регистрировать посещения страниц следует путем автоматического подключения файла access_logger.php в начало всех Web+страниц сайта. Это можно сделать очень просто: установив параметр auto_prepend_file в конфигурационном файле php.ini равным абсолютному пути к данному сценарию. Например:

auto_prepend_file = /home/james/access_logger.php

470 Глава 11

Рис. 11.10.

Другой вариант состоит в подключении протоколирующего сценария в начало ка+ ждой Web+страницы, находящейся в защищенной паролем области сайта. Сценарий должен подключаться в начале каждой страницы, до отправки каких+либо HTML+ тегов или текста, в противном случае функция header() не будет работать.

Предположим, что используется первый подход, и для подключения сценария ко всем .php+страницам на сервере устанавливается параметр auto_prepend_file. Чтобы исключить в таком случае некоторые файлы и каталоги из процесса аутенти+ фикации, можно перечислить их соответственно в двух массивах. Когда пользователь пытается зайти на какую+либо страницу, сценарий протоколирования может сверять имя страницы и путь к ней с элементами массивов и требовать аутентификации толь+ ко в том случае, если совпадений не найдено.

Начнем с подключения файла common_db.inc и определения массивов исключе+ ний и имен таблиц:

<?php

require_once ('common_db.inc'); $exclude_dirs = array('/info', '/contact');

$exclude_files = array('index.html', 'info.html', 'register.php'); $user_tablename = 'user';

$access_log_tablename = 'access_log'; $PHP_SELF = $_SERVER['PHP_SELF'];

Когда пользователь регистрируется на сайте, можно начать сеанс и зарегистриро+ вать в качестве переменной сеанса идентификатор этого пользователя. Впоследствии идентификатор и пароль пользователя будут использоваться в функции do_authenticate(). При первой инициализации сеанса и регистрации его пере+ менных переменные для имени пользователя и пароля не содержат значений, поэто+ му необходимо проверить, записана ли страница в список исключений. Если страница в списке исключений не значится, то вызывается функция do_authenticate():

session_start(); session_register('userid', 'userpassword'); if (!$_SESSION['userid']){

Использование PHP для управления информацией в базах данных MySQL 471

$filepath = dirname($_SERVER['SCRIPT_FILENAME']); $filename = basename($_SERVER['SCRIPT_FILENAME']); if($filepath == "){

$filepath = '/';

}

$auth_done = 0;

for($j=0; $j < count($exclude_dirs); $j++) { if($exclude_dirs[$j] == $filepath){

break;

}else{

for($i=0; $i< count($exclude_files); $i++) { if($exclude_files[$i] == $filename){

break;

}

if ($i == (count($exclude_files) - 1)){ do_authentication();

$auth_done = 1; break;

}

}

}

if($auth_done){ break;

}

}

}

?>

Рассмотрим отслеживание посещений страниц пользователем, который уже заре+ гистрировался на сайте и передал свой идентификатор и пароль. Снова вызывать функцию do_authenticate(), конечно, нежелательно. Однако известно, что если пользователь успешно зарегистрировался на сайте, то переменные сеанса, в которых хранится идентификатор и пароль пользователя, проинициализированы, поэтому можно использовать следующий код:

if ($_SESSION['userid'] && $_SESSION['userpassword']){ $userid = $_SESSION['userid'];

$filename = basename($_SERVER['SCRIPT_FILENAME']); $link_id = db_connect($default_dbname);

$query = "SELECT userid FROM $access_log_tablename WHERE page = '$filename' AND userid = '$userid'"; $result = mysql_query($query);

if(!mysql_num_rows($result)){

$query = "INSERT INTO $access_log_tablename VALUES ('$filename', '$userid', 1, NULL)";

}else{

$query = "UPDATE $access_log_tablename

SET visitcount = visitcount + 1, accessdate = NULL WHERE page = '$filename' AND userid = '$userid'";

}

mysql_query($query);

$num_rows = mysql_affected_rows($link_id); if($num_rows != 1){

die(sql_error());

}

}

Соседние файлы в папке web - tec