Lúc này ứng dụng zf của chúng ta sẽ có cấu trúc như hình sau: Như vậy, ta phải thiết lập ứng dụng theo mô hình ở trên.. Ứng với các layouts ta cũng có các file css, image và các thông ti
Trang 1Biên soạn:
GV Bùi Quốc Huy – C.E.O/Founder QHOnline www.qhonline.edu.vn – www.qhonline.info
Lưu hành nội bộ
Trang 2Giáo trình: PHP Framework
Project Training Xây dựng ứng dụng nhỏ với Zend 1.xA- Thiết lập, cấu hình cho blog:
Để thực thi tốt cho việc cấu hình blog này Ta sử dụng zend tool hoặc tự cấu hình theo bài hướng dẫn này:
ung-dung-theo-mo-hinh-module.html
http://www.qhonline.info/zend-framework/73/zend-framework-huong-dan-cau-hinh-Để tạo cấu trúc mặc định, sau đó ta thiết lập theo hướng cơ bản mà ta luôn mong muốn
Lúc này ứng dụng zf của chúng ta sẽ có cấu trúc như hình sau:
Như vậy, ta phải thiết lập ứng dụng theo mô hình ở trên Mô hình này phân tách ứng dụng theo 2 module là admin và default Đi kèm với 2 module này là 2 giao diện tương ứng
Để có được mô hình trên ta phải cấu hình và thiết lập như sau
Tại file index.php ta chỉnh lại:
Trang 3// Create application, bootstrap, and run
$application = new Zend_Application(
includePaths.library = APPLICATION_PATH "/ /library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
Trang 4Vì ở cấu trúc dạng module nên tại các thư mục khác ta cũng phải thiết lập file
bootstrap.php như sau:
Vậy nên ta sẽ tự tạo một lớp có tên QHO_Controller_Action Đây là lớp đặt trong thư viện (library/QHO/Controller/Action.php)
Lớp này sẽ kế thừa lớp Zend_Controller_Action Chính vì vậy, nó sẽ mang đầy đủ các phương thức cơ bản của lớp này giống với những gì mà chúng ta đã từng làm trước đây
Để ZF hiểu được cấu trúc như vậy, bắt buộc các bạn phải thêm vào file application.ini như sau:
autoloadernamespaces.app = "QHO_"
Trang 5Đoạn code này sẽ chỉ ra tiếp vị ngữ của chúng ta là QHO.
Và hiển nhiên tại các controller chúng ta chỉ cần đoạn mã kế thừa đơn giản để xử lý chúng Chẳng hạn, tôi sử dụng IndexController với thông tin như sau:
<?php
class Admin_IndexController extends QHO_Controller_Action {
public function indexAction(){
echo 'Ban dang truy cap vao Admin Module';
}
}
Như thế ứng với từng controller chúng ta chỉ cần extends QHO_Controller_Action thì
sẽ giải quyết được bài toán này
Vậy tại lớp QHO_Controller_Action ta sẽ làm gì ?
Xét class trên ta sẽ hiểu rõ chức năng và nhiệm vụ của chúng
Vậy ta thiết lập phương thức init() để chúng thiết lập mặc định việc lấy thông tin module này Nhưng nhớ rằng sử dụng từ khóa parent::init() để chắc chắn rằng phương thức init() của chúng ta không bị ghi đè lên các phương thức khác
Trang 6Tại đây ta lấy thông tin bằng cú pháp getModuleName() Sau đó gán biến $dirtemp bằng với đường dẫn của thư mục scripts (ứng với từng module riêng biệt).
Và cuối cùng ta triệu gọi module như cú pháp ở trên Lúc này, ta đã hoàn tất 1 việc gọi và xác định layout nào cho từng module
Ứng với các layouts ta cũng có các file css, image và các thông tin file phụ tương ứng.Nên lúc này ta cũng cần gọi thông tin của chúng tại phương thức init() này luôn:
$title="Admin Control Panel 1.0";
Trang 7Để load thông tin css, image, script chúng ta bắt buộc sử dụng phương thức getBaseUrl() để lấy được đường dẫn thực trong ứng dụng (lưu ý không thể gọi theo đường dẫn vật lý trên ứng dụng như chúng ta đã từng làm).
Hiện tại, ta đang xây dựng module admin, nên thiết kế module admin này sẽ như sau:+ Đầu tiên là file styles.css được lưu tại: templates/admin/layouts/scripts/css
Trang 11+ File top.phtml đơn giản:
< div id =top>< img src ="<?php echo $this->dirimg; ?>/banner.gif" />
< li >< a href =""> Add categorie </ a ></ li >
< li >< a href =" "> Manage categorie </ a ></ li >
< li >< a href =""> Add Entry </ a ></ li >
< li >< a href =" "> Manage Entry </ a ></ li >
< li >< a href =" "> Manage Comment </ a ></ li >
Trang 12< li >< a href =" "> Add User </ a ></ li >
< li >< a href =" "> Manage User </ a ></ li >
Về cơ bản, tạm thời ta đã thiết lập xong layout cho ứng dụng
Tiếp tục, ta tiến hành xây dựng CSDL như sau:
Mysql> create database zfblog;
Thiết lập Model cho môi trường multi module của chúng ta như sau:
Trang 13Tại file bootstrap.php chính ta xây dựng phương thức initDB như sau:
B- Xây dựng chức năng thành viên:
Xây dựng bảng user như sau:
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL auto_increment,
`username` varchar(50) NOT NULL,
`password` char(32) NOT NULL,
`email` varchar(50) NOT NULL,
`level` char(1) NOT NULL default '1',
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
Và thêm 2 user như sau:
INSERT INTO `user` VALUES (1, 'kenny', '12345',
'kenny@qhonline.info', '2');
INSERT INTO `user` VALUES (2, 'test', '12345', 'test@qhonline.info', '1');
1- Xây dựng trang thêm thành viên:
Trước hết, ta cần thiết lập zend_form và tách hẳn chúng ra 1 file riêng biệt tại đường dẫn admin/forms/user.php để tiện cho việc tái sử dụng sau này
Tại file này, ta áp dụng zend form để xây dựng các thành phần của form như sau:
Trang 14class Admin_Form_User extends Zend_Form{
public function init()
{
parent ::init();
$this->setAction('')
->setMethod('post') ->setAttrib('id','demo') ->setAttrib('enctype','multipart/form-data');
$username=$this->createElement('text','username', array (
label=>"Username", required=>"true", ));
$password=$this->createElement('password','password', array (
label=>"Password", required=>"true"
));
$repassword=$this->createElement('password','repassword', array (
label=>"Re-Password", ));
$email=$this->createElement('text','email', array (
label=>"Email", required=>"true", ));
$level=$this->createElement('select','level', array (
label=>"Access", multioptions=> array ("1"=>"Member",
"2"=>"Administrator"), value=>'1'
}
}
?>
Trang 15Tiếp tục tại controller ta khởi tạo AddAction như sau.
public function addAction()
Vậy ta tạo file checkuser.php tại admin/forms/validator/
File này sẽ có nội dung như sau:
<?php
class Admin_Form_Validator_CheckUser{
public $_report;
public $_messages;
public function construct($data = array ()){
$validator = new Zend_Validate_StringLength(4 32);
Trang 16Các validate mà ta đang sử dụng:
1- Tên truy cập có độ dài tối thiểu là 4 cho tới 32 ký tự
2- Sử dụng model để kiểm tra xem có bị trùng username hay không ?
3- Mật khẩu không được bỏ trống ?
4- Mật khẩu và xác nhận mật khẩu có chính xác hay không ?
5- Email có hợp lệ hay không ?
Riêng đổi với kiểm tra có tồn tại user hay không, ta phải sử dụng tới model vì thông qua model để kiểm tra trực tiếp từ CSDL của chúng ta
Vậy lúc này tại admin/models/DbTable/ ta tạo file Muser.php
<?php
class Admin_Model_DbTable_Muser extends Zend_Db_Table_Abstract {
protected $_name = 'user';
protected $_primary = 'id';
function checkuser($user){
$data=$this->select()->where("username = ?",$user);
$row=$this->fetchRow($data);
if ($row)
Trang 17return true ; else
return false ; }
Trong ZF, nếu chúng ta tương tác dữ liệu trên 1 bảng riêng biệt thì nên đưa chúng vào thư mục DbTable Vì vậy, ở phần trên tôi đã chuyển file Muser.php vào chung với thư mục này
Nhiệm vụ của phương thức checkuser() này sẽ chạy câu truy vấn để kiểm tra xem có tồn tại ai trong CSDL hay không Nếu có nó sẽ trả về là true và ngược lại sẽ là false.Trong phương thức validate của chúng ta, nếu nhận được là true ta sẽ tiến hành thông báo lỗi
Như vậy, tại controller ta sẽ đưa chúng vào như sau:
if ($this->_request->isPost()){
$data= $this->_request->getParams();
$validate = new Admin_Form_Validator_CheckUser($data);
Nếu trong quá trình kiểm tra bị lỗi, tức là biến toàn cục report sẽ được bật là true
< div id ="errors" style ="color:white;">
< > Co loi xay ra: </ b >< br />
Trang 18Chú ý phương thức populate() của zend form Đây là 1 điểm nhấn trong thư viện ZF Populate() sẽ làm công việc, giữ lại các tham số mà người dùng vừa nhập liệu nhưng
vì dữ liệu chưa hợp lệ nên bị từ chối khi xử lý
Trong trường hợp dữ liệu đã hợp lệ Thì công việc còn lại của chúng ta là thêm người dùng vào CSDL bằng một phương thức adduser() tại model như sau:
Sau đó đẩy người dùng về indexAction để kết thúc thao tác xử lý Vậy code xử lý cho
sự kiện này sẽ như sau:
public function addAction(){
$form= new Admin_Form_User();
$muser= new Admin_Model_DbTable_Muser();
$muser->adduser($data);
$this->_redirect('/admin/user/index');
} }
$this->view->form=$form;
}
Giao diện cơ bản của ứng dụng này tại đây:
Trang 192- Xây dựng trang quản lý thành viên:
Sau khi thực thi công việc thêm thành viên thành công, việc còn lại của chúng ta là liệt kê thông tin của người dùng trên IndexAction() để tiện lợi cho việc sửa, xóa, quản
lý thông tin thành viên
Tại model Admin_Model_DbTable_User ta thiết lập phương thức listuser() với chức năng liệt kê toàn bộ thông tin thành viên
Tại view index.phtml ta thiết lập như sau:
< table width =400 align =center>
< tr >
< td class =title> STT </ td >
< td class =title> Username </ td >
< td class =title> Level </ td >
< td class =title> Edit </ td >
< td class =title> Del </ td >
Trang 20} else {
echo "<td align=center><font color=red>Admin</font></td>";
} echo "<td align=center><a href=".$this-
Kế tới, ta tiến hành phân trang cho ứng dụng quản lý thành viên
Tại controller ta thiết lập các thông số như sau:
public function indexAction()
+ Dòng đầu tiên ta khởi tạo đối tượng zend_paginator
+ Dòng thứ 2 ta thiết lập số record trên mỗi trang
+ Dòng thứ 3 ta thiết lập khoảng cách hiển thị trên các số trang
+ Dòng thứ 4 ta thiết lập trang đầu tiên, mang giá trị là 1
+ Dòng thứ 5 ta đưa các đối tượng trên thực thi
+ Và cuối cùng ta đổ ra view
Tại view index, ngoài việc ta đổ dữ liệu từ model ra, ta cũng cần hiển thị số trang, các link cho next, pre,… Vậy, ta có đoạn code sau:
<?php echo $this->paginationControl($this->info,
Trang 21'Sliding',
'user/pagination.phtml'); ?>Tiếp tục, tại thư mục view/user ta tạo file có tên pagination.phtml với nội dung:
<?php if ($this->pageCount): ?>
< div class ="paginationControl" style ="float:right; padding: 10px;">
<! Previous page link >
<?php
if ( isset ($this->previous)){
echo '<a href="' $this->url( array ('page' =>
$this->previous)) '"> < Previous</a> | ';
echo '<a href="' $this->url( array ('page' =>
$page)) '">' $page '</a> | ';
echo '<a href="' $this->url( array ('page' =>
$this->next)) '">Next ></a>';
?>
</ div >
<?php endif ; ?>
3- Xây dựng trang sửa thành viên:
Để sửa thành viên, ta phải đi qua hai giai đoạn
+ Một là lẫy dữ liệu từ CSDL và đổ chúng vào form
+ Hai là cập nhật dữ liệu từ trong form vào trong CSDL
Vậy đối với edit action ta cần lấy được id mà người dùng muốn sửa để lấy thông tin chi tiết từ CSDL và đưa chúng vào form Kế tiếp ta kiểm tra xem người dùng đã nhấn nút submit chưa ? Nếu chưa, ta sẽ đổ dữ liệu từ CSDL ra form thông qua phương thức populate() Vậy code của editAction sẽ là:
public function editAction()
{
$id = $this->_request->getParam('userid');
$form= new Admin_Form_User();
$muser= new Admin_Model_DbTable_Muser();
if (!$this->_request->ispost()){
$data=$muser->getuser($id)->toArray();
$form->populate($data);
Trang 22Tiếp theo, chúng ta xử lý khi người dùng nhập liệu trên form Để làm được việc này,
ta cần lấy thông tin từ những gì mà người dùng đã nhập liệu Và xây dựng 1 lớp validation dành cho việc sửa thành viên này
Với lớp validation update này, chúng ta không thể yêu cầu người dùng phải nhập mật khẩu, Vì họ có thể muốn hoặc không muốn chỉnh sửa mật khẩu Ngoài ra, cũng cần tính tới trường hợp người sử dụng muốn sửa lại tên truy cập đã tồn tại trong CSDL Lúc này, ta cần sửa lại phương thức checkuser trong Muser.php
Khi người dùng muốn sửa user tức sẽ tồn tại id mà họ mong muốn sửa Sử dụng ID
đó ta so sánh trong quá trình kiểm tra thông tin user đó bằng một điều kiện where id
!= $id Vậy sẽ tồn tại 2 điều kiện where nếu người dùng muốn sửa user
Khi người dùng muốn thêm user tức không tồn tại id nào cả Vậy việc thêm vào chỉ cần kiểm tra 1 điều kiện where về username mà thôi
Đoạn code xử lý tình huống trên như sau trên file Muser.php :
return false ; }
Trang 23Vậy tại file valid cho người dùng sửa thành viên (forms/validator/updateuser.php):
< div id ="errors" style ="color:white;">
< > Co loi xay ra: </ b >< br />
Trang 24"level" => $arr["level"], );
Cuối cùng editAction() sẽ như sau:
public function editAction()
{
$id = $this->_request->getParam('userid');
$form= new Admin_Form_User();
$muser= new Admin_Model_DbTable_Muser();
$muser->edituser($data);
$this->_redirect("admin/user/index");
} }
Trang 25Để xây dựng trang xóa thành viên, ta cũng cần xây dựng delAction() Và phương thức deluser() tại Model để thực thi chức năng xóa thành viên này.
Vậy ta xây dựng phương thức deluser() tại Model như sau:
Do delAction() chỉ làm công việc xóa thành viên và di chuyển họ trở về indexAction, nên chúng ta không cần tạo view Lúc này ta cần sử dụng 1 helper để quy ước không cần view cho action này
$this->_helper->viewRenderer->setNoRender( true );
Và cuối cùng là nội dung delAction()
public function delAction()
5- Xây dựng chức năng đăng nhập, đăng xuất hệ thống:
Để tiến tới xây dựng trang đăng nhập hệ thống ta sử dụng thư viện Zend_Auth trong
ZF Thư viện này đã hỗ trợ chúng ta trong việc thiết lập và sử dụng những chức năng
cơ bản của quá trình chứng thực người dùng
Để kích hoạt Zend_Auth ta cần thiết lập Zend_session tại file bootstrap.php chính:protected function _initSession(){
Zend_Session::start();
}
Tiếp tục, tại Model Muser Ta lại thiết lập phương thức checklogin() Công việc chính của phương thức này là sử dụng lớp Zend_Auth để chứng thực xem người dùng nhập thông tin username và password có đúng với CSDL hay không
Trang 26Trước hết, ta cần kiểm tra xem người dùng có nhập liệu hay không ? Nếu có ta tiếp tục khởi tạo Zend_Registry Công việc của thư viện này là chúng sẽ lấy thông tin kết nối CSDL tại phương thức _initDB() mà ta đã cấu hình tại bootstrap.php chính
Kế tới ta truyền tham số username và password từ form nhập liệu của người dùng vào
để so sánh với thông tin tại CSDL
Nếu quá trình kiểm tra hoàn tất và chúng hoàn toàn hợp lệ thì việc còn lại của chúng
ta là đưa giá trị trong cột vào session Dĩ nhiên với password thì chúng ta không nên đưa vào session (lưu ý là ta không cần thiết lập session vì bản thân zend_auth đã thay
ta làm những việc này rồi)