Yêu cầu thg 11 1, 2018 3:09 CH 2148 0 1
  • 2148 0 1
0

Vấn đề về phân trang trong PHP

Chia sẻ
  • 2148 0 1

Mình đang gặp vấn đề về thuật toán phân trang trong PHP. Đây là code của mình:

//Xử lý phân trang PHP

//Tìm tổng số records
$sql1 = "select count(id) as total from phan_trang";
$query1 = mysqli_query($conn, $sql1);
$result1 = mysqli_fetch_array($query1);
$total_record = $result1['total'];

//Tìm limit và current_page
if (isset($_GET['page']))   {
    $current_page = $_GET['page'];
}
else {
    $current_page = "1";
}

$limit = "10";

//tính total_page(số trang cần chia)
$total_page = ceil($total_record/$limit);


//giới hạn current_page trong khoảng từ 1 -> total_page
if ($current_page > $total_page)    {
    $current_page = $total_page;
}
else if ($current_page < 1) {
    $current_page = 1;
}


//tìm start
$start = ($current_page - 1)*$limit;
?>




<html>
    <div class="add_form">
        <form action="add_process.php" method="post">
            <label>NAME:</label>
            <input type="text" name="name">
            <input type="hidden" name="id" value="<?php echo $id;?>">
            <input type="submit" name="btsubmit" value="ADD">
        </form>
    </div>

    <div class="table_view">
        <table>
            <tr>
                <th>STT</th>
                <th>ID</th>
                <th>NAME</th>
            </tr>
            <?php
            //danh sách phân trang
            $sql = "select * from phan_trang limit $start, $limit";

            $query = mysqli_query($conn, $sql);

            $stt = 1;

            while ($result = mysqli_fetch_array($query))    {
                echo'<tr>
                        <td>'.$stt.'</td>
                        <td>'.$result['id'].'</td>
                        <td>'.$result['name'].'</td>
                    </tr>';
                $stt++;
            }
            ?>
        </table>
    </div>

    **<div class="thanh_phan_trang">
        <?php

        if ($current_page >= 2 && $current_page <= $total_page-1 || $current_page == $total_page)  {
            echo'<a href="#">PREV</a>   ';
        }

        $b = $current_page - 2;
        $c = $current_page + 2;

        if ($b <= 0)    {
            $c -= ($b - 1);
            $b = 1;
        }

        if ($c > $total_page)   {
            $c = $total_page;
            $b = $b - 1 ;
        }

        for ($a = $b; $a <= $c; $a++)    {
            if ($a == $current_page)    {
                echo'<span style="background-color: blue; color: white">'.$a.'</span>   ';
            }
            else    {
                echo'<a href="index.php?page='.$a.'">'.$a.'</a>   ';
            }
        }

        if ($current_page >= 2 && $current_page <= $total_page-1 || $current_page == 1 )  {
            echo'<a href="#">NEXT</a>   ';
        }

        ?>
    </div>**

Mục đích của mình là muốn hiển thị thanh phấn trang với tối đa 5 ô chọn trang (còn lại thì Prev và Next). và trang đang ở thì nằm giữa. Ngoại trừ 2 trang đầu và cuối thì lùi dần về 2 bên (ví dụ trang 1 thì ở ngoài cùng, trang 2 lùi vào 1 ô, trang 3 thì ở giữa, cứ thế đến trang cuồi cùng -1 thì ở gần ngoài và trang cuối ở ngoài cùng).

Mình mới chỉ làm được một nửa, vì ở trang cuối cùng thì hiển thị ra là 4 ô chọn chứ không phải 5 ô như mong đợi. Mình nghĩ ở đây là do thuật toán ở đoạn if $c > $total page có vấn đề. Mong mọi người giúp đỡ.

Avatar Tran Duc Thang @thangtd90
thg 11 2, 2018 1:55 SA

Theo mình hiểu thì với trường hợp bạn đang ở trang 10, chẳng hạn, thì ô phân trang của bạn sẽ hiển thị là

(< Previous) (8) (9) (10) (11) (12) (Next >)

đúng không nhỉ 🤔

vì ở trang cuối cùng thì hiển thị ra là 4 ô chọn chứ không phải 5 ô như mong đợi

Cụ thể thì với trường hợp người dùng đang ở trang cuối cùng thì bạn kỳ vọng hiển thị ra thế nào nhỉ, bởi vì sau đó đâu còn trang nào nữa 🤔

