Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Постраничная навигация в поиске
 
 автор: Dizels   (07.08.2010 в 21:00)   письмо автору
 
 

Собственно, нужно сделать чтобы если результатов поиска много (больше 5), то чтобы эти результаты выводились постранично. Собственно, как узнать (какой запрос должен быть?) - сколько строк из базы удовлетворило запросу?

  Ответить  
 
 автор: deimand   (07.08.2010 в 21:06)   письмо автору
 
   для: Dizels   (07.08.2010 в 21:00)
 

передавать все get параметрами в кнопках навигации

site.ru?m=search&q=searchtext&page=1
site.ru?m=search&q=searchtext&page=2
site.ru?m=search&q=searchtext&page=3
site.ru?m=search&q=searchtext&page=4
и так далее...

  Ответить  
 
 автор: Dizels   (07.08.2010 в 21:12)   письмо автору
 
   для: deimand   (07.08.2010 в 21:06)
 

Это мне понятно, тут проблема немного в другом, сейчас поясню:

// Проверяем наличие и число параметров поиска    
    // Артикул
    if(!empty($_POST['art'])) $tmp1 = " and tov_id=".$_POST['art'];    
    // Название
    if(!empty($_POST['name']))
    {
        $name = $_POST['name'];
        $tmp2 = " name LIKE '%$name%' ";
    }
    else $tmp2 = "1";
    // Цена
    if(!empty($_POST['price_min']))
    $tmp3 = " and price>".$_POST['price_min'];
    if(!empty($_POST['price_max']))
    $tmp4 = " and price<".$_POST['price_max'];    
    // Формируем запрос из переданных данных
    $query = "SELECT * FROM textil_tovar
                        WHERE $tmp2
                        ".$tmp1.$tmp3.$tmp4."
                        ORDER BY id";
    // Выполняем SQL-запрос
    $prt = mysql_query($query);
    if(!$prt) puterror("Ошибка");
    // Кол-во рядов в наборе должно быть больше 0
    if (mysql_num_rows($prt)>0)
    {
        // Переменная хранит число записей выводимых на станице 
        $num = 5; 
        // Извлекаем из URL текущую страницу 
        $page = $_GET['page']; 
        // узнаем сколько всего товаров удовлетворило шаблону поиска
        $zzz= mysql_num_rows($prt);
        $posts = mysql_result($zzz,0);
        // Находим общее число страниц 
        //$total = intval(($posts - 1) / $num) + 1; 
        $total = intval($posts / $num); if ($posts % $num) ++$total; 
        // Определяем начало сообщений для текущей страницы 
        $page = intval($page); 
        // Если значение $page меньше единицы или отрицательно 
        // переходим на первую страницу 
        // А если слишком большое, то переходим на последнюю 
        //if(empty($page) or $page < 0) $page = 1; 
        if(empty($page) or $page < 0) $page = 1; 
        if($page > $total) $page = $total; 
        // Вычисляем начиная к какого номера 
        // следует выводить сообщения 
        $start = $page * $num - $num; 

// Выбираем $num сообщений начиная с номера $start 

Вот тут собственно и проблема, так как дальше нужно делать выборку из уже сделанного запроса, а как это сделать - я не могу понять...

  Ответить  
 
 автор: deimand   (07.08.2010 в 21:18)   письмо автору
 
   для: Dizels   (07.08.2010 в 21:12)
 

а можете перед текстом в коде "// Проверяем наличие и число параметров поиска" написать открывающий тег php кода?


<?php 
// раскраска появится

  Ответить  
 
 автор: Dizels   (08.08.2010 в 13:23)   письмо автору
 
   для: deimand   (07.08.2010 в 21:18)
 

Я бы поставил, но увы уже не могу отредактировать сообщение.

  Ответить  
 
 автор: .....   (07.08.2010 в 21:18)
 
   для: Dizels   (07.08.2010 в 21:12)
 

id_theme=60261

  Ответить  
 
 автор: chexov   (08.08.2010 в 12:44)   письмо автору
 
   для: Dizels   (07.08.2010 в 21:12)
 

загоняйте в сессию значения поиска

  Ответить  
 
 автор: Dizels   (08.08.2010 в 13:53)   письмо автору
 
   для: chexov   (08.08.2010 в 12:44)
 

А как это корректно сделать? (С сессиями не разу не работал). Приведите пример кода, пожалуйста.

  Ответить  
 
 автор: bab-nike   (08.08.2010 в 15:24)   письмо автору
 
   для: Dizels   (08.08.2010 в 13:53)
 

Вам надо в запрос добавить LIMIT, ну хотя бы так

<?php
$query
=....//тут ваш запрос
$query_limit sprintf("%s LIMIT %d, %d"$query$startRow$maxRows);
$prtmysql_query($query_limit);
//$startRow = $pageNum * $maxRows;
//$pageNum это текущая страница
//$maxRows = 5;//число записей на одной странице
?>

Ну и конечно отфильтровать GET запросы не забудьте

  Ответить  
 
 автор: Dizels   (14.08.2010 в 17:26)   письмо автору
 
   для: bab-nike   (08.08.2010 в 15:24)
 

<?php
    
// Формируем запрос из переданных данных
    
$query "SELECT * FROM penoteka_tovar
                        WHERE 
$tmp2
                        "
.$tmp1.$tmp3.$tmp4."
                        ORDER BY id"
;

if (!
$_GET['page'])
{
$pageNum "1";
}
else 
$pageNum $_GET['page'];

$startRow $pageNum $maxRows;
//$pageNum это текущая страница
$maxRows 5;//число записей на одной странице
$query_limit sprintf("%s LIMIT %d, %d"$query$startRow$maxRows);
    
// Выполняем SQL-запрос
$prtmysql_query($query_limit);


    if(!
$prtputerror("Ошибка");
    
// Кол-во рядов в наборе должно быть больше 0
    
if (mysql_num_rows($prt)>0)
    {    
    
?>
    <table border="0" width='500'>
        <tr>
            <td width='430' align='left'><font size='2'>Фото</font></td>
            <td width='30'><font size='2'>Описание</font></td>
        </tr>
        <?php
        
while($par mysql_fetch_array($prt))
        {
            echo 
"
                    <tr>
                        <td><a href='tovar.php?id="
.$par['id']."' border='0'><img src='http://pic.krukro.com/public_html/supermarket/products/preview/".$par['photo']."'></a></td>
                        <td><font size='2'>
                        <a href='tovar.php?id="
.$par['id']."'>".$par['name']."</a><br>
                        "
.$par['price']." руб.</font></td>
                    </tr>"
;                        
        }
    }
    else echo 
"Поиск не дал результатов. Попробуйте изменить критерии поиска.";
    echo 
"</table>";
}
?>

исправил все вот так, выводится первая 5-ка. Но если в урл подставляю ?page=2 - то ничего не выводится, хотя элементы удовлетворяющие запросу еще есть - 100%.

  Ответить  
 
 автор: Dizels   (14.08.2010 в 17:48)   письмо автору
 
   для: Dizels   (14.08.2010 в 17:26)
 

Что-то я не то сделал, но что - понять не могу. Вот код:

<?php
// Формируем запрос из переданных данных
    
$query "SELECT * FROM penoteka_tovar
                        WHERE 
$tmp2
                        "
.$tmp1.$tmp3.$tmp4."
                        ORDER BY id"
;

    
// Определяем общее число товаров, удовлетворяющих поиску 
    
$result mysql_query($query);                     
                        
    
//число товаров, выводимых на одной странице
    
$maxRows 5;
            
    
// Находим общее число страниц        
    
$posts mysql_result($result,0);      
    
$total intval($posts $maxRows); if ($posts $maxRows) ++$total;                         
    
    
// выводим общее число товаров и страниц
    
echo "$posts <BR>";
    echo 
$total;                

    
// определяем на какой странице находимся    
    
if (!$_GET['page'])
    {
        
$pageNum "1";
    }
    else 
$pageNum $_GET['page'];

    
// вспомагательная переменная для запроса
    
$startRow $pageNum $maxRows;

    
// ограничиваем запрос $maxRows товарами
    
$query_limit sprintf("%s LIMIT %d, %d"$query$startRow$maxRows);
    
// Выполняем SQL-запрос
    
$prtmysql_query($query_limit);


    if(!
$prtputerror("Ошибка");
    
// Кол-во рядов в наборе должно быть больше 0
    
if (mysql_num_rows($prt)>0)
    {    
    
?>


в поиск вбиваю - отображать все товары от 1 руб. Т.е. должны показаться вообще все товары в базе, а мне в этом месте:

    // выводим общее число товаров и страниц
    echo "$posts <BR>";
    echo $total;

выдает:
1
1

  Ответить  
 
 автор: Trianon   (14.08.2010 в 19:04)   письмо автору
 
   для: Dizels   (14.08.2010 в 17:48)
 

всё верно.

  Ответить  
 
 автор: Dizels   (14.08.2010 в 19:12)   письмо автору
 
   для: Trianon   (14.08.2010 в 19:04)
 

Поясните, пожалуйста.
Я лично не понимаю почему все верно, ведь товаров удовлетворяющих поиску - много (более 20)

  Ответить  
 
 автор: Trianon   (14.08.2010 в 19:35)   письмо автору
 
   для: Dizels   (14.08.2010 в 19:12)
 

Посмотрите же, что возвращает запрос SELECT * FROM penoteka_tovar
И что Вы из этих данных берете посредством mysql_result($result,0)

  Ответить  
 
 автор: Dizels   (14.08.2010 в 20:05)   письмо автору
 
   для: Trianon   (14.08.2010 в 19:35)
 

Я так понимаю, что проблема во в этом:
WHERE $tmp2

когда переменная принимает значение 1

Подскажите тогда, пожалуйста, как правильно переписать данный запрос?

  Ответить  
 
 автор: Trianon   (14.08.2010 в 20:07)   письмо автору
 
   для: Dizels   (14.08.2010 в 20:05)
 

нет. Проблема не в этом, иначе бы я этот фрагмент запроса процитировал.
Выполните простейший запрос
SELECT * FROM penoteka_tovar 

и посмотрите, что он возвращает.


>Подскажите тогда, пожалуйста, как правильно переписать данный запрос?

Правильно переписать можно единственным образом.
Понять, что происходит.
Вы хотите - не понимая.
Такой роскоши я Вам доставить, с некоторых пор, не могу.

  Ответить  
 
 автор: Dizels   (14.08.2010 в 20:14)   письмо автору
 
   для: Trianon   (14.08.2010 в 20:07)
 

Проблема как я понял здесь:
// Находим общее число страниц        
    $posts = mysql_result($result,0);  

0 - это означает номер столбца, который необходимо вернуть.

Верно?

Но, как тогда правильно?

  Ответить  
 
 автор: Trianon   (14.08.2010 в 20:47)   письмо автору
 
   для: Dizels   (14.08.2010 в 20:14)
 

а по-моему 0 у Вас означает номер строки, значение [первого] поля которой надо вернуть.
И что там?

  Ответить  
 
 автор: Dizels   (14.08.2010 в 21:32)   письмо автору
 
   для: Trianon   (14.08.2010 в 20:47)
 

<?php
// Соединяемся с базой данных
require_once $_SERVER['DOCUMENT_ROOT'] . '/admin/config.php';
$query "SELECT * FROM penoteka_tovar";
$z=mysql_query($query);
$posts mysql_result($z,0);
echo 
"$posts";
?>

Выдает: 1
т.е. я так понимаю, что это выдается первая строка (нулевая).

Но тогда мне не понятно, как нужно переписать данный код.
Вернее в теории понятно, что нужно указать, чтобы считал номер последней строки - это и будет кол-во записей. Но как это сделать?

  Ответить  
 
 автор: Trianon   (14.08.2010 в 22:03)   письмо автору
 
   для: Dizels   (14.08.2010 в 21:32)
 

у таблицы нет ни первых строк ни последних.
Все строки в таблице лежат внавал.
Поэтому никакую последнюю строку Вы не получите.

А количество строк определяется через агрегатную функцию COUNT()

  Ответить  
 
 автор: Dizels   (15.08.2010 в 11:45)   письмо автору
 
   для: Trianon   (14.08.2010 в 22:03)
 

Огромное спасибо, вроде разобрался.
Но - появилась еще одна проблема:
форма поиска у меня в отдельном файле - searchform.php:
<center>
<b>Поиск по каталогу:</b>
</center>
<form action="search.php" method="post">
    <font size='2'>
    Артикул: <input size=6 type=text name=art value=<?php echo $_POST['art']; ?>><br>
    Название: <input type=text name=name value=<?php echo $_POST['name']; ?>>    <br>                            
    Цена от <input size=4 type=text name=price_min value=<?php $_POST['price_min'?>>
        до <input size=4 type=text name=price_max value=<?php $_POST['price_max'?>><br>
    <input type="submit" value="Искать">    
    <input type="hidden" name="search" value="search">
    </font>
</form>

вот файл обработчик search.php:


<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/penoteka/searchform.php';
// Скрипт обработчик
if(isset($_POST['search']))
{
    
?>
    <br>
    <center>Результаты поиска:</center>
    <br>
    <?php
    
// Флаг равен true, если есть хотя бы один критерий поиска
    
$is_query false;
    
    
// Проверяем наличие и число параметров поиска
    
    // Артикул
    
if(!empty($_POST['art'])) $tmp1 " and tov_id=".$_POST['art'];
    
    
// Название
    
if(!empty($_POST['name']))
    {
        
$name $_POST['name'];
        
$tmp2 " name LIKE '%$name%' ";
    }
    else 
$tmp2 "1";
    
// Цена
    
if(!empty($_POST['price_min']))
    
$tmp3 " and price>".$_POST['price_min'];
    if(!empty(
$_POST['price_max']))
    
$tmp4 " and price<".$_POST['price_max'];
            
    
// Переменная хранит число записей выводимых на станице 
    
$num 5
    
// Извлекаем из URL текущую страницу 
    
if(!empty($_GET['page']))
    {
    
$page $_GET['page'];
    }
    else 
$page 1;
    
// Определяем общее число сообщений в базе данных 
    
$result mysql_query("SELECT count(*) FROM penoteka_tovar
                        WHERE 
$tmp2
                        "
.$tmp1.$tmp3.$tmp4."
                        ORDER BY id"
); 
            
$posts mysql_result($result,0);      
            
// Находим общее число страниц 
            //$total = intval(($posts - 1) / $num) + 1; 
            
$total intval($posts $num); if ($posts $num) ++$total
            
// Определяем начало сообщений для текущей страницы 
            
$page intval($page); 
            
// Если значение $page меньше единицы или отрицательно 
            // переходим на первую страницу 
            // А если слишком большое, то переходим на последнюю 
             
if(empty($page) or $page 0$page 1
            if(
$page $total$page $total
            
// Вычисляем начиная c какого номера 
            // следует выводить сообщения 
            
$start $page $num $num;     


echo 
"
$posts <br>
$total <br>
$page  <br>
$start <br>
"
;

            
            
// Выбираем $num сообщений начиная с номера $start                         
            
$res mysql_query("SELECT * FROM penoteka_tovar
                        WHERE 
$tmp2
                        "
.$tmp1.$tmp3.$tmp4." LIMIT $start$num"); 
                        
            while(
$f mysql_fetch_array($res))
            {
            
?>
                <table border="0" width='500'>
        <tr>
            <td width='430' align='left'><font size='2'>Фото</font></td>
            <td width='30'><font size='2'>Описание</font></td>
        </tr>
        <?php
        
            
echo "
                    <tr>
                        <td><a href='tovar.php?id="
.$f['id']."' border='0'><img src='preview/".$f['photo']."'></a></td>
                        <td><font size='2'>
                        <a href='tovar.php?id="
.$f['id']."'>".$f['name']."</a><br>
                        "
.$f['price']." руб.</font></td>
                    </tr>"
;                        
        
    }
    echo 
"</table>";

?>
                
                <?php
            
}
            
            
            
// Проверяем нужны ли стрелки назад 
            
if ($page != 1$pervpage '<a class=lm href= ./search.php?page=1>1</a> ...
            <a class=lm href= ./search.php?page='
. ($page 1) .'>предыдущая</a>'
            
// Проверяем нужны ли стрелки вперед 
            
if ($page != $total$nextpage ' <a class=lm  href= ./search.php?page='. ($page 1) .'>следующая</a> 
                                    ... <a class=lm  href= ./search.php?page=' 
.$total'>' .$total'</a>'
            
// Находим две ближайшие станицы с обоих краев, если они есть 
            
if($page 0$page2left ' <a class=lm  href= ./search.php?page='. ($page 2) .'>'. ($page 2) .'</a> | '
            if(
$page 0$page1left '<a class=lm  href= ./search.php?page='. ($page 1) .'>'. ($page 1) .'</a> | '
            if(
$page <= $total$page2right ' | <a class=lm  href= ./search.php?page='. ($page 2) .'>'. ($page 2) .'</a>'
            if(
$page <= $total$page1right ' | <a class=lm  href= ./search.php?page='. ($page 1) .'>'. ($page 1) .'</a>';
            
// Вывод меню 
            
echo '<center>'.$pervpage.$page2left.$page1left.'<b>'.$page.'</b>'.$page1right.$page2right.$nextpage.'</center>'
            
?>


И получается так, что первую страницу выдает как надо, а при переходе на вторую и другие - выдаются только номера страниц. Почему это происходит - я понял: не передаются параметры из формы поиска. Но вот как сделать, чтобы они передавались - не могу понять.
И еще сразу один вопрос: если в форму поиска в строку "название" вбивать 2 слова, к примеру: "ручка шариковая" - то после передачи параметров и вывода результатов в форме отображается только первое слово, в данном примере - ручка.
Почему такое происходит? И как это исправить?

  Ответить  
 
 автор: Trianon   (15.08.2010 в 11:52)   письмо автору
 
   для: Dizels   (15.08.2010 в 11:45)
 

>Огромное спасибо, вроде разобрался.
>Но - появилась еще одна проблема:
Судя по тому, что ниже - не одна.

>И получается так, что первую страницу выдает как надо, а при переходе на вторую и другие - выдаются только номера страниц. Почему это происходит - я понял: не передаются параметры из формы поиска. Но вот как сделать, чтобы они передавались - не могу понять.

для начала определитесь, каким методом ( GET или POST ) Вы будете обращаться к страницам.
Выберете что-то одно.


>И еще сразу один вопрос: если в форму поиска в строку "название" вбивать 2 слова, к примеру: "ручка шариковая" - то после передачи параметров и вывода результатов в форме отображается только первое слово, в данном примере - ручка.
>Почему такое происходит?

Посмотреть HTML-код формы.

>И как это исправить?

и исправить.

  Ответить  
 
 автор: Dizels   (15.08.2010 в 21:09)   письмо автору
 
   для: Trianon   (15.08.2010 в 11:52)
 

> Посмотреть HTML-код формы.
> и исправить.

Сделал, спасибо.


> для начала определитесь, каким методом ( GET или POST ) Вы будете обращаться к страницам.
Выберете что-то одно.

Я так понимаю, что в данном случае лучше и безопаснее будет POST. Но вот тогда - мне не понятно, как реализовать переход по самим страницам (т.е. корректную передачу переменной $page) - может приведете какой пример? Или же подскажете как это сделать?

  Ответить  
 
 автор: Dizels   (17.08.2010 в 10:38)   письмо автору
 
   для: Dizels   (15.08.2010 в 21:09)
 

Все еще нужно помощь в осознании того, как передавать переменную $page

  Ответить  
 
 автор: Trianon   (17.08.2010 в 12:12)   письмо автору
 
   для: Dizels   (15.08.2010 в 21:09)
 

>> Посмотреть HTML-код формы.
>> и исправить.
>
>Сделал, спасибо.
>
>
>> для начала определитесь, каким методом ( GET или POST ) Вы будете обращаться к страницам.
>Выберете что-то одно.
>
>Я так понимаю, что в данном случае лучше и безопаснее будет POST.
Чем же это проще?
По-моему, это как раз сложнее.
Каким боком метод обработки соотносится с безопасностью?

>Но вот тогда - мне не понятно, как реализовать переход по самим страницам (т.е. корректную передачу переменной $page) - может приведете какой пример? Или же подскажете как это сделать?

Обычно как раз делают GET.
POST делают для запросов, которые изменяют состояние сервера (вносчят данные в БД, меняют значения и т.п)
А читающие запросы обычно обрабатывают через GET

Но если Вы так хотите - делайте форму с кнопками навигации.

  Ответить  
 
 автор: Dizels   (17.08.2010 в 19:18)   письмо автору
 
   для: Trianon   (17.08.2010 в 12:12)
 

Переделал, через Get - все работает вроде:)

Но - теперь нашел еще один косяк:
если вводить в поиск два слова, к примеру ручка шариковая - то возможны 2 вараинта:
1) если в записи эти слова идут вместе - то выдаст запись как результат поиска
2) если не вместе (ручка уникальная шариковая) - то выдает, что ничего не найдено.

Я так понимаю, что это из-за того, как я ищу:
на данный момент это выглядит так:
$tmp2 = " name LIKE '%$name%' ";

а мне нужен полнотекстовый поиск по столбцу name.

Для этого проделал следующее:
в sql-таблице сделал запрос:

ALTER TABLE `penoteka_tovar` ADD FULLTEXT (`name`)

а в файле search.php переписал так:

<?php
if(!empty($_GET['name']))
    {
        
$name $_GET['name'];
        
$name trim($name);
        
$temp strtok($name," ");
        while (
$temp)
        {
            
$search .= "MATCH (name) AGAINST ('$temp')";
            
$temp strtok(" ");
        }
    }
...
$res mysql_query("SELECT * FROM penoteka_tovar
                        WHERE 
$search
                        "
.$tmp1.$tmp3.$tmp4." LIMIT $start$num"); 

Но, выдает ошибку и ничего не находит. Подскажите, что сделал не так?

  Ответить  
 
 автор: oliss   (18.08.2010 в 07:15)   письмо автору
 
   для: Dizels   (17.08.2010 в 19:18)
 

а ОШИБКУ ТЯЖЕЛО БЫЛО НАПИСАТЬ .
.ДА-ДА ТУ КОТОРУЮ ВЫДАЁТ СКРИПТ
смотрите
 "MATCH (name) AGAINST

  Ответить  
 
 автор: Dizels   (18.08.2010 в 15:33)   письмо автору
 
   для: oliss   (18.08.2010 в 07:15)
 

вот ошибка:
Warning: mysql_result(): supplied argument is not a valid MySQL result resource in /home/u35265//www/penoteka/search.php on line 71

  Ответить  
 
 автор: Dizels   (18.08.2010 в 21:40)   письмо автору
 
   для: Dizels   (18.08.2010 в 15:33)
 

проблема все еще актуальна.

  Ответить  
 
 автор: Trianon   (18.08.2010 в 22:51)   письмо автору
 
   для: Dizels   (18.08.2010 в 15:33)
 

это не та ошибка

  Ответить  
 
 автор: Dizels   (21.08.2010 в 16:16)   письмо автору
 
   для: Trianon   (18.08.2010 в 22:51)
 

// Определяем общее число сообщений в базе данных 
    $result = mysql_query("SELECT count(*) FROM penoteka_tovar
                        WHERE $tmp2
                        ".$tmp1.$tmp3.$tmp4."
                        ORDER BY id"); 
            $posts = mysql_result($result,0);      

71 строка эта:
$posts = mysql_result($result,0);  

  Ответить  
 
 автор: Dizels   (23.08.2010 в 12:01)   письмо автору
 
   для: Dizels   (21.08.2010 в 16:16)
 

Пожалуйста, подскажите что не так. Если я чего-то не выкладываю, чтобы понять проблему - дайте понять что именно нужно.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования