Danh mục : Thiết kế website

Cách làm phân trang trong PHP

Cách làm phân trang trong PHP

Mình sẽ cố gắng viết bài này một cách đơn giản nhất (step by step) để các bạn mới bắt đầu viết code có thể tham khảo:

 1. Giả sử ta có database như hình bên dưới

tên database : qlbansua
có 1 table tên là: sua

2. Để hiển thị danh sách sửa lên trang index.php, ta làm như sau:

index.php

<?php
$conn  = mysql_connect(‘localhost’, ‘root’, ‘xxxxx’);
$db  = mysql_select_db(‘qlbansua’);

$result = mysql_query(‘select * from sua’);

echo ‘<table border=”1″>’;
echo ‘<tr>
<th width=”50″>Mã</th>
<th width=”150″>Tên</th>
<th width=”200″>Mô tả</th>
</tr>’;
while ($row = mysql_fetch_assoc($result)) {
echo ‘<tr>
<td>’, $row['ma'],’</td>
<td>’, $row['ten'],’</td>
<td>’, $row['mota'],’</td>
</tr>’;
}
echo ‘</table>’;
?>

3. Chạy thử file trên ta có kết quả như sau:

 

Các bạn thấy đó điều gì sẽ xảy ra nếu danh sách sữa của chúng ta có đến hàng nghàn record. Làm sao người dung có thể xem hết tất cả (mà không bị qua mắt). Từ đây người ta phát sinh thuật ngữ phân trang, mục đích là chia danh sách sữa ra làm nhiều trang, mỗi trang khỏang 10 đến 20 record. Như vậy mỗi lần người dùng chỉ nhìn khỏang 20 record, nên không bị qua mắt.

Đối với  ví dụ trên, nếu mỗi  trang ta  chỉ cho hiển thị 10 record, thì chúng ta sẽ có  2 trang.
+ Trang 1 có 10 record từ loại sữa có “Mã=1″ đến “Mã=10″.
+ Trang 2 có 2 record từ loại sữa có “Mã=11″ đến “Mã=12″

4. Phân trang

Như vậy làm sao biết khi nào người dung muốn xem trang 1, khi nào muốn xem trang 2,….

Ta sẽ qui định cho họ luôn, như sau:

+ Nếu họ truy cập vào địa chỉ: http://localhost/index.php  , hoặc http://localhost/index.php?page=1 thì sẽ xem được trang 1 của ta
+ Nếu họ truy cập vào địa chỉ: http://localhost/index.php?page=2 thì sẽ xem được trang 2 của ta
… tương tự cho n page

Ở đây tôi dùng biến page, các bạn có thể dùng bất cứ biến gì tùy thích

5. Lý thuyết MySQL

Chúng ta đã qua được phần qui định cho người sử dụng, bây giờ làm sao query được 10 record tương ứng với từng trang đây.

Ở trên, ta dùng câu query: “select * from sua”  ==> cái này thì cho ra tất cả record.

Làm sao lấy được 10 record bất kỳ đây. Rất may!!! là MySQL có hỗ trợ cho ta việc này, bằng cách chèn thêm cụm từ khóa sau đây vào sau câu query “LIMIT vi_tri_bat_dau, so_luong_can_lay”.

Tức là:

“select *  from sua limit 0, 10″      ==> dùng để lấy 10 record, bắt đầu từ vị trí thứ 0 (như vậy có nghĩa là nó sẽ trả ra: 10 record từ loại sữa có “Mã=1″ đến “Mã=10″)

“select *  from sua limit 10, 10″      ==> dùng để lấy 10 record, bắt đầu từ vị trí thứ 10 ( do dữ liệu hiện tại của chúng ta từ vị trí thứ 10, chỉ còn 2 record nên nó sẽ trả ra: 2 record từ loại sữa có “Mã=11″ đến “Mã=12″)

6.Áp dụng vào php

Mừng quá!!!! vậy là bên mysql đã hỗ trợ việc lấy record theo ý của ta rồi, còn chằng chờ gì nữa, áp dụng vào file index.php thôi, bạn mở file index.php, chúng ta cùng nhau suy luận một tí:

Nếu  người dùng muốn xem trang 1 thì ta query từ vị trí thứ 0 trở đi 10 record
Nếu  người dùng muốn xem trang 2 thì ta query từ vị trí thứ 10 trở đi 10 record
Nếu  người dùng muốn xem trang 3 thì ta query từ vị trí thứ 20 trở đi 10 record
Nếu  người dùng muốn xem trang 4 thì ta query từ vị trí thứ 30 trở đi 10 record
Nếu  người dùng muốn xem trang 5 thì ta query từ vị trí thứ 40 trở đi 10 record
…..

Nhận xét:
+ Thành phần thứ 2 của cụm LIMIT là không đổi (lúc nào cũng 10 record), nên ta thông qua nó
+
Nếu trang 1 thì vị trí thứ 0
Nếu trang 2 thì vị trí thứ 10
Nếu trang 3 thì vị trí thứ 20
Nếu trang 4 thì vị trí thứ 30

