Главная | Учебник | Статьи | FAQ | Книги | Ссылки |
Гостевая книга на PHP/MySQL
Artem Sapegin
http://sapegin.ru
Сегодня расскажу вам о том, как написать гостевую книгу на 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('PATH', '/gb/'); // путь к гостевой книге define('RECSPERPAGE', 10); // количество записей на одной странице define('ADMIN_EMAIL', 'artem@sapegin.ru'); // email администратора define('ERROR_LOG_FILE', 'logs/error.log'); // файл лога ошибок // Параметры БД define('DBHOST', 'localhost'); // имя хоста define('DBUSER', 'root'); // имя пользователя define('DBPASSWD', ''); // пароль define('DBNAME', 'test'); // имя базы данных ?>
Теперь подумаем, какие вспомогательные функции нам понадобятся. На нужно будет взаимодействовать с СУБД, проверят и обрабатывать вводимые пользователем данные. Так же для функций администрирования на понадобится отличать администратора от простых пользователей.
Начнём с работы с СУБД.
<?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); } ?>
Написание аутентификации администратора я оставляю вам в качестве домашнего задания. Есть достаточно много способов и их обсуждение - тема отдельной статьи. Я приведу лишь функцию-заглушку:
<?php /** * Проверка: администратор или обычный пользователь */ function auth_is_admin() { return @$_GET['admin']; } ?>
Далее идёт достаточно большой модуль, в котором содержится почти весь 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 © 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 '<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); // перекидываем браузер на первую страницу // это нужно, чтобы, если пользователь нажмет кнопку Refresh, // запись не добавилась еще раз 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 /** * fjGuestbook 1.2 * * Ядро гостевой книги * * Copyright 2002-2004 Artem Sapegin * http://sapegin.ru */ // подключаем модули 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(); ?>
Как видите, ничего сложного не было. Но если вопросы всё же возникнут - спрашивайте - постараюсь помочь.
Вы так же можете скачать гостевую книгу.