将搜索与分页相结合而不是正确输出

时间:2016-09-17 09:18:12

标签: php mysql pagination

目前,分页功能在显示所有结果时工作正常,或者如果我操纵查询以显示特定结果(WHERE X = Y),我可以愉快地遍历所有页面。现在,我试图实现搜索功能。

问题#1 - 它只显示输入搜索结果的第一页,当我转到下一页时,它会显示数据库中的其他项目(与搜索无关)。 [已解决] 请参阅脚本中的更新。

问题#2 - 返回的页数是从整个数据库计算出来的(显示+400页)而不是只有3页,因为搜索结果应为45项。

我的结构概要是:

<?php
//FOR PAGINATION
$pages = new Paginator('15','n'); // number of items to show on each page

$stmt = $db->query("SELECT * FROM items "); //**FOCUS 1**
$pages->set_total($stmt->rowCount()); //pass number of records to PAGINATION

// SEARCH QUERY
if(isset($_GET['search_item'])){ // UPDATE-was POST
    $search_item = $_GET['search_item']; // UPDATE-was POST

    $stmt = $db->prepare("SELECT * FROM items WHERE item_name LIKE   '%".$search_item."%' OR item_code LIKE '%".$search_item."%' ORDER BY item_name ".$pages->get_limit());

$stmt->execute(array("%$search_item%"));
$set_total = ($stmt->rowCount());
//$min_length = 2; not necessary for example
}
?>

<!-- SEARCH FORM -->
<form method="GET" action=""><!-- **FOCUS 2** --> <!-- WAS PREVIOUSLY POST -->
    <input type="text" name="search_item" placeholder="search" style="width:200px;">
    <input type="submit" value="search" id="submit">
</form>

<!-- display results here in table format using while -->

<?php 
// PAGINATION RESULTS/PAGES DISPLAY
echo $pages->page_links('index.php?p=index&search_item='.$search_item.'&'); //**FOCUS 3** // UPDATE-was just  echo $pages->page_links();
?>

分页班:

class Paginator {

    private $_perPage;  // set the number of items per page. |@var numeric
    private $_instance; // set get parameter for fetching the page number | @var string
    private $_page; // sets the page number. | @var numeric
    private $_limit;    // set the limit for the data source | @var string
    private $_totalRows = 0;    // set the total number of records/items. | @var numeric

    // __construct | pass values when class is istantiated | @param numeric     $_perPage  sets the number of iteems per page | @param numeric  $_instance sets the instance for the GET parameter
    public function __construct($perPage,$instance){
        $this->_instance = $instance;
        $this->_perPage = $perPage;
        $this->set_instance();  
    }

    // get_start | creates the starting point for limiting the dataset | @return numeric
    private function get_start(){
        return ($this->_page * $this->_perPage) - $this->_perPage;
    }

    // set_instance | sets the instance parameter, if numeric value is 0 then set to 1 | @var numeric
    private function set_instance(){
        $this->_page = (int) (!isset($_GET[$this->_instance]) ? 1 : $_GET[$this->_instance]); // 1 was changed to 1
        $this->_page = ($this->_page == 0 ? 1 : $this->_page); // 1 was changed to 5
    }

    // set_total | collect a numberic value and assigns it to the totalRows | @var numeric
    public function set_total($_totalRows){
        $this->_totalRows = $_totalRows;
    }

    /**
    * get_limit
    * returns the limit for the data source, calling the get_start method and passing in the number of items perp page
    * @return string
    */
    public function get_limit(){
        return "LIMIT ".$this->get_start().",$this->_perPage";
    }

    /**
    * page_links
    * create the html links for navigating through the dataset
    * @var sting $path optionally set the path for the link
    * @var sting $ext optionally pass in extra parameters to the GET
    * @return string returns the html menu
    */
    public function page_links($path='?',$ext=null) {
        $adjacents = "2";
        $prev = $this->_page - 1;
        $next = $this->_page + 1;
        $lastpage = ceil($this->_totalRows/$this->_perPage);
        $lpm1 = $lastpage - 1;

        $pagination = "";
        if($lastpage > 1) {
        $pagination .= "<div class='pagination'>";
        if ($this->_page > 1)
        $pagination.= "<a href='".$path."$this->_instance=$prev"."$ext'>«</a>";
        else
        $pagination.= "<span class='disabled'>«</span>";   

        if ($lastpage < 7 + ($adjacents * 2)) { //7
            for ($counter = 1; $counter <= $lastpage; $counter++) {
                if ($counter == $this->_page)
                $pagination.= "<span class='current'>$counter</span>";
                else
                $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";                   
            }
        }
        elseif($lastpage > 3 + ($adjacents * 2)) { //3
            if($this->_page < 1 + ($adjacents * 2)) {
                for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) { //4
                    if ($counter == $this->_page)
                    $pagination.= "<span class='current'>$counter</span>";
                    else
                    $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";                   
                }
                $pagination.= "...";
                $pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
                $pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";       
            }
            elseif($lastpage - ($adjacents * 2) > $this->_page && $this->_page > ($adjacents * 2)) {

                $pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
                $pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
                $pagination.= "...";
                for ($counter = $this->_page - $adjacents; $counter <= $this->_page + $adjacents; $counter++) {
                    if ($counter == $this->_page)
                    $pagination.= "<span class='current'>$counter</span>";
                    else
                    $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";                   
                }

                $pagination.= "..";
                $pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
                $pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";       
            } else {

                $pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
                $pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
                $pagination.= "..";
                for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
                    if ($counter == $this->_page)
                    $pagination.= "<span class='current'>$counter</span>";
                    else
                    $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";                   
                }
            }
        }