Avatar Vượng @vuongnq000
thg 11 2, 2018 2:41 SA

@thangtd90 ý mình là ví dụ như có tổng cộng 10 trang chẳng hạn, thì khi ta đang ở trang cuối cùng thì sẽ như thế này:

(< Previous) (6) (7) (8) (9) [10]

(Ở đây đang ở trang 10 nên trang 10 sẽ được tô đậm lên để khác với các trang còn lại. Và vì là trang cuối cùng nên sẽ không hiển thị nút Next)

Còn nếu ở trang 9:

(< Previous) (6) (7) (8) [9] (10) (Next >)

(Vẫn hiển thị từ trang 6 > 10 (5 trang chọn), và vì không phải trang cuối cùng nên vẫn hiển thị nút Next)

Trang 8:

(< Previous) (6) (7) [8] (9) (10) (Next >)

Bắt đầu từ trang 7 (khi trang được chọn chuyển về giữa) thì mới bắt đầu thay đổi:

(< Previous) (5) (6) [7] (8) (9) (Next >)

Từ trang 7 trở về trang 3 thì trang hiện tại được tô đậm sẽ luôn ở giữa. Cho đến trang 2 và 1 thì lùi dần về ngoài cùng:

(< Previous) (1) (2) [3] (4) (5) (Next >)
(< Previous) (1) [2] (3) (4) (5) (Next >)
[1] (2) (3) (4) (5) (Next >)

1 CÂU TRẢ LỜI


Đã trả lời thg 11 2, 2018 3:12 SA
Đã được chấp nhận
+4

Bạn thử tham khảo cách sau xem 😄

Mình vừa nghĩ vừa code thẳng trên này luôn, nên không đảm bảo nó sẽ chạy được luôn đâu, bạn check qua nhé 😄

// $currentPage số trang hiện tại 
// $totalPage tổng số trang
$pagination = [$currentPage]; // Đây là mảng lưu các trang sẽ xuất hiện ở phần phân trang
while (count($pagination) < 5) { // Sẽ chạy vòng lặp cho đến khi nào mảng này có đủ 5 phần tử thì thôi
    $left = $pagination[0] - 1; // Phần tử tiếp theo ở bên trái sẽ là phần tử bên trái ở thời điểm hiện tại trừ đi 1
    $right = $pagination[count($pagination) - 1] + 1; // Phần tử tiếp theo ở bên phải sẽ là phần tử bên phải ở thời điểm hiện tại cộng với 1
    $added = false; // Biến để kiểm tra xem có trang mới được thêm vào không
    if ($left > 0) {
        array_unshift($pagination, $left); // Đẩy page mới vào đầu mảng 
        $added = true;
    }
    if ($right <= $totalPage) {
        array_push($pagination, $right); // Đẩy page mới vào cuối mảng 
        $added = true;
    }
    if (!$added) { // Nếu cả bên trái lẫn bên phải đều không thể thêm phần tử nào vào nữa, thì break khỏi vòng lặp
        break;
    }
}
// Sau vòng lặp này bạn sẽ có một mảng có tối đa là 5 trang
if ($pagination[0] != $currentPage) { // Nếu trang ngoài cùng bên trái, mà không phải là current page, thì sẽ có nút Previous 
     array_unshift($pagination, '< Previous');
}

if ($pagination[count($pagination) - 1] != $currentPage) { // Nếu trang ngoài cùng bên phải, mà không phải là current page, thì sẽ có nút Next 
     array_push($pagination, 'Next >');
}

// Đến đây bạn sẽ có mảng $pagination chứa đủ Previous, Next, lẫn 5 trang xung quanh currentPage, bạn chỉ cần foreach rồi in ra thôi :D
Chia sẻ
Avatar Vượng @vuongnq000
thg 11 2, 2018 5:20 SA

Ồ được rồi nè. Cảm ơn bạn nhiều nhé!!! Thế mà mình nghĩ mãi không ra...

Avatar Tran Duc Thang @thangtd90
thg 11 2, 2018 5:38 SA
Avatar Truong Dang @xdangminhtruongx
thg 11 2, 2018 7:36 SA

@thangtd90 mình vừa nghĩ vừa code thẳng trên này luôn 😂😂😂(baiphuc)

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí