Сейчас мы применим полученные знания для создания собственного web -сервиса.

7.1. Постановка задачи

Необходимо создать сервис «Интернет-словарь», в котором зарегистрированные ученики могут добавлять новые термины и свою интерпретацию их, преподаватель может просматривать добавленные определения, высказывать свое, отношение, замечания, а также получать статистическую информацию, сколько терминов добавил каждый ученик. Данный сервис можно использовать для повторения изученной темы по любому предмету. Создание такого web -сервиса может стать одним из итоговых проектов, поэтому мы не будем приводить последовательность шагов по созданию такого проекта, а рассмотрим лишь основные идеи.

Структура сервиса изображена на рисунке 12.

Структура web -сервиса
Рисунок 12. Структура web -сервиса.

7.2. Создание базы данных

Нам потребуется база данных, имеющая следующую структуру (рисунок 13):

Структура базы данных
Рисунок 13. Структура базы данных.

Она состоит из трех связанных таблиц. На рисунке приведены отношения между таблицами. Так между таблицами «ученики» и «термины» связь «один ко многим», это означает, что один и тот же ученик может создать несколько терминов. Давайте рассмотрим, какие поля содержит каждая таблица, Не забывайте, что имена полей и названия таблиц не должны содержать кириллические символы.

Таблица «student» (на рисунке она называется «ученики», содержит информацию об участниках проекта).

поле

тип

комментарий

id_student

int

это – уникальное поле, идентификатор, при его создании необходимо назначать параметр, auto _ increment .

student_name

varchar(20)

фамилия имя участника проекта

student_login

varchar(20)

логин ученика

student_pass

varchar(20)

пароль

student_email

varchar(20)

электронный адрес

student_admin

int

идентификатор администратора. Все пользователи проекта хранятся в одной таблице. У учеников в этом поле хранится ноль, у учителей единица.

Ниже приведен пример SQL -запроса для создания таблицы с заданной структурой:

Листинг № 24

CREATE TABLE students (  id_student int(11) NOT NULL auto_increment,
student_name varchar(20) NOT NULL default '',
student_login varchar(20) NOT NULL default '',
student_password varchar(20) NOT NULL default '',
student_e_mail varchar(20) default NULL,
student_admin int default NULL, 
PRIMARY KEY (id_student));

SQL -запросы для создания трех других таблиц, вы сможете создать самостоятельно.

Таблица «dict» (на рисунке, «термины», в таблице хранятся все термины из всех словарей).

поле

тип

комментарий

id_dict

int

идентификатор термина, при его создании необходимо назначать параметр, auto _ increment .

dict_name

varchar(20)

название термина

dict_article

text

описание термина, так как размер описания может быть достаточно большой, мы используем тип text

dict_date

date

дата создания термина

dict_student

int(11)

связь с таблицей «student». В таблице хранится идентификатор ученика, записавшего данный термин.

Таблица «сomment» (на рисунке, «комментарии», в таблице хранятся все комментарии ко всем терминам).

поле

тип

комментарий

id_сomment

int

идентификатор термина, при его создании необходимо назначать параметр, auto _ increment .

сomment_name

varchar(20)

название термина

сomment_dict

int(11)

связь с таблицей «dict». Так как связь осуществляется через идентификатор таблицы, то тип данного поля обязательно должен быть числовым.

сomment_сomment

text

сам комментарий, так как размер описания может быть достаточно большой, мы используем тип text

сomment_student

int(11)

связь с таблицей «student». В таблице хранится идентификатор ученика, записавшего данный термин.

сomment_date

date

дата создания комментария

7.3. Сессионные переменные

В нашем проекте необходимо создать страницу index.php на ней должна находиться форма для авторизации (логин, пароль, кнопка войти) сылки:

зарегистрироваться (registr.php);
просмотр терминов (article .php);
и поле для поиска нужного термина.

Прежде чем начнем разбирать основные идеи при создании программного кода давайте еще раз взглянем на рисунок 82 со структурой сервиса. У нас три типа пользователя (учитель, ученик, гость). В зависимости от того, с какими правами мы зашли в данный момент, у нас должны отображаться различные пункты меню.

Для того, чтобы сервер всегда знал с кем он имеет дело в данный момент используется механизм «сессий». В сессионных переменных можно сохранить любые значения, которые будут доступны серверу в течении всего времени нахождения на сайте. Для запуска сессий необходимо вначале страницы index.php добавить следующий программный код:

<?  session_start (); ?> 

Теперь мы можем в любой части кода объявлять сессионные переменные, например, с помощью строки:

$_SESSION['id'] = $row['user_id'];

