PHP

Гостевая книга на PHP/MySQL

Сегодня расскажу вам о том, как написать гостевую книгу на PHP и MySQL. Ничего сложного в этом нет, да и возможности данной гостевой не самые большие: постраничный вывод записей, проверка вводимых данных, возможность удалять записи.

Допустим, что у вас уже есть PHP, MySQL и веб-сервер. Вы всё установили и настроили.

Начнём с создания таблицы, в которой будут храниться данные нашей гостевой книги. Будем спрашивать у пользователя имя и комментарий. При желании пользователь сможет сообщить адреса электронной почты и домашней странички. Для администрирования книги нам понадобится ещё одно поле, уникальное для каждой записи, - идентификатор. Ну и дата, конечно. В итоге получается такая таблица:
CREATE TABLE gb (
   id int(10) unsigned NOT NULL auto_increment,
   datetime datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
   name varchar(100) NOT NULL,
   email varchar(100),
   www varchar(100),
   message text NOT NULL,
   PRIMARY KEY (id)
);

Таблица у нас есть. Теперь можно приступать к программированию.

Для создадим файл с настройками гостевой книги:
<?php
// общие константы
define(&apos;PATH&apos;, &apos;/gb/&apos;); // путь к гостевой книге
define(&apos;RECSPERPAGE&apos;, 10); // количество записей на одной странице
define(&apos;ADMIN_EMAIL&apos;, &apos;artem@sapegin.ru&apos;); // email администратора
define(&apos;ERROR_LOG_FILE&apos;, &apos;logs/error.log&apos;); // файл лога ошибок

// Параметры БД
define(&apos;DBHOST&apos;, &apos;localhost&apos;); // имя хоста
define(&apos;DBUSER&apos;, &apos;root&apos;); // имя пользователя
define(&apos;DBPASSWD&apos;, &apos;&apos;); // пароль
define(&apos;DBNAME&apos;, &apos;test&apos;); // имя базы данных
?>

Теперь подумаем, какие вспомогательные функции нам понадобятся. На нужно будет взаимодействовать с СУБД, проверят и обрабатывать вводимые пользователем данные. Так же для функций администрирования на понадобится отличать администратора от простых пользователей.

Начнём с работы с СУБД.
<?php
/** recource db_connect ( string host, string user, string passwd, string dbname )
* Подключение к СУБД и открытие базы данных
*/
function db_connect($host, $user, $passwd, $dbname)
{
$link = mysql_pconnect($host, $user, $passwd) or die(&apos;Could not connect to database&apos;);
mysql_select_db($dbname) or die(&apos;Could not select database&apos;);
return $link;
}

/** Выполняет запрос к БД
*
* @param текст запроса
* @return resource id
*/
function db_query($query)
{
$result = mysql_query($query)
  or die(&apos;Bad database query&apos;);
return $result;
}

/** Выполняет запрос к БД (placeholder)
*
* @param текст запроса
* @param*
* @return resource id
*/
function db_query_ex($query)
{
$values = func_get_args();
array_shift($values);
$i = 0;
return db_query(preg_replace(&apos;%\?%e&apos;, &apos;"\&apos;".addslashes($values[$i++])."\&apos;"&apos;,
                $query));
}
?>

Обработка строк (проверка и фильтрация вводимых пользователем данных).
<?php
/**
* Проверяет является ли строка адресом e-mail
*/
function strings_isemail($string)
{
return preg_match(&apos;%[-\.\w]+@[-\w]+(?:\.[-\w]+)+%&apos;, $string);
}

