Форум {конференція) — це Web-еквівалент телеконференцій, які беруть свій початок від електронних дошок конференцій (bulletin board system, BBS). Ці засоби дають можливість брати участь у дискусіях з іншими «читачами», обговорювати різноманітні питання. Форум може відігравати важливу роль у Web-сайті навчального закладу. Учні зможуть обговорити різноманітні питання, присвячені навчальному процесу школи, позакласній діяльності, задати питання вчителям. Форум буде цікавим для абітурієнтів та випускників навчального закладу.
Ще не так давно створити власний форум було під силу не кожному. Необхідним було глибоке знання технології CGI та мови програмування Perl.
Проте з появою тандему PHP+MySQL програмування форумів стало цікавою і навіть «захоплюючою» задачею, доступною користувачам різної кваліфікації
До програмування форумів існує така кількість підходів, як і кількість сайтів, що включають сторінку форуму. Змінюється кількість файлів, з яких складається форум, форми виведення інформації, методи захисту від повідомлень що можуть містити деструктивний код. Форуми використовують в основному два методи виведення інформації. Перший — це виведення лише тем повідомлень і кількості відповідей на них. До самого повідомлення і відповідей можна перейти шляхом клацання на відповідних гіперпосиланнях. Проте, на нашу думку, така форма у деяких випадках є не зовсім зручною, оскільки користувачу доводиться витрачати додатковий час на завантаження кожного повідомлення і відповіді на нього.
Є шанс пропустити деякі повідомлення з цікавою інформацією, тому для створення нашого форуму було вибрано іншу форму — коли всі повідомлення і відповіді на них виводяться повністю і на спільній сторінці. Вигляд сторінки форуму подано на рис. 2.3.
Рис. 2.3
Для збереження записів форуму створимо базу даних inter, таблицю forum з полями, поданими у таблиці 2.6 (верхній рядок подано англійською для простішого створення бази за допомогою РНРМуAdmin).
Таблиця 2.6.Поля таблиці forum
Field
Type
Null
Default
Extra
Призначення
id
tinyint(4)
No
auto_increment
номер запису
name
varchar(20)
No
ім'я
subj
varchar(40)
No
тема повід.
comments
text
No
текст повід.
date
varchar(20)
No
дата повід.
mail
varchar(255
No
email-адреса
SQL-запит для створення такої таблиці має вигляд:
CREATE TABLE forum (
id tinyint(4) NOT NULL auto_increment,
name varchar(20) NOT NULL,
subj varchar(20) NOT NULL,
comments text NOT NULL,
date varchar(20) NOT NULL,
mail varchar(255) NOT NULL,
PRIMARY KEY (id));
Відмітимо, що для збереження дат у MySQL є відповідний тип поля — date. Оскільки в даній задачі не передбачається ніяких маніпуляцій з датами, для збереження дати повідомлення обрано символьний тип varchar().
Форум складається з трьох файлів forum.php, writeforum.php i admin.php.
Скрипт forum, php виводить повідомлення з бази даних, а також відображає форму, за допомогою якої користувач може передавати повідомлення. Текст файла forum, php подано в лістингу
Як бачимо, код PHP можна поділити на частини. Частину, що відповідає за з'єднання з сервером баз даних, для зручності модифікації винесено в голову документа (дескриптор <HEAD></HEAD>). Другу частину, що виводить повідомлення з бази даних, поміщено у відповідне місце таблиці.
Скрипт writeforum. php отримує дані з форми файла forum, php, перевіряє їх та записує до бази даних форуму. Код скрипту подано в лістингу.
Код запису до бази даних дещо складніший, ніж у випадку, який розглянуто в прикладі побудови адресної бази даних. Це пояснюється необхідністю додаткової перевірки наявності даних про ім'я атора, тему та текст повідомлення, правильність введення e-mail-адреси. Крім того, повідомлення можуть містити деструктивний код, наприклад, JavaScript-програму, яка стирає вміст документа і поміщує туди власний код сторінки (deface).
Велику увагу слід приділяти контролю довжини повідомлень. І, хоча такий контроль здійснюється у самій формі введення даних (за допомогою атрибута maxlength), ці обмеження можуть легко обійти зловмисники шляхом підміни форми на власну.
Зазначимо, що розуміння ділянок коду, який використовуються для перевірки адреси, захисту від HTML-дескрипторів, може викликати в початківців деякі труднощі, тому на початку достатньо без заглиблення в суть коду просто переписувати їх у потрібне місце власних проектів.
Лістинг 2.20
<?php
//ініціалізація змінних
define("DBName", "inter");
defineO'HostName","localhost");
define("UserName","root");
define("Password","");
// функція перевіряє правильність введення email-адреси
У наведеному коді прослідковується важлива функція Header(), яка служить для пересилання Web-серверу рядка HTTP-заголовка. Тут для редиректу (переадресації) на сторінку forum, php серверу пересилається рядок «Location: forum.php».
Для адміністрування форумом служить скрипт admin, php. Відмітимо, що він використовується лише для вилучення записів. Відображення сторінки admin. php у броузері подано на рис.2.4. Форма служить для введення пароля та номерів записів для знищення.
Рис. 2.4
Код скрипту:
Лістинг 2.21
<html>
<head>
<title>Forum administrater</title>
<META content="text/html; charset=windows-1251"
http-equiv=Content-Type>
</head>
<body>
<?php
// ініціалізація змінних
define("DBName","inter");
define("HostName","localhost");
define("UserName","root");
define("Password","");
/*функція виводить записи і відображає форму*/
function display_form() {
global $PHP_SELF;
//з'єднання з базою
$db=mysql_connect(HostName, UserName, Password); i
f(!$db)
{ echo "He можу з'єднатися з сервером MySQL!<br>"; exit; }
if(!mysql_select_db(DBName, $db))
{ echo "He можу з'єднатися з базою!<br>"; exit; }
// виведення впорядкованих за спаданням записів
$result = mysql_query("SELECT * FROM forum ORDER BY id DESC",$db);
$number=mysql_numrows($result);
$i=0;
while ($i<$number)
{
$id=mysql_result($result,$i,"id");
$name=mysql_result($result,$i,"name");
$subj=mysql_result($result,$i,"subj");
$mail=mysql_result($result,$i, "mail");
$comments=mysql_result($result,$i,"comments");
$date=mysql_result($result,$i,"date");
printf ("<p><B>%S: %S </B><br>\n",$id, $subj);
printf ("%S <br>\n", $comments);
printf ("%S: %S %S<br> \n", $date, $name, $mail);
$i++;
echo "<p> <HR><p> ";
?>
<!-- Форма для введення пароля та діапазону записів, які підлягають знищенню. Скрипт, що опрацьовує дані з цієї форми, знаходиться у тому самому файлі (форма викликається сама на себе).-->
{echo "He можу встановити з'єднання з севером MyS0L<br>"; exit;}
if (!mysql_select_db(DBName,$db) )
{ echo "He можу з'єднатися з базою", DBName,"!<br>"; exit; }
//sql-запит на видалення записів
$sql= "DELETE FROM forum WHERE id BETWEEN $from AND $to";
// передача запиту серверу
$result = mysql_query($sql);
echo "Дані оновлено!\n";
// закриваємо з'єднання
mysql_close ($db);
}//кінець функції process form()
?>
<?phр
/*головна ділянка коду*/
// перевіряємо чи змінна $stage не порожня -
//опрацьовуємо дані, виводимо форму
// в іншому випадку тільки виводимо форму
if (!empty($stage)) { process_form(); display_form(); }
else { display_form(); }
?>
</body>
</html>
При виведенні даних використовується функція printf (), знайома для тих, хто колись працював з мовою С чи Perl. У наведених функціях комбінація %s означає те, що на її місці повинно бути значення змінної, яка знаходиться у другій половині виразу printf, причому приведено до типу «рядок».
У попередніх прикладах форма і php-програма, що опрацьовує дані, знаходились у різних файлах. У цьому прикладі використано цікавий прийом, коли форма і програма, що опрацьовує дані, знаходяться в тому самому файлі. Відбувається так званий «виклик форми самої на себе». Для цього використано такий відкриваючий дескриптор форми:
Атрибуту ACTION присвоюється значення, згенерованс php-кодом. У коді використовується змінна $PHP_SELF, значенням якої є ім'я та URL поточної сторінки. Використання цієї змінної гарантує коректну роботу скрипту у випадку перенесення його в інший каталог, або навіть на інший комп'ютер.
Форма має також одне скрите поле:
<INPUT TYPE=HIDDEN NAME="stage" VALUE="results'>
Це поле є невидимим у броузері і служить для створення змінної $stage для ідентифікації стану сторінки: у даний момент сторінка відображає зміст бази , і форму (значення змінної $stage порожнє), чи опрацьовує дані з форми (значення $stage не є порожнім).
Така ідентифікація використовуєтся в глобальній частині PHP-коду (не у тілі функцій):
if (!empty($stage)) { process_form(); display_form(); }
else { display_form(); }
Якщо адміністратор форуму перший раз (в даному сеансі) звертається до сторінки admin, php, то змінна $stage — порожня і тому викликається функція display_form(), яка виводить всі записи, збережені у базі даних, а також відображає форму. Після введення пароля, діапазону записів, що підлягають видаленню, і натискування на кнопці «Вилучити» викликається ця сама сторінка. Але у даному випадку змінна $stage не є порожньою і вищенаведений оператор викликає функцію process_form() — для опрацювання даних, отриманих із форми, тобто власне вилучення записів та display_form() — для виводу модифікованої бази та відображення форми.
Необхідно також звернути увагу на те, що у тілі функцій змінні описуються з директивою global. Вона вказує, що ці змінні є глобальними, тобто областю дії їх є вся сторінка.
Описаний форум можна удосконалювати. Перш за все доцільно зробити так, щоб на одну сторінку виводилось не більше ЗО повідомлень. Доступ до решти повідомлень може здійснюватись за допомогою гіперпосилання, розміщеного внизу сторінки.
Контрольні запитання
1.Яке розширення повинен мати файл, в якому міститься РНР-сценарій?