Для работы форума необходим веб-сервер Apache с поддержкой PHP и база данных MySQL. Скрипт forum.php3 помещается в каталог /usr /local /apache /htdocs (без пробелов). Работающий форум можно посмотреть здесь, а полный листинг здесь.
Начало
Прежде,чем начать рассмотрение практического применения PHP,нужно войти в MySQL как администратор и создать базу данных,в которой будет храниться вся информация.
Создаем базу данных forum.
mysqladmin -u root -p create forum; use forum;
Создаем 3 таблицы в базе данных forum.В них будет записываться вся информация.
create table info ( id int (4) not null auto_increment primary key, name varchar (15) not null, password varchar (15) not null, email varchar (40) not null, posts int (4) default 0, key (name),key (password));
create table topics ( top_id int (4) not null auto_increment primary key, top_name varchar (255) not null, name varchar (15) not null, message text not null, replies int (4) default 0, post_date datetime default 0000-00-00 00:00:00, last_reply datetime default 0000-00-00 00:00:00, key (top_name),key (name));
create table replies ( name varchar (15) not null, top_name varchar (255) not null, reply text not null, reply_date datetime default 0000-00-00 00:00:00, key (name),key (top_name));
Регистрация пользователя в БД
Далее пойдет чистый PHP и HTML.
Сгенерируем форму для регистрации:
<h2 align=center><font color="ff0000">Registration.</font></h2> <p><font face="serif" size=2> Please,fill in the form below. <p>You may use only english chars
in your name,and names length should be not less than 3 and not more than 15 characters. <br>Remember:all form fields are case sensitive.It means the names
<font face="arial" size=2 color="0000ff">name</font> and
<font face="arial" size=2 color="0000ff">Name</font> are different. <p>Passwords length should be not less than 6 characters.<br> Dont forget to enter your e-mail address, you may need it if youll forget your password. <p><FORM ACTION="" METHOD="POST" name="reg"> <p align=right><a href="">Home</a> <center><TABLE BGCOLOR="bfbfbf"> <tr><td colspan=2> </td></tr> <tr><TD><b>Login:</b><TD> <INPUT TYPE="text" NAME="login" SIZE="20" maxlength="15" > <tr><TD><b>Password:</b><TD> <INPUT TYPE="password" NAME="pass" SIZE="20" onFocus="is_ValidLogin (this.form.login.value)";return true> <tr><TD><b>Verify password:</b><TD> <INPUT TYPE="password" NAME="verpass" SIZE="20" onFocus="is_ValidPass (this.form.pass.value)";return true> <tr><TD><b>E-mail:</b><TD> <INPUT TYPE="text" NAME="email" SIZE="20" onFocus="verPasswd ()";return true> <tr><td colspan=2><input type="hidden" name="action" value="register"> <tr><td colspan=2><input type="hidden" name="verify" value="ok"> <tr><TD colspan=2><p><center> <INPUT TYPE="submit" name="submit" VALUE="Submit" onMouseOver="true_Email (this.form.email.value)";return true></center> <tr><td colspan=2> </table> </form>
Функции,использованные в форме, служат для проверки информации,введенной пользователем. Далее, нужно обработать данные. Для соединения с БД используется функция mysql_connect ().Поскольку соединяться с БД придется не раз,я вынес все данные в функцию connect ()
function connect () { $hostname="localhost:3306"; $user="root"; $password="ваш пароль"; $db="forum";
Эта функция подключает базу данных и проверяет наличие ошибок соединения. Теперь можно получить и обработать данные пользовательского ввода.
if ($action=="register") { connect (); if ($verify) {
$query="select id from info where name=$login"; // Запрос к БД. $result=mysql_query ($query);
if (mysql_num_rows ($result)) { // Проверяем,не существует ли уже такой пользователь. print_header (); echo "<p align=center><b>Error!</b>"; echo "<p>Name <b>".$login."</b> already exists.Please,go back and choose another name."; ?> <p><center><a href="?action=register">Go back</a></center> <?php } else { // Если все ОК вставляем данные в таблицу info.
$query="insert into info (name,password,email) values ($login,$pass,$email)"; $result=mysql_query ($query);
// Говорим пользователю спасибо и распечатываем информацию. print_header (); echo "<h3 align=center>Thank you,<font color=ff0000>".$login."!</font></h3>";?> <p>You are successfuly registered and your information added to our database. <p>Please,remember your information.Only registered users may post messages and replies. <p><font face=arial size=2 color=0000ff>Your login:</font> <font face=arial size=2 color=ff0000></font><br> <font face=arial size=2 color=0000ff>Password:</font> <font face=arial size=2 color=ff0000></font><br> <font face=arial size=2 color=0000ff>E-mail:</font> <font face=arial size=2 color=ff0000></font> <p>Good luck! <center><a href=""> Go to topics</a> <a href="?action=add_new_top"> Post new topic</a> </center> <?php } }
Функция print_header ()-это заголовок html-страницы. Она тоже использована для уменьшения количества кода.
function print_header () { ?> <html><head><title>Forum version 1.1</title> </head><style> A:link {font-family:arial;font-size:10pt;text-decoration:none;color:#0000ff;} A:hover {font-family:arial;font-size:10pt;text-decoration:none;color:red;}"; A:visited {font-family:arial;font-size:10pt;text-decoration:underline;color:#0000ff;} BODY {background-color:#e6e8fa;font-family:arial;font-size:10pt;color:#333300;} TD {font-family:arial;font-size:10pt;color:#333300;} H2 {text-align:center;color:blue;} </style><body> <?php }
Ну вот и все. Пользователь зарегистрирован и может помещать сообщения в форуме.
Создание нового топика
Для создания нового топика используем следующую форму:
Все поля обязательны для заполнения. Пользователь должен ввести свое имя,под которым он регистрировался в БД и пароль.Скрипт проверяет наличие их в БД,и если все нормально-помещает сообщение в таблицу topics.Если же имя и пароль введены неверно-выдается ошибка.Помещать сообщения могут только зарегистрированные пользователи. Вот как это выглядит:
elseif ($action=="add_new_top") { connect (); // Соединяемся с БД. if ($test) {
//функций htmlspecialchars (),str_replace () и nl2br (). // htmlspecialchars () используется для того,чтобы
//преобразовать html-теги.Это делается в целях безопасности и для защиты от разного рода шутников :) // str_replace () заменяет символ одинарной кавычки на пробел,
//т.к. внесение одинарной кавычки в БД //недопустимо-это специальный служебный символ.Это защитит БД от взлома. // nl2br () преобразует символ конца строки в html-тег<br>.
//Это используется для того,чтобы текст,введенный в форму сохранился неизменным. $query="select id from info where name=$nick AND password=$passwd";
// Запрос к БД.Проверка имени и пароля. $result=mysql_query ($query);
// Если все ОК,проверяем,чтобы поля формы не были пустыми. if (mysql_num_rows ($result)) { if (strlen ($theme)!=0 && strlen ($message)!=0) {
// Если все ОК,вставляем данные в таблицу topics. $query="insert into topics (top_name,name,message,post_date,last_reply)
// Обновляем таблицу info-увеличиваем количество постов для данного пользователя на 1. $query="update info set posts=posts+1 where name=$nick"; $result=mysql_query ($query); print_header ();
// Говорим пользователю спасибо. ?> <h3 align=center>Thank you,<font color="ff0000"><?php echo $nick ?>!</font></h3> <p>Your topic has been submitted. <p><center> <a href="<?php echo $script ?>">Go to topics</a>
<a href="<?php echo $script ?>?action=add_new_top"> Post new topic</a> </center> <?php } else { print_header ();
// Если одно из полей формы оказалось пустым-выдается ошибка. ?> <h2 align=center>Error!</h2> <p>You didnt enter topic name or message.Please,go back and try again. <p><center> <a href="<?php echo $script ?>?action=add_new_top">Go back</a> <a href="?action=remind_pass">Forgot password?</a> </center> <?php } } else { print_header ();
// Если введены неверные имя или пароль,также выдается ошибка. ?> <h2 align=center>Error!</h2> <p>You entered incorrect name or password.Please,go back and try again. <p><center> <a href="<?php echo $script ?>?action=add_new_top">Go back</a> <a href="<?php echo $script ?>?action=remind_pass">Forgot password?</a></center> <?php } }
Все эти предосторожности не лишние. Во-первых в целях безопасности самой базы данных. Во-вторых для защиты форума от случайных посетителей и от взлома. Новый топик создан и информация добавлена в таблицу topics. Далее рассмотрим,как разместить ответ на сообщение.
Посылка ответа на сообщение
Она ничем не отличается от создания нового топика,только ответ помещается в таблицу replies. Сгенерируем форму.
С этим,думаю,все понятно,так же как и в предыдущем примере.
Чтение топика
Это довольно объемная часть скрипта,по ходу дела я буду давать пояснения.
elseif ($action=="read_topic") { if ($top_name) { connect ();
// В этом случае данные выбираются из 2-х таблиц-topics и info. $query="select message,post_date,info.posts,
info.email from topics,info where topics.name=
info.name and topics.top_name=$top_name and topics.name=$name"; $result=mysql_query ($query);
$row=mysql_fetch_array ($result); $message=$row["message"]; $post_date=$row["post_date"]; $posts=$row["posts"]; $email=$row["email"]; // Вырезаем теги <br>,чтобы они не отображались на странице. $message=str_replace ("<br>","",$message); $char=$message;
// Эта куча преобразований позволяет помещать
//в сообщения смайлики и выводить их на экран в виде рисунков. $char=str_replace (":)","<img src=./images/smile.gif>",$char); $char=str_replace (":(","<img src=./images/frown.gif>",$char); $char=str_replace (":o","<img src=./images/redface.gif>",$char); $char=str_replace (":D","<img src=./images/biggrin.gif>",$char); $char=str_replace (";)","<img src=./images/wink.gif>",$char); $char=str_replace (":p","<img src=./images/tongue.gif>",$char); $char=str_replace (":cool:","<img src=./images/cool.gif>",$char); $char=str_replace (":rolleyes:","<img src=./images/rolleyes.gif>",$char); $char=str_replace (":mad:","<img src=./images/mad.gif>",$char); $char=str_replace (":eek:","<img src=./images/eek.gif>",$char); $char=str_replace (":confused:","<img src=./images/confused.gif>",$char);
print_header (); ?>
// Теперь все выбранные данные помещаем в html-таблицу и выводим на экран. <p align=right> <a href="<?php echo $script ?>">Go to topics</a>
<a href="<?php echo $script ?>?action=add_new_top"> Post new topic</a> <a href="<?php echo $script ?>?action=post_reply&top_name=
// страницам в случае,если количество записей больше 20. // Для этого подсчитываем количество записей
//в таблице replies для данного топика. $query="select COUNT(*) as count from replies where top_name=$top_name"; $result=mysql_query ($query); $items=mysql_fetch_array ($result); $count=$items["count"]; $pages=ceil ($count/$lines);
// В случае,если количество ответов больше 20,
//формируем ссылки с номерами страниц. if ($count>$lines) { echo "<p align=right>"; for ($i=0;$i<$pages;$i++) { ?> <a href="<?php echo $script ?>?action=read_topic&top_name=
<?php echo $top_name ?>&name=
<?php echo $name ?>&page=<?php echo $i ?>">
<?php echo ($i+1) ?></a><?php } } } }
Вот и все.Теперь вы видите,как просто можно работать с БД с помощью PHP,и как это облегчает жизнь. Все это остается за кадром,а посетители форума видят обычную html-страницу.Далее рассмотрим, как можно редактировать сообщения.
Редактирование сообщения
Редактирование сообщения может понадобиться,если пользователь допустил ошибку, или хочет изменить что-нибудь в тексте. Редактировать можно только свои сообщения, за этим следит скрипт и БД.В зависимости от того, является сообщение топиком или ответом на топик, выводятся 2 разные формы.
connect ();
// Если это топик,находим его в таблице topics. if ($type=="message") { $query="select message from topics where name=$nick and top_name=$top_name"; $result=mysql_query ($query); $row=mysql_fetch_array ($result); $message=$row["message"]; $message=str_replace ("<br>","",$message);
print_header ();
// Помещаем сообщение в форму для редактирования. ?> <h3 align=center><font color="0000ff">Edit message.</font></h3> <p align=right> <a href="<?php echo $script ?>">Go to topics</a>
elseif ($action=="edit") { if ($submit) { connect ();
// Делаем все как обычно.Переменная
//$end-это строка,добавляемая в конце редактируемого сообщения. $date=date ( "Y-m-d H:i:s",mktime ()); $end="\n----------------------------------------------------------\n
This message was edited by $nick $date."; $post=str_replace (""," ",$post); $post.=$end; $post=htmlspecialchars ($post); $post=nl2br ($post);
// Проверяем имя и пароль. if ($type=="message") { $query="select id from info where name=$name and password=$passwd"; $result=mysql_query ($query);
// Если все ОК и это топик-обновляем таблицу topics. if (mysql_num_rows ($result) && $name==$nick) { $query="update topics set message=$post where top_name=$top_name"; $result=mysql_query ($query); print_header (); ?>
Post new topic</a> </center> <?php } else { print_header (); ?>
// Если имя и пароль не найдены или пользователь
//не является автором сообщения выдается ошибка. <h3 align=center>Error!</h3> <p>This message cannot be edited.May
be you entered incorrect nick or password, or you are not an author of this message. <p>Please,go back and try again. <p><center> <a href=javascript:history.back ()> Go back</a>
// Если это ответ на топик,изменяем таблицу replies. $query="select id from info where name=$name
and password=$passwd"; $result=mysql_query ($query);
if (mysql_num_rows ($result) && $name==$nick) { $query="update replies set reply=$post where top_name=$top_name and name=$nick and reply_date=$reply_date";
Post new topic</a> </center> <?php } else { print_header (); ?> <h3 align=center>Error!</h3> <p>This message cannot be edited.May be you entered incorrect nick or password, or you are not an author of this message. <p>Please,go back and try again. <p><center> <a href=javascript:history.back ()> Go back</a>
Как видите,ничего нового.Те же SQL-запросы в связке с PHP-функциями.
Если пользователь забыл пароль
Если пользователь забыл пароль, ему достаточно ввести свой e-mail, который он указал при регистрации, и пароль будет выслан ему на этот e-mail. Форма для ввода:
// Если есть,отправляем сообщение с паролем. if (mysql_num_rows ($result)) { $to=$email; $subject="Password reminder"; $mes="Your password:".$password."."; mail ("$to","$subject","$mes");
print_header (); ?> <h3 align=center>Hello,<?php echo $name ?>!</h3> <p>You entered valid e-mail! <p>Your password sent to your e-mail address. <p><center> <a href="<?php echo $script ?>">
Go to topics</a> <a href="<?php echo $script ?>
?action=add_new_top"> Post new topic</a> </center> <?php } else { print_header (); ?>
// Если e-mail не найден,выводится ошибка. <h3 align=center>Sorry!</h3> <p>This e-mail address hasnt been found in our database.<br> Please,verify your e-mail address an try again,
or go to our registration page and register. <p><center> <a href="<?php echo $script ?>
?action=remind_pass">Go back</a>
<a href="<?php echo $script ?>?action=register">
Register</a> </center> <?php } }
Главная страница форума
Вот мы и добрались до конца, точнее до начала-главной страницы форума, на которой показывается список топиков, количество ответов, автор топика, дата создания топика и дата последнего ответа на него.
В принципе,ничего нового. Количество записей на страницу также ограничено 20.
$query="select COUNT(*) as count from topics"; $result=mysql_query ($query); $items=mysql_fetch_array ($result); $count=$items["count"]; $pages=ceil ("$count/$lines");
if ($count>$lines) { echo "<p align=right>"; for ($i=0;$i<$pages;$i++) { ?> <a href="<?php echo $script ?>?page=<?php echo $i ?>">
<?php echo ($i+1) ?></a><?php } } } ?>
Конечно,данный форум не пример для подражания. У каждого своя манера программирования. Может другой напишет это по-своему. Однако за основу принять можно.