PHP. Разработка модуля комментариев для сайта - Дмитрий Приходько
9.2.2 Форма поиска
Так как не исключена ситуация, что в комментариях нам надо будет, что-нибудь искать, поэтому создадим для страницы комментариев форму поиска «search.html.php»
Листинг 19. search.html.php Путь: news/chat/admin/ search.html.php
<form action="" method="post" class="stat">
<center>
Панель информации:
</center>
<fieldset>
<div>
<label for="author">Пользователь:</label>
<select name="author" id="author">
<option value="">Все пользователи</option>
<?php foreach ($users as $user) : ?>
<option value="<?php htmlout($user['id']); ?>"><?php
htmlout($user['login']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="category">Раздел:</label>
<select name="category" id="category">
<option value="all">Все разделы</option>
<option value="say">Комментарии</option>
<option value="reply">Ответы</option>
</select>
</div>
<div class="textsearch">
<label for="text">Содержит текст:</label>
<input type="text" name="text" id="text">
</div>
<div class="textsearch_button">
<input type="hidden" name="action" value="search">
<input type="submit" value="Искать">
</div>
</fieldset><!– END fieldset –>
<fieldset>
<legend>Выборка для: </legend>
<h5 class="user"><?= $legend ?></h4>
</fieldset>
<fieldset>
<legend>Список пользователей:</legend>
<ul style="list-style-type:none;padding:0px;margin:5px;">
<?php foreach ($users as $user): ?>
<li style="border-bottom:1px solid lightgray; margin-bottom:5px;">
<?php
htmlout($user['id']); echo '.   ';
htmlout($user['login']);
?>
</li>
<?php endforeach; ?>
</ul>
</fieldset>
</form>
Обычная HTML форма в полях <fieldset> которой, сгруппированы параметры для поиска и фильтрации данных. Поиск ведется по тексту. Результаты можно отфильтровать по логину пользователя и разделу.
Форма сгруппирована из блоков:
• Панель информации – общий контейнер для блоков.
• Пользователи – выпадающий список <select> пользователей.
• Раздел – выпадающий список <select> разделов, их всего три «Все разделы», «Комментарии» и «Ответы».
• Поле ввода поискового запроса и кнопка для оправки этого запроса «Искать».
Данные из формы отправляются на обработку в файл comment.php.
9.2.3 Скрипт обработки страницы комментариев
Обработкой данных на странице комментариев будет заниматься файл «comment.php».
Листинг 20. comment.php Путь: news/chat/admin/ comment.php
<?php
error_reporting(E_ALL);
include_once $_SERVER['DOCUMENT_ROOT'] . '/chat/dsn.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/chat/admin/clean.php';
//Пользователи для панели информации
try {
$result = $dsn->query('SELECT id, login FROM users');
} catch (PDOException $e) {
echo $e->getMessage();
echo $e->getLine();
exit('Ошибка поиска пользователя в базе комментариев');
}
foreach ($result as $row) {
$users[] = array('id' => $row['id'], 'login' => $row['login']);
}
/* Получаем логин пользователя при запросе */
if (isset($_POST['author']) and $_POST['author'] != '') {
try {
$sql = 'SELECT login FROM users WHERE id = :id';
$s = $dsn->prepare($sql);
$s->bindValue(':id', $_POST['author']);
$s->execute();
$legend = $s->fetchColumn(0);
} catch (PDOException $e) {
echo $e->getMessage();
echo $e->getLine();
exit('Ошибка поиска логина в базе комментариев');
}
} else {
$legend = '';
}
/* Start. Работаем с комментариями */
//если выбрано поле "ответы" выходим и ничего не делаем в разделе "комментарии"
if (isset($_POST['category']) and $_POST['category'] == 'reply') {
}
/* иначе формируем запрос к базе */
elseif (isset($_POST['action']) and $_POST['action'] == 'search' or !isset($_POST['action'])) {
include $_SERVER['DOCUMENT_ROOT'] . '/chat/dsn.php';
// Базовое выражение SELECT.
$select = 'SELECT say.id, say.userid, say.saytext, say.saydate';
$from = ' FROM say INNER JOIN users ON say.userid = users.id';
$where = ' WHERE TRUE';
$sequence = array();
// Автор выбран
if (isset($_POST['author']) and $_POST['author'] != '') {
$where .= " AND userid = :userid";
$sequence[':userid'] = $_POST['author'];
}
// Была указана какая-то искомая строка
if (isset($_POST['text']) and $_POST['text'] != '') {
$where .= " AND saytext LIKE :saytext";
$sequence[':saytext'] = '%' . $_POST['text'] . '%';
}
try {
$sql = $select . $from . $where;
$s = $dsn->prepare($sql);
$s->execute($sequence);
} catch (PDOException $e) {
echo $e->getMessage();
echo $e->getLine();
exit('Ошибка при извлечении комментариев');
}
foreach ($s as $row) {
$says[] = array('id' => $row['id'], 'userid' => $row['userid'], 'text' => $row['saytext'], 'saydate' => $row['saydate']);
}
}
/* End. Завершаем обработку комментариев */
/* Start. Работаем с ответами на комментарии */
//если выбрано поле "комментарии" выходим и ничего не делаем в разделе "ответы"
if (isset($_POST['category']) and $_POST['category'] == 'say') {
}
/* иначе формируем запрос к базе */ elseif (isset($_POST['action']) and $_POST['action'] == 'search' or !isset($_POST['action'])) {
include $_SERVER['DOCUMENT_ROOT'] . '/chat/dsn.php';
// Базовое выражение SELECT.
$select = 'SELECT reply.userid, reply.replytext,reply.replyid, reply.replydate ';
$from = ' FROM reply INNER JOIN users ON reply.userid = users.id ';
$where = ' WHERE TRUE';
$order = ' ORDER BY reply.replyid';
$sequencer = array();
if (isset($_POST['author']) and $_POST['author'] != '') { // Автор выбран
$where .= " AND userid = :userid";
$sequencer[':userid'] = $_POST['author'];
}
if (isset($_POST['text']) and $_POST['text'] != '') { // Была указана какая-то искомая строка
$where .= " AND replytext LIKE :replytext";
$sequencer[':replytext'] = '%' . $_POST['text'] . '%';
}
try {
$sql = $select . $from . $where . $order;
$s = $dsn->prepare($sql);
$s->execute($sequencer);
} catch (PDOException $e) {
echo $e->getMessage();
echo $e->getLine();
exit('Ошибка при извлечении ответов на комментарии');
}
foreach ($s as $row) {
$replys[] = array('replyid' => $row['replyid'], 'userid' => $row['userid'], 'replytext' => $row['replytext'], 'replydate' => $row['replydate']);
}
}
include_once $_SERVER['DOCUMENT_ROOT'] . '/chat/admin/comment.html.php';
Вывод информации производится в соответствии с условиями заданными в форме поиска: по имени пользователя, по разделу, по искомому тексту.
В начале скрипта делаем выборку из БД всех пользователей. Затем получаем из БД логин пользователя, для которого выполняется поиск.
Создаем запрос SELECT, зависящий от указанных в форме условий. Сначала определим строки, объединение которых формирует запрос SELECT в том случае, если не выбран ни один критерий, строки находятся в переменных:
$select, $from и $where.
Если кнопка «Искать» не нажималась, то $_POST['action'] будет отсутствовать и будут, отображены все комментарии и ответы них.
Т.к. базовое выражение SELECT собирается из тех критериев, что выбраны в форме, то в запросе будут операторы FROM и WHERE. Если критерии не заданы (то есть нужно получить все данные из БД), WHERE будет ненужной. Добавлять выражения к несуществующему оператору проблематично, поэтому подставляем такую команду, которая никак не повлияет на результат, если ее опустить. Здесь подойдет выражение WHERE TRUE, которое всегда истинно.
Для добавления новой строки к существующей используется оператор конкатенации (.=). В этом скрипте к оператору WHERE добавляется условие, по которому содержимое поля userid из таблицы say должно совпадать со значением псевдопеременной :userid. Вначале скрипта с помощью метода bindValue установить требуемое общее значение $_POST['author'] нельзя т.к. еще не подготовлен объект параметризированного запроса, из которого этот метод вызывается. Вследствие этого запрос разбросан по вышеперечисленным строкам ($select, $from и $where).
Инициализируем массив $sequence для сохранения параметризированных переменных, используя их имена в качестве индексов. В массиве будет храниться id пользователя и текст поискового запроса. Содержимое массива:
$sequence (
:userid => "$_POST['author']",
:saytext => "'%'.$_POST['text'].'%'"
);
где "$_POST['author']" = $user['id'].
Чтобы получить