В данном случае мы объявили сессионную переменную “id” и присвоили ей значение некоторое значение, извлеченное из sql-запроса. Количество сессионных переменных может быть произвольным и к ним можно обращаться в коде $_SESSION['id'], вот только передавать их от страницы к странице не нужно, сервер сделает это за вас. Таким образом, использование сессионных переменных повышает безопасность вашего сервиса. Пользователю достаточно один раз авторизироваться (ввести свой логин и пароль) и в дальнейшем свободно перемещаться по сервису.

Для того чтобы закрыть сессию и соответственно очистить все сессионные переменные необходимо выполнить команду session_destroy();

После того, как посетитель введет свой логин и пароль (если они у него есть, разумеется), он переходит на отдельную страницу authorize.php, она должна быть прописана в параметре action тега FORM .

Листинг № 25

<?
session_start();
include ("_connect.php");
$login = mysql_real_escape_string($_REQUEST['login']);
$pass = mysql_real_escape_string($_REQUEST['pass']);
$sql = "SELECT * FROM student";
$result = mysql_query ($sql);
$kl=0;
while($row = mysql_fetch_array($result)){
if(($login == $row['student_login']) && ($pass == $row['student_pass'])){
$_SESSION['logged_user'] = $row['student_name'];
$_SESSION['id_user'] = $row['id_student'];
header ("Location:article.php");
exit;
} else {$kl=1;} }
if($kl==1){
header ("Location: index.php"); exit; } ?>

Строка 2 включает механизм сессий (это необходимо делать на каждой странице).

Строка 3 подключает файл _connect .php , в котором осуществляется подключение к базе данных.

Строки 4-5 извлекают введенный пользователем логин и пароль.

Строка 9 запускает цикл, в котором перебираются все записи из таблицы students и в случае если находится такая запись в которой поля login и pass совпадают с значениями, введенными пользователем, то создаются две сессионные переменные logged _ user и id _ user (строки 9-10).

Строка 13 перенаправляет уже авторизированного посетителя на страницу article.php .

В случае, если в таблице пользователя с введенными логином и паролем нет, то посетитель вновь перенаправляется на страницу index.php.

7.4. Регистрация нового пользователя

После выбора ссылки «зарегистрироваться» посетитель оказывается на странице с полями формы: фамилия имя, логин, пароль, e - mail, а также кнопками добавить и очистить.

После ввода данных и нажатия кнопки «зарегистрироваться» должен выполниться примерно следующий программный код (листинг 25):

Листинг № 26

