Phân trang là kỹ thuật có lẽ đã không còn xa lạ gì với những ai đã và đang viết web. Việc phân trang sẽ giúp cho ứng dụng của bạn thao tác nhanh hơn và gọn hơn mỗi khi đổ dữ liệu ra bên ngoài, vì thế có thể xem nó là một lớp quan trọng trong mọi ứng dụng hiện nay.
Trước hết ta thực hiện việc khởi tạo và khai báo thông tin kết nối cơ sở dữ liệu.
Mã:
CREATE TABLE user (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
username varchar(50) NOT NULL,
password char(32) NOT NULL,
level int(1) NOT NULL DEFAULT '1',
PRIMARY KEY (id)
);
INSERT INTO user(username,password,level) VALUES ('admin', '12345', '2');
INSERT INTO user(username,password,level) VALUES ('kenny', '12345', '2');
INSERT INTO user(username,password,level) VALUES ('jacky', '12345', '1');
INSERT INTO user(username,password,level) VALUES ('vivi', '12345', '1');
INSERT INTO user(username,password,level) VALUES ('abc', '123', '1');
INSERT INTO user(username,password,level) VALUES ('mimi123', '12345', '1');
INSERT INTO user(username,password,level) VALUES ('mimi456', '12345', '1');
INSERT INTO user(username,password,level) VALUES ('mimi789', '123', '1');
Mã:
resources.db.adapter = "Pdo_mysql" resources.db.params.host = "localhost" resources.db.params.username = "root" resources.db.params.password = "" resources.db.params.dbname = "qhonline"
PHP Code:
<?phpclass Model_User extends Zend_Db_Table_Abstract{
protected $_name="user";
protected $_primary="id";
public function listall(){
return $this->fetchAll()->toArray();
}
}
PHP Code:
<?phpclass UserController extends Zend_Controller_Action{
public function indexAction()
{
$muser=new Model_User;
$paginator = Zend_Paginator::factory($muser->listall());
$paginator->setItemCountPerPage(3);
$paginator->setPageRange(3);
$currentPage = $this->_request->getParam('page',1);
$paginator->setCurrentPageNumber($currentPage);
$this->view->data=$paginator;
}
}+ Trước tiên ta nạp model user vào để gọi phương thức listall().
+ Tiếp tục ta khởi tạo lớp Zend_Paginatior và truyền tham số lấy được từ model qua. Tham số này là một mảng liệt kê toàn bộ thành viên có trong bảng.
+ Kế tới ta cấu hình số lượng dữ liệu hiển thị trên trang. Cụ thể trong bài ta đang quy ước là 3 dòng dữ liệu trên 1 trang.
+ Ta cấu hình hiển thị 1 lần chỉ 3 trang.
+ Lấy trang hiện hành và mặc định sẽ là trang một.
+ Đưa tham số trang hiện hành vào phương thức setCurrentPageNumber()
+ Cuối cùng, ta đổ dữ liệu ra view.
Tiếp tục ta tạo view index.phtml tại thư mục: views/script/user/
PHP Code:
<table width='300' align='center' border='1'>
<tr>
<td>User Id</td>
<td>Username</td>
<td>Level</td>
</tr>
<?phpforeach($this->data as $item)
{
echo "<tr>";
echo "<td align='center'>".$item['id']."</td>";
echo "<td align='center'>".$item['username']."</td>";
if($item['level'] == 1){
echo "<td align='center'>Member</td>";
}else{
echo "<td align='center'><font color='red'>Admin</font></td>";
}
echo "</tr>";
}?></table>
<?php
echo $this->paginationControl($this->data, 'Sliding' , 'user/pagination.phtml'); ?>Ở phần cuối ta có thêm đoạn lệnh sau:
PHP Code:
<?php
echo $this->paginationControl($this->data, 'Sliding' , 'user/pagination.phtml'); ?>Tại views/scripts/user tạo file pagination.phtml như cấu hình ở trên với nội dung:
PHP Code:
<?php if ($this->pageCount): ?><div class="paginationControl" align="center">
<?php
if (isset($this->previous)){
echo '<a href="' . $this->url(array('page' => $this->previous)). '"> < Previous</a> | ';
}
foreach ($this->pagesInRange as $page){
if ($page != $this->current){
echo '<a href="' . $this->url(array('page' => $page)). '">' . $page . '</a> | ';
}else{
echo $page . ' | ';
}
}
if (isset($this->next)){
echo '<a href="' . $this->url(array('page' => $this->next)) . '">Next ></a>';
}
?></div>
<?php endif; ?>Về mặt cơ bản thì Zend_Paginator làm công việc đưa tất cả record của câu truy vấn vào trong 1 mảng dữ liệu. Sau đó nó phân trang trực tiếp từ dữ liệu trong mảng này. Điều này trên thực tế thì chỉ có thể đáp ứng được với mô hình dữ liệu nhỏ, vì nếu dùng với hàng trăm ngàn dòng dữ liệu thì có lẽ việc đem chúng đổ vào mảng thôi cũng là điều không đơn giản.
Nhóm phát triển Zend Framework cũng hiểu những khó khăn từ phía người sử dụng về điều này, nên các phiên bản sau này của zend đã hỗ trợ thêm nhiều phương thức nhằm giải quyết bài toán này.
Đó là sử dụng thêm phương thức bên dưới với các tham số truyền vào, trước khi gọi lớp Zend_Paginator.
PHP Code:
new Zend_Paginator_Adapter_DbSelect()
PHP Code:
<?phpclass Model_User extends Zend_Db_Table_Abstract{
protected $_name="user";
protected $_primary="id";
public function listall(){
$query=$this->select();
$query->from($this->_name,array('id','username','level'));
return $query;
}
}Kế tới tại UserController.php ta sửa lại như sau:
PHP Code:
<?phpclass UserController extends Zend_Controller_Action{
public function indexAction(){
$muser=new Model_User;
$adapter = new Zend_Paginator_Adapter_DbSelect($muser->listall());
$paginator = new Zend_Paginator($adapter);
$paginator->setItemCountPerPage(3);
$paginator->setPageRange(3);
$currentPage = $this->_request->getParam('page',1);
$paginator->setCurrentPageNumber($currentPage);
$this->view->data=$paginator;
}
}Ta truyền phương thức listall() vào lớp Zend_Paginator_Adapter_DbSelect. Tại đó, tự nó sẽ biết phải lấy dữ liệu như thế nào. Cuối cùng, thay vì ta dùng Zend_Paginator::factory() thì nay ta khởi tạo hẳn một phương thức và truyền dữ liệu mà ta đã cấu hình ở trên vào.
Chạy ứng dụng, bạn sẽ thấy kết quả giống với lúc ta dùng ở trên.
Vậy liệu chúng có khác gì không ?. Vì dẫu sao cả hai cùng làm công việc hiển thị toàn bộ dữ liệu cơ mà ?.
Giờ bạn hãy mở file index.phtml ra và thêm vào dòng lệnh sau để xem kiến trúc bên trong mảng của data trước khi đổ ra có gì nhé.
PHP Code:
<?php
echo "<pre>";
print_r($this->data);
echo "</pre>";?>Phần bôi đen là phần tôi muốn các bạn chú ý khi tham khảo đoạn thông tin trên từ manual của Zend Framework.
Tải toàn bộ mã nguồn của bài học tại đây
Như vậy, qua phần này. Tôi đã hướng dẫn các bạn bước đầu làm quen và tìm hiểu được lớp Zend_Paginator, từ đó sử dụng chúng cho công việc phân trang dữ liệu trong ứng dụng. Tiếp tục ở bài sau, chúng ta sẽ cùng tìm hiểu về lớp Zend_Form, đồng thời dùng nó để xây dựng các biểu mẫu nhập liệu như thế nào.
(Bùi Quốc Huy)
Không có nhận xét nào:
Đăng nhận xét