Как сделать пагинацию плюс сортировка php

По отдельности все это я сделал, и сортировку и пагинацию, но теперь вопрос в другом, как мне перезаписывать переменые если я меняю сортировку или перехожу на следующую страничку


Ответы (3 шт):

Автор решения: Istinnavvine
    function product_sort()
{
    $url_val = explode("=",$_SERVER['QUERY_STRING']);

        $_GET['sort'];

        
        echo '  <a href="?sort=name">
                    <div class="sort" id="byname">Name</div>
                </a>';
                    
        echo    '<a href="?sort=price">
                        <div class="sort" id="byprice">Price</div>
                    </a>';
        echo    '<a href="?sort=populary">
                    <div class="sort" id="bycategory">Popular</div>
                </a>';
        
}

    function pagination()
{
    include("connect.php");

    $sortbyVAL = ($_GET['sort']) ? $_GET['sort'] : 'name';
    $cur_page = ($_GET['page']) ? $_GET['page'] : 1;

    $productsOnPage = 8;

    $from = ($cur_page-1)*$productsOnPage;

    $q = "SELECT images.image_url as image, products.name as name, products.price as price , products.id as id from products
                JOIN images on images.product_id = products.id group by name order by $sortbyVAL LIMIT $from, $productsOnPage";

    $q = $connect->prepare($q);
    $q->execute();

    $arr = $q->fetchAll(PDO::FETCH_ASSOC);

    echo "<div class='product-list row'>";
        foreach($arr as $k)
        {
            echo '
                    <a href="/pages/product.php?id='.$k["id"].'" class="product-box">
                            <div class="img-box">
                                <img src="/img/'.$k['image'].'" alt="">
                            </div>
                            <div class="product-info-box col">
                                <div class="product-name text">'.$k['name'].'</div>
                                <div class="price">'.$k['price'].'$</div>
                            </div>
                    </a>
                ';
        }
    echo "</div>";

    $q = "SELECT count(*) as count from products";
    $q = $connect->prepare($q);

    $q->execute();

    $count = $q->fetch(PDO::FETCH_ASSOC);

    $pagesCount = ceil($count['count'] / $productsOnPage);


    echo '<div class="paginations row">';
        for($i = 1; $i<=$pagesCount;$i++)
        {
            echo "<a href=\"?page=$i \" class=\"pagination heading active\">$i</a>";
        }
    echo '</div>';
}
→ Ссылка
Автор решения: Sergei Kirjanov

Сортировка и пагинация -- состояния, которые хранятся в URL.

Нужны 2 функции, которые переводят состояния из URL в массив ["sort"=>"name",...] и обратно. В них нет ничего про сортировку и пагинацию.

В случае php в одну сторону получается само -- $_GET

Когда формируем href -- меняем копию состояния-массивa, и переводим обратно в URL (в href)


Через sortbyVAL может быть сделана SQL инъекция.

Старайтесь не вклеивать переменные в запрос, а использовать prepare/bind/execute. A если приходится вклеивать, ходошо проверять содержимое.

sort-у сделать bind не получится (скорее всего) -- приходится вклеивать, и хорошо проверять содержимое.

A page сделать bind получится (скорее всего).


function build_ref($key,$value){
    $param = $_GET; # $param копируется в $_GET ; это работает для array ; для object перекладывается ссылка
    $param[$key] = $value;
    return $_SERVER['ORIG_PATH_INFO']."?".http_build_query($param);
}
function active_class($is){
    return $is ? "active" : "";
}
# имя функции отражает то, что она делет
function print_prod_list(){ 
# проверяем, что в $_GET["sort"] то, что мы задумали, а не инъекция в подарок от хакеров
    $allow_sort = ["name"=>1,"price"=>1];
    $active_sort = isset($allow_sort[$_GET["sort"]]) ? $_GET["sort"] : "name";
# page пойдет в bind; тут не проверяем
    $active_page_str = isset($_GET["page"]) ? $_GET["page"] : "1"; 
#
    foreach(["1","2","3"] as $page) 
        echo '<a href="'.build_ref("page",$page).'" class="goto-page '.active_class($active_page_str===$page).'">'.$page.'</a>';
    foreach(["name","price"] as $col) 
        echo '<a href="'.build_ref("sort",$col).'" class="sort '.active_class($_GET["sort"]===$col).'">'.$col.'</a>';
# ... тут будет sql и т. д.
}
print_prod_list();
→ Ссылка
Автор решения: Istinnavvine
    function get_url($key = null)
{
    $url = ((!empty($_SERVER['HTTPS'])) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

    $parts = parse_url($url); 
    if (!empty($parts['query'])) {
        parse_str($parts['query'], $query); 
        if (is_null($key)) {
            return $query;
        } elseif (isset($query[$key])) {
            return $query[$key];
        }        
    }
 
    return false;
}

    function product_sort()
{
        $u = get_url();

        $g = $u['page'] ? "?page=".$u['page']."&" : "?";
        
        echo '  <a href="'. $g .'sort=name">
                    <div class="sort" id="byname">Name</div>
                </a>';
                    
        echo    '<a href="'.$g.'sort=price">
                        <div class="sort" id="byprice">Price</div>
                    </a>';
        echo    '<a href="'.$g.'sort=populary">
                    <div class="sort" id="bycategory">Popular</div>
                </a>';
        
}
    function pagination()
{
    include("connect.php");

    $sortbyVAL = ($_GET['sort']) ? $_GET['sort'] : 'name';
    $cur_page = ($_GET['page']) ? $_GET['page'] : 1;

    $productsOnPage = 2;

    $from = (intval($cur_page)-1)*$productsOnPage;

    $q = "SELECT images.image_url as image, products.name as name, products.price as price , products.id as id from products
                JOIN images on images.product_id = products.id group by name order by $sortbyVAL LIMIT $from, $productsOnPage";

    $q = $connect->prepare($q);
    $q->execute();

    $arr = $q->fetchAll(PDO::FETCH_ASSOC);

    echo "<div class='product-list row'>";
        foreach($arr as $k)
        {
            echo '
                    <a href="/pages/product.php?id='.$k["id"].'" class="product-box">
                            <div class="img-box">
                                <img src="/img/'.$k['image'].'" alt="">
                            </div>
                            <div class="product-info-box col">
                                <div class="product-name text">'.$k['name'].'</div>
                                <div class="price">'.$k['price'].'$</div>
                            </div>
                    </a>
                ';
        }
    echo "</div>";

    $q = "SELECT count(*) as count from products";
    $q = $connect->prepare($q);

    $q->execute();

    $count = $q->fetch(PDO::FETCH_ASSOC);

    $pagesCount = ceil($count['count'] / $productsOnPage);


    $u = get_url();

    $g = $u['sort'] ? "?sort=".$u['sort']."&" : "?";

    echo '<div class="paginations row">';
        for($i = 1; $i<=$pagesCount;$i++)
        {
            echo "<a href='".$g."page=$i' class=\"pagination heading active\">$i</a>";
        }
    echo '</div>';
}
→ Ссылка