<?
if (isset($_REQUEST['add'])){
$name = mysql_real_escape_string($_REQUEST['name']);
$login = mysql_real_escape_string($_REQUEST['login']);
$pass = mysql_real_escape_string($_REQUEST['pass']);
$email = mysql_real_escape_string($_REQUEST['email']);
$sql_select = "SELECT * FROM student";
$result = mysql_query($sql_select); 
$z = 0; 
while($row = mysql_fetch_array($result)){ 	
if ($row["student_name"] == $name){ 
print("<p>Участник с таким именем уже зарегистрирован</p>");   
$z = $z+1; } 
} 	
if($name == null){ 
$z = $z+1; 
print("<p>Вы не написали имя автора</p>"); } 
if($z == 0){ 
$sql_add = "INSERT INTO student VALUES(null, '$name', '$email', '$login', '$pass', '0')"; 	
mysql_query($sql_add); 
$_SESSION['logged_user'] = $name; 
$_SESSION['id_user'] = mysql_insert_id(); //вывод последнего id для передачи в сессии 	} 
} 
?>

Строка 2 проверяет нажата ли кнопка add (имя кнопки типа submit в форме). Если это так выполняется весь дальнейший код.

Строки 3-6 извлекают данные из формы регистрации.

Строка 7-9 извлекают данные из таблицы student для дальнейшей проверки на совпадение данных.

В строках 10-16 проверяют нет ли в таблица пользователя с таким же именем, что и ввел пользователь.В случае если такого пользователя нет, новый пользователь добавляется в базу данных (строки 18-19. Обратите внимание в SQL -запросе статус пользователя задается, как ‘0', то есть каждый зарегистрированный пользователь – ученик.

Строки 20-217 задают две сессионные переменные logged_user и id_user . Для переменной id_user используется функция mysql_insert_id (). Она извлекает идентификатор последней добавленной записи.

Теперь мы можем перенаправить вновь зарегистрированного пользователя на страницу article.php .

7.5. Просмотр/добавление/изменение терминов

Давайте рассмотрим основные идеи для создания страницы article.php .

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

Кроме того, давайте не забывать, что каждый посетитель может просматривать все термины, а вот изменять/редактировать можно только свои записи.

Для того, чтобы выдавать различное меню я предлагаю подключать к сервису файл menu.inc

Листинг № 27

<?
if(!isset($_SESSION['id_user'])){
include ("menu_user.inc");
} else {
$id_user = $_SESSION['id_user'];
$sql_select = "SELECT * FROM student WHERE id_student = $id_user";
$result = mysql_query($sql_select);
while($row = mysql_fetch_array($result)){
$name_user = $row['student_name'];
print("<p>Добро пожаловать: $name_user</p>");
if($row['student_admin'] == 1){
include ("menu_admin.inc");
} else {
include ("menu_student.inc");
}
}
}
?>

В данном фрагменте если сессионная переменная id_user не существует (строка 2) подключается меню, находящееся в файле menu_user . inc (строка 3).

В противном случае выполняется SQL-запрос выбирающий из таблицы students запись, в которой идентификатор пользователя равен переменной id_user (строки 5-6).

Далее просматривается статус пользователя ($row ['admin']), если он равен единицы, подгружается меню из файла menu_admin.inc . Если же статус равен нулю, подгружается меню из файла menu_student.inc .

Выбор данных из связанных таблиц

При выводе терминов мы должны выбрать термины и их описания из таблицы term, а также данные об учениках, описавших данный термин. Для такого выбора используется SQL-запрос, представленный ниже :

$sql_select = "SELECT * FROM dict, student WHERE dict.dict_student = student.id_student ORDER by binary(lower(dict.dict_name))"; 
$result = mysql_query($sql_select);
$num = mysql_num_rows($result);

В нем выбор осуществляется из нескольких таблиц. После ключевого слова WHERE указываются через какое поле осуществляется связка, поле student из таблицы dict должно равняться полю id_student из таблицы student. Все записи сортируются по полюdict_nam.

Вывод терминов

Теперь, когда из базы данных выбраны данные, мы можем выводить их на экран. Для этого используется код, представленный в листинге №28.

Листинг № 28

<?  
while($row = mysql_fetch_array($result)){
print("<p><b>$row[dict_name]</b><br>");
print("$row[dict_article]<br>");
if(isset($_SESSION['id_user']) && $_SESSION['id_user'] == $row['dict_student']){ 
print("<a href=\"update_article.php?id=$row[id_dict]\">изменить</a> ");
print(" <a href=\"article.php?id_del=$row[id_dict]\">удалить</a><br>");
}
print("<i>добавлен:</i> $row[dict_date]<br>");
print("<i>автор:</i> <a href=\"mailto:$row[student_email]\">$row[student_name]</a></p>");
}
?>

В данном фрагменте вначале выводится термин, после на новой строке его описание и еще ниже автор дата добавления термина и его автор. В случае если идентификатор автора равен сессионной переменной $ id_user, рядом с термином появляется ссылки изменить/удалить (строки 5-8).

Добавление термина

Для добавления нового термина необходимо создать отдельную страницу add_article.php. На ней должна быть форма для ввода названия термина, его описание, а также код, который в целом аналогичен добавлению нового пользователя (листинг № 29 ). Вначале нужно проверить существует ли такой термин в базе данных, если это не так, выполняется код, представленный ниже:

Листинг № 29

if($z == 0){
$data_article = date("Y-m-d");
$sql_add = "INSERT INTO dict VALUES(null, '$name', '$article', '$data_article', '$student')";
mysql_query($sql_add);
print("<p>Ваш термин добавлен</p>");
}

Небольшая особенность данного кода в использовании функции date(), вычисляющий текущую дату в формате год-месяц-день. Если вы забыли про форматы дат, обратитесь к уроку №10.

После формируется SQL-запрос и данные добавляются в таблицу dict .

Дальнейшее реализация проекта

В уроке не рассказывается о добавлении комментариев. Вы сможете создать программный код самостоятельно.

У вас должен получиться рабочий web-сервис. Можно наметить пути его улучшения.

  • Необходимо в базу данных добавить отдельную таблицу, содержащую название вашего словаря и связать с ней таблицу term . Тогда возможно будет использовать сервис для составления словарей по разным темам.
  • При оформлении проекта нужно не забыть про каскадные таблицы стилей.
  • В меню пользователя нужно не забыть пункт «выход», который выполняет переход на страницу index.php и вызывает там функцию session_destroy().
  • Нужно создать страницу учителя, в которой он может изменять данные пользователей проекта, в том числе менять их статус (учитель/ученик).
  • На начальной странице ученик может выбирать название словаря (его идентификатор), который должен заноситься в сессионную переменную и в дальнейшем следовать за посетителем на разных страницах.
  • Для учителя нужно добавить страницу, на которой выводится информация о количестве терминов добавленных каждым пользователем.
  • В словаре можно сделать поле для поиска по ключевому слову.

Эти и другие улучшения вы можете выполнить самостоятельно или под руководством учителя. Ваша работа может стать итоговым проектом, результатом выступления на научно-практических конференциях.

Вопросы для самоконтроля

  1. для чего необходимо рисовать структуру сервиса?
  2. Что такое «сессионные переменные» и как их использовать?
  3. Для чего в каждой таблице используется поле «id»? Какой тип оно имеет?
  4. Как составлять SQL-запрос к связанным таблицам?