|
Очень распространенная задача для веб-мастера – как написать гостевую книгу на 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', 'example@sexample.ru'); // 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 не было. Данный скрипт не является абсолютно верным решением, лучше будет, если Вы его перед применением подредактируете и проверите на уязвимости. |