Bạn suy nghĩ gì về mối quan hệ giữa “vị trí” và “trang”. Mình sẽ đố bạn bài toán sau: mình có 2 biến $page, $vitri, bạn tìm dùm mình một công thức liên hệ giữa 2 biến đó, sao cho, nếu mình gán $page=1 thì $vitri = 0, nếu $page=2 thì $vitri=10,…

2 phút suy nghĩ bắt đầu…………..

Reng reng reng……….. hết giờ: bạn có kết quả chưa?

Công thức của mình thì như thế này:

$vitri = ($page -1)  * 10 ;

7. Nâng cấp file index.php

<?php
$conn  = mysql_connect(‘localhost’, ‘root’, ‘password’);
$db  = mysql_select_db(‘qlbansua’);

 $vitri = ($_GET['page'] – 1) * 10;
$result = mysql_query(‘select * from sua limit ‘.$vitri.’, 10′);

echo ‘<table border=”1″>’;
echo ‘<tr>
<th width=”50″>Mã</th>
<th width=”150″>Tên</th>
<th width=”200″>Mô tả</th>
</tr>’;
while ($row = mysql_fetch_assoc($result)) {
echo ‘<tr>
<td>’, $row['ma'],’</td>
<td>’, $row['ten'],’</td>
<td>’, $row['mota'],’</td>
</tr>’;
}
echo ‘</table>’;
?>

Sau khi nâng cấp file index.php ta thử truy cập vào trang 1 và trang 2, sẽ được kết quả như  2 hình  bên dưới

8. File index.php có lỗi:

Điều gì sẽ xảy ra, nếu bạn truy cập vào link sau: http://localhost/index.php  ==> bị lỗi ngay. Lý đó là trên link không tồn tại page nên ta không thể lấy được.

Như đã qui ước ở nên, nếu không tồn tại page thì mặc nhiên sẽ là trang 1, nên ta chỉnh lại file index.php như sau:

<?php
$conn  = mysql_connect(‘localhost’, ‘root’, ‘password’);
$db  = mysql_select_db(‘qlbansua’);

if (!isset($_GET['page'])) {
$_GET['page'] = 1;
}
$vitri = ($_GET['page'] – 1) * 10;
$result = mysql_query(‘select * from sua limit ‘.$vitri.’, 10′);

echo ‘<table border=”1″>’;
echo ‘<tr>
<th width=”50″>Mã</th>
<th width=”150″>Tên</th>
<th width=”200″>Mô tả</th>
</tr>’;
while ($row = mysql_fetch_assoc($result)) {
echo ‘<tr>
<td>’, $row['ma'],’</td>
<td>’, $row['ten'],’</td>
<td>’, $row['mota'],’</td>
</tr>’;
}
echo ‘</table>’;
?>

9. Một câu hỏi nữa

Người dùng sẽ hỏi chúng ta, làm sao tôi biết dữ liệu của anh có bao nhiêu trang?

Bạn trả lời cho họ rằng: “thì anh cứ lần lượt nhấn page=1, page=2,….page=n khi nào nó hết ra thì thôi” ,  hehehehehehe. Ai mà trả lời như vậy đúng không?

Chỉ cần vài phép toán đơn giản sẽ ra thôi, cùng nhau suy luận nào:
Nếu có tất cả là 12 record thì sẽ có 2 trang
Nếu có tất cả là 20 record thì sẽ có 2 trang
Nếu có tất cả là 25 record thì sẽ có 3 trang
Nếu có tất cả là 30 record thì sẽ có 3 trang
Nếu có tất cả là 39 record thì sẽ có 4 trang
Nếu có tất cả là 41 record thì sẽ có 5 trang
……
Bạn hãy nghĩ là công thức liên hệ giữa $tong_so_record và $tong_so_trang

2phút bắt đầu……………….

reng reng…………….hết giờ.

Công thức sẽ là:
$tong_so_trang = floor($tong_so_record/10) + 1;   //floor: lấy phần nguyên, tức là floor(1.2) = 1  ,  floor(2.9) = 2;

10. Nâng cấp file index.php thôi nào

<?php�
$conn  = mysql_connect(‘localhost’, ‘root’, ‘password’);
$db  = mysql_select_db(‘qlbansua’);

if (!isset($_GET['page'])) {
$_GET['page'] = 1;
}
$vitri = ($_GET['page'] – 1) * 10;
$result = mysql_query(‘select * from sua limit ‘.$vitri.’, 10′);

echo ‘<table border=”1″>’;
echo ‘<tr>
<th width=”50″>Mã</th>
<th width=”150″>Tên</th>
<th width=”200″>Mô tả</th>
</tr>’;
while ($row = mysql_fetch_assoc($result)) {
echo ‘<tr>
<td>’, $row['ma'],’</td>
<td>’, $row['ten'],’</td>
<td>’, $row['mota'],’</td>
</tr>’;
}
echo ‘</table>’;

