Очень распространенная задача для веб-мастера – как написать гостевую книгу на PHP и MySQL. Конечно же можно скачать готовый скрипт и вклеить его в свой дизайн сайта, что настоятельно не рекомендую делать. Причин для этого несколько: используя готовые скрипты мы ничему не научимся, руками мы сделаем защищённую, аккуратную и «быструю» гостевую книгу, что не всигда скажешь о скаченных.
Ничего сложного в этом нет (вполне нормальный урок для начинающего программиста на php и MySQL), да и возможности самой гостевой не самые большие: проверка вводимых пользователем данных, запись их в базу данных, постраничный вывод, возможность удалять записи. Для тех, кто хочет больше возможностей, советую создать редактирование записей и комментирование их (так же несложно).
Допустим, что у вас уже настроен PHP, MySQL и веб-сервер. Если нет и Вы не хотите возиться с муторной настройкой, то скачайте Denver – автоматически настроенный сервер, всё что нам понадобиться там ест: Apach + 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)
);
Теперь можно приступать к написанию самого скрипта. Для начала создадим файл с настройками гостевой книги. Советую делать подобный файл при написании всех скриптов (и инклудить его где необходимо функциями include(‘falename’) или once_include(‘filename’)).
С помощью такого файлы можно быстро редактировать настройки, не разбираясь в написанном коде:
<?php
// константы
define('PATH', '/gb/'); // путь к скрипту гостевой книги
define('RECSPERPAGE', 10); // количество записей на одной странице
define('ADMIN_EMAIL', '
[email protected]Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script '); // email изменить на свой
define('ERROR_LOG_FILE', 'logs/error.log'); // файл лога ошибок
// Параметры Базы Данны
define('DBHOST', 'localhost'); // имя хоста
define('DBUSER', 'root'); // имя пользователя
define('DBPASSWD', ''); // пароль пользователя к БД
define('DBNAME', 'test'); // имя базы данных
?>
Подумаем, какие функции в гостевой книге нам понадобятся. Нам необходимо будет взаимодействовать с СУБД (напомню, мы выбрали MySQL), обрабатывать вводимые пользователем данные (никогда «не доверяйте» вводимым в формы данным). Так же для функций администрирования нам понадобится отличать администратора от простых пользователей (на будущее лучше выводить админ-пенель для редактирования в отдельный фал и вообще в отдельную директорию, закрывая её пароль).
Начнём с работы с СУБД.
<?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('Could not connect to database');
mysql_select_db($dbname) or die('Could not select database');
return $link;
}
/** Выполняет запрос к БД
*
* @param текст запроса
* @return resource id
*/
function db_query($query) {
$result = mysql_query($query)
or die('Bad database query');
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('%?%e', '"'".addslashes($values[$i++])."'"',
$query));
}
?>
Проверка и фильтрация вводимых пользователем данных).
<?php
/**
* Проверяет является ли строка адресом e-mail
*/
function strings_isemail($string) {
return preg_match('%[-.w]+@[-w]+(?:.[-w]+)+%', $string);
}
/**
* Добавление ссылок на http и e-mail
*/
function strings_addlinks($string) {
return preg_replace('%((?:http|ftp)://[-w]+(?:.[-w]+)+b[-w:@&?=+,!/~*$.'%]*)(?<![.,?!)])%i','<a href="\1">\1<a>',$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('%(S{'.$wrap.'})%', '\1 , $text);
return substr($text, 0, $length);
}
?>
Написание аутентификации для администратора (отличить обычного пользователя от пользователя с возможностями удаления и редактирования) я оставляю вам как «домашнее задание». Есть достаточно много способов и их обсуждение - тема отдельной статьи. Я
Далее идёт достаточно большой модуль, в котором содержится почти весь 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>Гостевая книга</h1><?php
}
/**
* подвал страницы
*/
function template_footer() {
?>
<p>Гостевая книга Copyright © 2008
<a href="http://www.woolfs.ru">CyberWoolfs – уроки создания сайтов</a></p>
</body></html>
<?php
}
/**
* форма добавления новой записи
*/
function template_form($name, $email, $www, $message, $error) {
// вывод сообщения об ошибке
function error($error) {
if($error) echo '<br><font color=#880000>'.$error.
'</font>';
}
echo '<h2>Добавить новое сообщение</h2>
<p><table cellspacing="2" cellpadding="2" border="0">
<form action='.PATH.'?add=1 method=post><tr>
<td>Имя<font color=#880000>*</font>:</td>
<td><input type=text name="name" size=30
maxlength=100 value="'.$name.'">';
@error($error['name']);
echo '</td>
</tr><tr>
<td>Email:</td>
<td><input type=text name="email" size=30
maxlength=100 value="'.$email.'">';
@error($error['email']);
echo '</td>
</tr><tr>
<td>URL:</td>
<td><input type=text name="www" size=30
maxlength=100 value="'.$www.'">';
echo '</td>
</tr><tr>
<td>Сообщение<font color=#880000>*</font>:</td>
<td><textarea cols=40 rows=5
name="message">'.$message.'</textarea>';
@error($error['message']);
echo '</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>';
}
/**
* печать одной записи гостевой книги
*/
function template_show_body($id, $name, $email, $www, $message, $datetime) {
$out = '<div class=c><div class=cn><b>'.$name.'</b>';
// если есть email или homepage - печатаем и
if($email || $www) {
$out .= '( ';
if($email) $out .= ' <a href=mailto:'.$email.'>email</a>';
if($email && $www) $out .= ' | ';
if($www) $out .= ' <a href='.$www.'>www</a>';
$out .= ' )';
}
$out .= ' пишет '.$datetime.':</div>'.$message.'</div>';
// если гостевую книгу просматривает администратор - выводим кнопку
// удаления ненужной нам записи
if(auth_is_admin()) {
$out .= '<div class=c>[ <a href='.PATH.'?admin=1&del='.$id.
'>удалить</a> ]</div>';
}
return $out;
}
?>
И вот, мы наконец-то дошли до главного. До модуля гостевой книги. Постараюсь написать побольше комментариев, чтобы вам было понятно.
<?php
/**
* Создание таблицы, если её ещё нет
*/
function gb_install() {
db_query(
'CREATE TABLE IF NOT EXISTS gb (
id int(10) unsigned NOT NULL auto_increment,
datetime datetime NOT NULL default '0000-00-00 00:00:00',
name varchar(100) NOT NULL default '',
email varchar(100) default NULL,
www varchar(100) default NULL,
message text NOT NULL,
PRIMARY KEY (id),
INDEX (datetime)
) TYPE=MyISAM;'
);
}
/**
* Добавление записи в гостевую книгу
*/
function gb_add($name, $email, $www, $message, &$error) {
// проверяем правильность заполнения полей
$error = '';
if(empty($name))
$error['name'] = 'Это обязательное поле';
if(empty($message))
$error['message'] = 'Это обязательное поле';
if(!empty($email) && !strings_isemail($email))
$error['email'] = 'Это не email';
// если не было ошибок - добавляем
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) && 'http://' != substr($www, 0, 7))
$www = 'http://'.$www;
// запрос на добавление записи в базу данных
db_query_ex('INSERT INTO gb (name, email, www, message, datetime)
VALUES(?, ?, ?, ?, NOW())', $name, $email, $www, $message);
// перекидываем браузер на первую страницу
header('Location: '.PATH."?page=1");
}
}
// удаление записи из гостевой книги
function gb_delete($id) {
// запрос на удаление записи из базы данных
// WHERE id = '.$id указывает на запись, которую следует удалить
db_query_ex('DELETE FROM gb WHERE id = ?', $id);
// И снова перекидываем пользователя
header('Location: '.PATH."?page=1"); // ???
}
// вывод страницы с записями
function gb_show($page) {
// положение первой записи страницы
$begin = ($page - 1) * 10;
// выборка записей из базы данных
// SELECT * FROM gb - все поля из бд gb
// ORDER BY datetime DESC - сортировка по дате, новые сверху
// LIMIT '.$begin.','.RECSPERPAGE - ограничение:
// RECSPERPAGE (см. defines.php) записей начиная с $begin
$result = db_query('SELECT * FROM gb ORDER BY datetime DESC LIMIT '.
$begin.', '.RECSPERPAGE);
$out = '';
// цикл по всем выбранным записям
while($row = mysql_fetch_array($result))
$out .= template_show_body($row['id'], $row['name'], $row['email'],
$row['www'], $row['message'], $row['datetime']);
// уничтожаем результат
mysql_free_result($result);
echo $out;
}
// вывод списка страниц
function gb_showpages($current) {
// узнаем число записей в гостевой книге
$result = db_query('SELECT * FROM gb');
$rows = mysql_num_rows($result);
if($rows) {
$pages = ceil($rows / RECSPERPAGE);
// печатаем ссылки на страницы (номер текущей страницы не является ссылкой)
echo '<div class=c>';
for($i = 1; $i <= $pages; $i++) {
if($i != $current)
echo ' | <a href='.PATH.'?page='.$i.'>'.$i.'</a>';
else
echo ' | '.$i;
}
echo ' |';
// если это не полследняя страница печатаем ссылку "Дальше"
if($current < $pages)
echo ' >a href='.PATH.'?page='.($current + 1).
'>Дальше >></a>';
echo '</div>';
}
}
?>
И наконец, последний штрих – объединяем это вместе:
<?php
// подключаем модули
require_once 'my/defines.php';
require_once 'my/template.php';
require_once 'engine/lib/strings.php';
require_once 'engine/lib/auth.php';
require_once 'engine/lib/bd.php';
require_once 'engine/gb.php';
// подключаемся к БД
db_connect(DBHOST, DBUSER, DBPASSWD, DBNAME);
// создаём таблицу, если её нет
gb_install();
// получаем данные формы, если форма была отправлена
if (!empty($_POST['sb'])) {
$name = @$_POST['name'];
$email = @$_POST['email'];
$www = @$_POST['www'];
$message = @$_POST['message'];
$formerr = '';
}
else {
$name = $email = $www = $message = $formerr = '';
}
// если в GET-запросе не указан номер страницы, выводим первую
if(is_numeric(@$_GET['page']))
$page = $_GET['page'];
else
$page = 1;
// если нужно добавить запись, добавляем
if(@$_GET['add'])
gb_add($name, $email, $www, $message, $formerr);
// если нужно удалить запись, удаляем
if(isset($_GET['del']) && auth_is_admin())
gb_delete(intval($_GET['del']));
// печатаем гостевую книгу
template_header($page);
gb_showpages($page);
gb_show($page);
gb_showpages($page);
template_form($name, $email, $www, $message, $formerr);
template_footer();
?>
Как видите, несмотря на слегка объёмный код, ничего сложного в гостевой книге на php и mysql не было. Данный скрипт не является абсолютно верным решением, лучше будет, если Вы его перед применением подредактируете и проверите на уязвимости.