        if ($this->_page < $counter - 1)
        $pagination.= "<a href='".$path."$this->_instance=$next"."$ext'>»</a>";
        else
        $pagination.= "<span class='disabled'>»</span>";
        $pagination.= "</div>\n";       
    }


    return $pagination;
}
}

尝试解决:

我一直在搞乱代码,不记得我尝试过的所有内容,但我看过的是 FOCUS 区域。

FOCUS 1 我认为为了只为搜索输出的总结果生成分页,我需要添加类似的内容(“WHERE item_name LIKE'%”。$ search_item。“%'” ),当我编码时(“WHERE item_name LIKE'ford')它有效,它显示正确的页数,但是当我循环结果不正确时,只需添加'%'。$ search_item。”%'to查询生成一个未定义的变量错误,我理解为'%'。$ search_item。“%'直到编码后才设置。

焦点2 我尝试将方法更改为操作更改为action="index.php?p=index&search=<?php echo $search_item ;?>". now this changes the URL to what i think should be correct 'index.php?search_item=ford'但它仍然无法正常工作搜索功能,因为我必须硬编码WHERE才能显示结果(FOCUS 1)。

焦点3 我不记得我做了什么,类似于焦点2 中的操作,但是当我在单独的页面上盘旋时,它显示了正确的URL路径我期待。

似乎当我尝试一件事时,它适用于其中一个焦点,但不会在其他地方使用。

CLOSEST IV GOT SO FAR!我现在已经正确显示了项目,并且能够正确循环浏览页面!我已经将上面的代码修改为我现在拥有的内容,以及我在评论中的内容。我现在的问题是显示分页中正确的页数 - 它显示所有+400页面,但是我的搜索变量会传递到每个页面,我可以循环搜索结果并且......它会“切断”它所在的位置例如如果我只有50个结果,那么它将显示第1,2,3页的结果,然后在第4页上显示没有结果。

任何人都可以告诉我我哪里出错或者对我应该看什么有任何建议。

1 个答案:

答案 0 :(得分:1)

焦点1

您的$pages->get_limit()函数是否也返回SQL查询的LIMIT部分?根据我的回复,我假设该方法只返回一个整数。如果是这种情况,那么您的SQL查询中缺少LIMIT

此外,我无法在示例代码中的任何位置看到您获取当前页码以帮助分页。你的Paginator课程提供这个吗?通过下面的示例,我已经分配了一个变量$page,我假设当前页码将在$_GET['page']

试试这个:

$search_item = isset($_GET['search']) ? urldecode($_GET['search']) : null;

$page = 1;
if (isset($_GET['page']) && is_numeric($_GET['page']) && (int)$_GET['page'] > 0)
    $page = (int)$_GET['page'];

if (is_string($search_item) && mb_strlen($search_item) > 0) {
    $stmt = $db->prepare("SELECT * FROM items WHERE item_name LIKE :search_item 
      OR item_code LIKE :search_item ORDER BY item_name ASC LIMIT :limit OFFSET :offset");
} else {
    $stmt = $db->prepare("SELECT * FROM items ORDER BY item_name ASC LIMIT :limit OFFSET :offset");
}

if ($stmt->execute(
  array(
    'search_item' => '%' . $search_item . '%',
    'offset' => ($pages->get_limit() * ($page - 1)),
    'limit' => $pages->get_limit()
  )
)) {
    $set_total = $stmt->rowCount();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

焦点2

或许考虑将form方法更改为GET并使用$_GET收集搜索过滤器,例如关键字和页码(与上面的示例一样)。这样可以使您不必创建会话,并且可以轻松构建分页链接。

示例:

<?php $numPages = ceil($total / $pages->get_limit()); ?>
<ul class="pagination">
    <?php for ($p = 1; $p < ($numPages + 1); $p++) { ?>
        <li>
            <a href="index.php?p=search&search=<?php echo urlencode($search_item); ?>&page=<?php echo $p; ?>">
                <?php echo $p; ?>
            </a>
        </li>
    <?php } ?>
</ul>

或类似的东西: - )