$re = mysql_query(‘select * from sua’);
$n = mysql_num_rows($re);
$tong_so_trang = floor($n/10) + 1;
echo ‘Tong so trang la: ‘.$tong_so_trang;

?>

==> Chạy thử lại, ta

11. Lỡ sướng rồi, cho sướng luôn đi

Người dùng sẽ yêu cầu ta làm cho họ các link tương ứng với các trang, để click vào cho sướng (chứ hiện tại muốn qua trang khác, phải click trên thanh address cực quá).

Ok, có được $tong_so_trang rồi, ta chỉ việc thực hiện vòng lặp for, in ra là xong.

File index.php sẽ được nâng cấp như sau:

<?php�
$conn  = mysql_connect(‘localhost’, ‘root’, ‘password’);
$db  = mysql_select_db(‘qlbansua’);

if (!isset($_GET['page'])) {
$_GET['page'] = 1;
}
$vitri = ($_GET['page'] – 1) * 10;
$result = mysql_query(‘select * from sua limit ‘.$vitri.’, 10′);

echo ‘<table border=”1″>’;
echo ‘<tr>
<th width=”50″>Mã</th>
<th width=”150″>Tên</th>
<th width=”200″>Mô tả</th>
</tr>’;
while ($row = mysql_fetch_assoc($result)) {
echo ‘<tr>
<td>’, $row['ma'],’</td>
<td>’, $row['ten'],’</td>
<td>’, $row['mota'],’</td>
</tr>’;
}
echo ‘</table>’;

$re = mysql_query(‘select * from sua’);
$n = mysql_num_rows($re);
$tong_so_trang = floor($n/10) + 1;
for ($i=1 ; $i<=$tong_so_trang ; $i++) {
echo ‘<a href=”index.php?page=’.$i.’”>Trang’.$i.’</a> ‘;
}
?>

12. Nâng cấp tí nữa

Người dùng sẽ hỏi ta: nhìn vào danh sách Trang1, Trang2,… làm sao biết hiện tại đang đứng ở trang nào?

Ok, trong lúc for, chỉ cần ta so sánh $i với $_GET['page'], nếu bằng nhau, thì $i đó chính là trang hiện tại.

Ta chỉnh lại vòng lặp for như sau:

 for ($i=1 ; $i<=$tong_so_trang ; $i++) {
if ($i == $_GET['page']) {
echo ‘[Trang'.$i.'] ‘;
} else {
echo ‘<a href=”index.php?page=’.$i.’”>Trang’.$i.’</a> ‘;
}
}

13. Gắn thêm nút back, next

Bạn thử nghĩ xem, khi nhấn vào nút back thì sẽ link đến trang nào?  ==> Có phải là trang hiện tại  trừ đi 1 không? (Trang hiện tại chính là $_GET['page'])
Như vậy tương tự link của nút next là: trang hiện tại công thêm 1.

Trước vòng lặp for ta sẽ gắn nút back, sau vòng lặp for ta sẽ gắn nút next

echo ‘<a href=”index.php?page=’.($_GET['page']-1).’”>back</a> ‘;

 for ($i=1 ; $i<=$tong_so_trang ; $i++) {
if ($i == $_GET['page']) {
echo ‘[Trang'.$i.'] ‘;
} else {
echo ‘<a href=”index.php?page=’.$i.’”>Trang’.$i.’</a> ‘;
}
}

echo ‘ <a href=”index.php?page=’.($_GET['page']+1).’”>next</a>’;

14. Sẽ có lỗi đấy

Bạn thử nghĩ xem điều gì sẽ xảy ra: nếu đang đứng ở trang 1 mà nhấn nút back, hoặc đang đứng ở trang cuối cùng mà  nhấn nút next. ==> Sẽ xảy ra lỗi đúng không?

Như vậy ta sẽ chỉnh thêm tí nữa cho hoàn hảo:
+ Điều kiện để hiển thị nút back là trang hiện tại lớn hơn 1
+ Điều kiện để hiển thị nút next là trang hịên tại nhỏ hơn $tong_so_trang

if ($_GET['page'] > 1) { echo ‘<a href=”index.php?page=’.($_GET['page']-1).’”>back</a> ‘;}

 for ($i=1 ; $i<=$tong_so_trang ; $i++) {
if ($i == $_GET['page']) {
echo ‘[Trang'.$i.'] ‘;
} else {
echo ‘<a href=”index.php?page=’.$i.’”>Trang’.$i.’</a> ‘;
}
}

if ($_GET['page'] < $tong_so_trang) { echo ‘ <a href=”index.php?page=’.($_GET['page']+1).’”>next</a>’;}

Xong.

Bài viết này chỉ ở mức cơ bản, nhằm giới thiệu đến các bạn các bước cơ bản trong quá trình xử lý phân trang. Hy vọng nó sẽ là nền tảng để các hiểu và xử lý các vấn đề phức tạp hơn.


Tags
Viết comment
Nội dung
Name
Danh sách comment

Ý kiến của bạn