/**
* Добавление ссылок на http и e-mail
*/
function strings_addlinks($string)
{
return preg_replace(
&apos;%((?:http|ftp)://[-\w]+(?:\.[-\w]+)+\b[-\w:@&?=+,!/~*$\.\&apos;\%]*)(?<![\.,?!)])%i&apos;,
&apos;<a href="\\1">\\1<a>&apos;,
$string
);
}

/**
* Чистка строки
*/
function strings_clear($string)
{
$string = trim($string);
$string = stripslashes($string);
return htmlspecialchars($string, ENT_QUOTES);
}

/**
* Обрезание строки
*/
function strings_stripstring($text, $wrap, $length)
{
$text = preg_replace(&apos;%(\S{&apos;.$wrap.&apos;})%&apos;, &apos;\\1 &apos;, $text);
return substr($text, 0, $length);
}
?>

Написание аутентификации администратора я оставляю вам в качестве домашнего задания. Есть достаточно много способов и их обсуждение - тема отдельной статьи. Я приведу лишь функцию-заглушку:
<?php
/**
* Проверка: администратор или обычный пользователь
*/
function auth_is_admin()
{
return @$_GET[&apos;admin&apos;];
}
?>

Далее идёт достаточно большой модуль, в котором содержится почти весь HTML-код гостевой книги, - шаблон. В нём нет ничего сложного и его написание можно вполне под силу верстальщику сайта, если у вас таковой имеется.
<?php
/**
* заголовок страницы
*/
function template_header($page)
{
?><html>
<head>
<title>page <?=$page?> < fjGuestbook Demo</title>
<style>
body{
padding: 15px;
margin: 0;
color: #333;
background-color: #eee;
border-left: 30px solid #adba8e;
font: 500 .9em verdana, arial, helvetica;
}
a:link{color: #250;}
a:visited{color: #639;}
a:active,a:hover{
color: #c00;
text-decoration: underline;
}
h1 { font-size: 150%; }
h2 { font-size: 110%; }

.c{margin-bottom: 10px;}
.cn{
background-color: #d2d6bc;
padding: 2px 4px;
margin-bottom: 4px;
}
</style>
</head>
<body>
<h1>fjGuestbook Demo</h1><?php
}

/**
* окончание страницы
*/
function template_footer()
{
?>
<p>fjGuestbook 1.2. Copyright &copy 2002�2004
<a href="http://sapegin.ru">Artem Sapegin</a></p>
</body></html>
<?php
}

/**
* форма добавления новой записи
*/
function template_form($name, $email, $www, $message, $error)
{
  // вывод сообщения об ошибке
  function error($error)
  {
    if($error) echo &apos;<br><font color=#880000>&apos;.$error.
                    &apos;</font>&apos;;
  }

  echo &apos;<h2>Добавить новое сообщение</h2>
<p><table cellspacing="2" cellpadding="2" border="0">
<form action=&apos;.PATH.&apos;?add=1 method=post><tr>
<td>Имя<font color=#880000>*</font>:</td>
<td><input type=text name="name" size=30 
  maxlength=100 value="&apos;.$name.&apos;">&apos;;
  @error($error[&apos;name&apos;]);
  echo &apos;</td>
</tr><tr>
<td>Email:</td>
<td><input type=text name="email" size=30 
  maxlength=100 value="&apos;.$email.&apos;">&apos;;
  @error($error[&apos;email&apos;]);
  echo &apos;</td>
</tr><tr>
<td>URL:</td>
<td><input type=text name="www" size=30 
  maxlength=100 value="&apos;.$www.&apos;">&apos;;
  echo &apos;</td>
</tr><tr>
<td>Сообщение<font color=#880000>*</font>:</td>
<td><textarea cols=40 rows=5 
  name="message">&apos;.$message.&apos;</textarea>&apos;;
  @error($error[&apos;message&apos;]);
  echo &apos;</td>
</tr><tr>
<td> </td>
<td><small><font color=#880000>*</font>
 � Обязательные поля</small></td>
</tr><tr>
<td> </td>
<td><input name="sb" type=submit 
  value="Добавить сообщение"></td>
</form></tr>
</table>&apos;;
}

/**
* печать одной записи гостевой книги
*/
function template_show_body($id, $name, $email, $www, $message, $datetime)
{
  $out = &apos;<div class=c><div class=cn><b>&apos;.$name.&apos;</b>&apos;;
  // если есть email или homepage - печатаем их
  if($email || $www)
  {
    $out .= &apos;( &apos;;
    if($email)
      $out .= &apos; <a href=mailto:&apos;.$email.&apos;>email</a>&apos;;
    if($email && $www)
      $out .= &apos; | &apos;;
    if($www)
      $out .= &apos; <a href=&apos;.$www.&apos;>www</a>&apos;;
    $out .= &apos; )&apos;;
  }
  $out .= &apos; пишет &apos;.$datetime.&apos;:</div>&apos;.$message.&apos;</div>&apos;;
  // если гостевую книгу просматривает администратор - печатаем кнопку
  // удаления записи
  if(auth_is_admin())
  {
    $out .= &apos;<div class=c>[ <a href=&apos;.PATH.&apos;?admin=1&del=&apos;.$id.
            &apos;>удалить</a> ]</div>&apos;;
  }

  return $out;
}

?>

И вот, мы наконец-то дошли до главного. До модуля гостевой книги. Постараюсь написать побольше комментариев, чтобы вам было понятно.
<?php
/**
* Создание таблицы, если её ещё нет
*/
function gb_install()
{
db_query(
&apos;CREATE TABLE IF NOT EXISTS gb (
id int(10) unsigned NOT NULL auto_increment,
datetime datetime NOT NULL default \&apos;0000-00-00 00:00:00\&apos;,
name varchar(100) NOT NULL default \&apos;\&apos;,
email varchar(100) default NULL,
www varchar(100) default NULL,
message text NOT NULL,
PRIMARY KEY (id),
INDEX (datetime)
) ENGINE=MyISAM;&apos;
);
}

/**
* Добавление записи в гостевую книгу
*/
function gb_add($name, $email, $www, $message, &$error)
{
// проверяем правильность заполнения полей
$error = &apos;&apos;;
if(empty($name))
$error[&apos;name&apos;] = &apos;Это обязательное поле&apos;;
if(empty($message))
$error[&apos;message&apos;] = &apos;Это обязательное поле&apos;;
if(!empty($email) && !strings_isemail($email))
$error[&apos;email&apos;] = &apos;Это не email&apos;;

// если не было ошибок - добавляем
if(!$error)
{
// чистим данные
$name = strings_clear($name);
$message = strings_clear($message);
$name = strings_stripstring($name, 15, 100);
$email = strings_stripstring($email, 100, 100);
$www = strings_stripstring($www, 100, 100);
$message = strings_stripstring($message, 100, 2000);
$message = nl2br($message);

// если пользователь поленился написать http:// перед адресом - сделаем
// это за него
if(!empty($www) && &apos;http://&apos; != substr($www, 0, 7))
$www = &apos;http://&apos;.$www;

// запрос на добавление записи в базу данных
db_query_ex(&apos;INSERT INTO gb (name, email, www, message, datetime)
       VALUES(?, ?, ?, ?, NOW())&apos;, $name, $email, $www, $message);
// перекидываем браузер на первую страницу
// это нужно, чтобы, если пользователь нажмет кнопку Refresh,
// запись не добавилась еще раз
header(&apos;Location: &apos;.PATH."?page=1");
}
}

// удаление записи из гостевой книги
function gb_delete($id)
{
  // запрос на удаление записи из базы данных
  // WHERE id = &apos;.$id указывает на запись, которую следует удалить
  db_query_ex(&apos;DELETE FROM gb WHERE id = ?&apos;, $id);
  header(&apos;Location: &apos;.PATH."?page=1"); // ???
}

// вывод страницы с записями
function gb_show($page)
{
// положение первой записи страницы
$begin = ($page - 1) * 10;
// выборка записей из базы данных
// SELECT * FROM gb - все поля из бд gb
// ORDER BY datetime DESC - сортировка по дате, новые сверху
// LIMIT &apos;.$begin.&apos;,&apos;.RECSPERPAGE - ограничение:
// RECSPERPAGE (см. defines.php) записей начиная с $begin
$result = db_query(&apos;SELECT * FROM gb ORDER BY datetime DESC LIMIT &apos;.
                    $begin.&apos;, &apos;.RECSPERPAGE);
$out = &apos;&apos;;

// цикл по всем выбранным записям
while($row = mysql_fetch_array($result))
$out .= template_show_body($row[&apos;id&apos;], $row[&apos;name&apos;], $row[&apos;email&apos;],
  $row[&apos;www&apos;], $row[&apos;message&apos;], $row[&apos;datetime&apos;]);

// уничтожаем результат
mysql_free_result($result);

echo $out;
}

// вывод списка страниц
function gb_showpages($current)
{
// узнаем число записей в гостевой книге
$result = db_query(&apos;SELECT * FROM gb&apos;);
$rows = mysql_num_rows($result);
if($rows)
{
$pages = ceil($rows / RECSPERPAGE);

// печатаем ссылки на страницы (номер текущей страницы не является ссылкой)
echo &apos;<div class=c>&apos;;
for($i = 1; $i <= $pages; $i++)
{
if($i != $current)
echo &apos; | <a href=&apos;.PATH.&apos;?page=&apos;.$i.&apos;>&apos;.$i.&apos;</a>&apos;;
else
echo &apos; | &apos;.$i;
}
echo &apos; |&apos;;

// если это не полследняя страница печатаем ссылку "Дальше"
if($current < $pages)
echo &apos; >a href=&apos;.PATH.&apos;?page=&apos;.($current + 1).
     &apos;>Дальше >></a>&apos;;
echo &apos;</div>&apos;;
}
}

?>

И последнее - объединяем всё вместе.
<?php
/**
* fjGuestbook 1.2
*
* Ядро гостевой книги
*
* Copyright 2002-2004 Artem Sapegin
* http://sapegin.ru
*/

// подключаем модули
require_once &apos;my/defines.php&apos;;
require_once &apos;my/template.php&apos;;

require_once &apos;engine/lib/strings.php&apos;;
require_once &apos;engine/lib/auth.php&apos;;
require_once &apos;engine/lib/bd.php&apos;;
require_once &apos;engine/gb.php&apos;;

// подключаемся к БД
db_connect(DBHOST, DBUSER, DBPASSWD, DBNAME);

// создаём таблицу, если её нет
gb_install();

// получаем данные формы, если форма была отправлена
if (!empty($_POST[&apos;sb&apos;]))
{
$name = @$_POST[&apos;name&apos;];
$email = @$_POST[&apos;email&apos;];
$www = @$_POST[&apos;www&apos;];
$message = @$_POST[&apos;message&apos;];
$formerr = &apos;&apos;;
}
else
{
$name = $email = $www = $message = $formerr = &apos;&apos;;
}

// если в GET-запросе не указан номер страницы, выводим первую
if(is_numeric(@$_GET[&apos;page&apos;]))
  $page = $_GET[&apos;page&apos;];
else
  $page = 1;

// если нужно добавить запись, добавляем
if(@$_GET[&apos;add&apos;])
  gb_add($name, $email, $www, $message, $formerr);

// если нужно удалить запись, удаляем
if(isset($_GET[&apos;del&apos;]) && auth_is_admin())
  gb_delete(intval($_GET[&apos;del&apos;]));

// печатаем гостевую книгу
template_header($page);
gb_showpages($page);
gb_show($page);
gb_showpages($page);
template_form($name, $email, $www, $message, $formerr);
template_footer();

?>

Как видите, ничего сложного не было. Но если вопросы всё же возникнут - спрашивайте - постараюсь помочь.

Вы так же можете скачать гостевую книгу.
Добавлено: 31 Декабря 2014 13:32:06 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...