Twitter Delicious Facebook Digg Stumbleupon Favorites More

Thứ Ba

HƯỚNG DẪN VIẾT HƯỚNG ĐỐI TƯỢNG PHP CLASS DATABASE



Tôi lấy ví dụ bài menu 2 cấp để viết TUT cho bài này nhé: http://forum.congthuongit.net/viewthread.php?tid=453333

Với bài viết đó, tôi đã sử dụng lập trình hướng thủ tục để giải quyết bài toán menu 2 cấp!
Như các bạn đã biết về lập trình hướng đối tượng, để viết 1 cách nhanh hơn, dễ chỉnh sửa hơn, tái tạo code nhanh và nhất là để người dùng sau này có thể tiếp tục phát triển người ta nghĩ đến "Lập trình hướng đối tượng", mọi thứ đều quy về "đối tượng" để dễ quản lý và sử dụng!

Vậy lập trình hướng đối tượng trong PHP như thế nào? Sử dụng ra sao? Các bạn hãy xem 1 số video training mà tôi đã sưu tầm được: http://fit-hitu.edu.vn/forum/thread-632.html

Với bài này tôi sẽ hướng dẫn cho các bạn viết lớp Database làm việc với CSDL, ngoài ra còn rất nhiều lớp khác như phân trang, template, mình sẽ cố gắng hướng dẫn sau!

Và đây là lớp Database đơn giản:
  1. <?php  
  2. class Database{  
  3.   
  4. private $db_connect;  
  5.   
  6. private $queryResult;  
  7.         function __construct($config){  
  8.               $this->connect($config);  
  9.         }  
  10.   
  11. function connect($config){  
  12.   
  13. $this->db_connect = @mysql_connect($config["hostname"],$config["userdb"],$config["passdb"])   
  14.   
  15. or die("Cannot Connect To MySQL Server");  
  16.   
  17. @mysql_select_db($config["dbname"], $this->db_connect) or die("Cannot Select Database MySQL Server!");  
  18.   
  19. $this->query("set names utf8");  
  20.   
  21. }  
  22.         function disconnect(){  
  23.                 mysql_close($this->db_connect);  
  24.         }  
  25.   
  26. function query($sql){  
  27.   
  28. $this->queryResult = @mysql_query($sql, $this->db_connect);  
  29.   
  30. return $this->queryResult;   
  31.   
  32. }  
  33.   
  34.   
  35.   
  36. function fetch($result = NULL){  
  37.   
  38. // Nếu không truyền result query  
  39.   
  40. if($result == NULL){  
  41.   
  42. // Nếu tồn tại result query  
  43.   
  44. if (is_resource($this->queryResult))  
  45.   
  46. return mysql_fetch_assoc($this->queryResult);  
  47.   
  48. return NULL;  
  49.   
  50. }  
  51.   
  52. return mysql_fetch_assoc($result);  
  53.   
  54. }  
  55.   
  56. function fetch_array($result = NULL){  
  57.   
  58. // Nếu không truyền result query  
  59.   
  60. if($result == NULL){  
  61.   
  62. if (is_resource($this->queryResult))  
  63.   
  64. while($r = $this->fetch()){  
  65.   
  66. $array[] = $r;   
  67.   
  68. }  
  69.   
  70. }  
  71.   
  72. else{  // Có truyền result  
  73.   
  74. while($r = $this->fetch($result)){  
  75.   
  76. $array[] = $r;   
  77.   
  78. }  
  79.   
  80. }  
  81.   
  82. return $array;  
  83.   
  84. }  
  85.   
  86. function exec_query($sql){  
  87.   
  88. $this->query($sql);  
  89.   
  90. return mysql_affected_rows();  
  91.   
  92. }  
  93.   
  94. function num_rows($result = NULL){  
  95.   
  96. if($result == NULL){  
  97.   
  98. if (is_resource($this->queryResult))  
  99.   
  100. return mysql_num_rows($this->queryResult);  
  101.   
  102. }  
  103.   
  104. return mysql_num_rows($result);  
  105.   
  106. }  
  107.   
  108.   
  109.   
  110. function __destruct(){  
  111.   
  112. $this->disconnect();  
  113.   
  114. }  
  115. }  
  116.   
  117. ?>  
Lớp gồm các thuộc tính:
+ private $db_connect : resource connect
+ private $queryResult : resource query
Lớp này có các phương thức sau:
__construct: Phương thức khởi tạo kết nối
connect($config) : Phương thức kết nối với CSDL, với dữ liệu truyền vào là 1 mảng liên hợp gồm 4 thông tin kết nối:
$config["hostname"] = 'localhost'; // Host name
$config["userdb"] = 'root'; // Username database
$config["passdb"] = 'vertrigo'; // Password database
$config["dbname"] = 'fusuhotel'; // Name database
disconnect(): Phương thức đóng kết nối CSDL
query($sql) : Phương thức tạo truy vấn CSDL, trả về resource mysql_query()
fetch($result = NULL): Phương thức fetch() dữ liệu theo từng record, dữ liệu trả về là 1 mảng record tương ứng với mysql_fetch_assoc() 
Nếu ta không truyền tham số $result vào thì mặc định nó sẽ dùng property $queryResult, ngược lại nó sẽ sử dụng $result mà ta truyền vào. Cụ thể sử dụng thế nào mình sẽ ví dụ sau
fetch_array($result = NULL) : Phương thức fetch_array() sẽ trả về cho ta 1 mảng assoc. Tương tự như fetch(), nếu không truyền $result thì nó sẽ sử dụng property $queryResult và ngược lại nó sẽ sử dụng $result truyền vào.
exec_query($sql) : Phương thức exec_query() thực hiện các câu lệnh: INSERT, UPDATE, DELETE, với $sql truyền vào là chuỗi truy vấn và kết quả trả về là số dòng đã thực thi mysql_affected_rows()
num_rows($result = NULL) : Phương thức num_rows() đếm số dòng (records) của $result truyền vào, nếu ta không truyền thì mặc định nó sử dụng property $queryResult
__destruct: Là hàm hủy đối tượng, nó sẽ gọi phương thức disconnect() để đóng kết nối với CSDL

Sau đây, tôi sẽ VD các sử dụng lớp Database mà chúng ta vừa tạo:
Đầu tiên bạn khởi tạo lớp Database, bạn có thể đặt đoạn mã này trong file config.php (file cấu hình)
  1. $config["hostname"] = 'localhost';   // Host name  
  2. $config["userdb"] = 'root';  // Username database  
  3. $config["passdb"] = 'vertrigo';  // Password database  
  4. $config["dbname"] = 'fusuhotel';  // Name database  
  5. // Khởi tạo lớp Database,  
  6. // Bạn lưu ý $db này là đối tượng mà ta sử dụng xuyên suốt trong toàn bộ trang web của mình  
  7. $db = new Database($config);  // rất đơn giản ta đã kết xong CSDL  
Như vậy là ta đã kết nối xong với CSDL

Như vd bài menu 2 cấp lần trước tôi sử dụng trường menu sau:
Menu(idMenu,nameMenu,linkMenu,titleMenu,newPageMenu,isParent,parentId,order,isPu​blished)

Bây giờ ta thử xuất ra tất cả menu trong CSDL nhé:
  1. // Chuỗi query  
  2. $query = "SELECT idMenu,nameMenu,linkMenu,titleMenu FROM Menu";  
Có 3 cách để các bạn truy vấn:
Dùng phương thức fetch() không có đối số truyền vào như tôi nói ở trên
  1. $db->query($query);  
  2. while($rows = $db->fetch()){  
  3.       echo '<li>  
  4.              <a title="'.$pr['titleMenu'].'" href="'.$pr['linkMenu'].'">'.$pr['nameMenu'].'</a>  
  5.              </li>';  
  6. }  
Dùng phương thức fetch() có đối số truyền vào
  1. $result = $db->query($query);  
  2. while($rows = $db->fetch($result)){  
  3.       echo '<li>  
  4.              <a title="'.$pr['titleMenu'].'" href="'.$pr['linkMenu'].'">'.$pr['nameMenu'].'</a>  
  5.              </li>';  
  6. }  
Sử dụng phương thức fetch_array() và dữ liệu trả về cho ta là 1 mảng liên hợp gồm nhiều dòng (records) dữ liệu mà ta truy vấn
+ Sử dụng fetch_array() không có tham số truyền vào
  1. $db->query($query);  
  2. $arrayMenu = $db->fetch_array(); // Trả về mảng gồm nhiều records  
  3. /* 
  4.  Bạn có thể xem trong $arrayMenu gồm những phần tử và giá trị gì, bằng cách dùng: 
  5. var_dump($arrayMenu);   
  6. Hoặc: 
  7. print_r($arrayMenu) 
  8. Nó sẽ in tất cả các element trong mảng $arrayMenu 
  9. */  
  10. // Dùng foreach để lặp các thẻ <li> của menu  
  11. foreach($arrayMenu as $pr)  
  12. {  
  13.       echo '<li>  
  14.              <a title="'.$pr['titleMenu'].'" href="'.$pr['linkMenu'].'">'.$pr['nameMenu'].'</a>  
  15.              </li>';  
  16. }  
+ Sử dụng fetch_array() có tham số truyền vào
  1. $result = $db->query($query);  
  2. $arrayMenu = $db->fetch_array($result ); // Trả về mảng gồm nhiều records  
  3. // Dùng foreach để lặp các thẻ <li> của menu  
  4. foreach($arrayMenu as $pr)  
  5. {  
  6.       echo '<li>  
  7.              <a title="'.$pr['titleMenu'].'" href="'.$pr['linkMenu'].'">'.$pr['nameMenu'].'</a>  
  8.              </li>';  
  9. }  
Tùy trường hợp mà ta sử dụng cho hợp lý. Do tôi sử dụng template Smarty nên sử dụng fetch_array() nhiều hơn:
http://fit-hitu.edu.vn/forum/thread-647.html . Nếu các bạn quan tâm đến smarty tôi sẽ hướng dẫn thêm!

OK! Bây giờ ta thử viết lại bài toán menu 2 cấp:
  1. <?php  
  2. $config["hostname"] = 'localhost';   // Host name  
  3. $config["userdb"] = 'root';  // Username database  
  4. $config["passdb"] = 'vertrigo';  // Password database  
  5. $config["dbname"] = 'fusuhotel';  // Name database  
  6. // Khởi tạo lớp Database,  
  7. $db = new Database($config);   
  8. // Do bài toán này có sử dụng query lồng nhau, ta bắt buột phải sử dụng fetch() có tham số $result truyền vào!  
  9.   
  10. [code]  
  11. $queryParent = $db->query("SELECT idMenu,nameMenu,linkMenu,titleMenu,newPageMenu   
  12.                      FROM menu WHERE isPublished = '1' and isParent = '1'  order by 'order' ASC ");  
  13.         ?>  
  14. <div class="content_menu">  
  15.    <ul>  
  16.        <?php  
  17.     while($pr = $db->fetch($queryParent))  
  18.     {  
  19.     ?>  
  20.           <li>  
  21.              <a target="<?php echo ($pr['newPageMenu'] == "1") ? "_blank" : "_self"; ?>" title="<?php echo $pr['titleMenu']; ?>" href="<?php echo $pr['linkMenu']; ?>"> <?php echo $pr['nameMenu']; ?></a>  
  22.           </li>  
  23.        <?php  
  24.              // Trong mỗi menu cha, ta lại tìm menu con để lặp  
  25.           $queryChild = $db->query("SELECT idMenu,nameMenu,linkMenu,titleMenu,newPageMenu FROM menu   
  26.                         WHERE isPublished = '1' and isParent = '0' and parentId = '".$pr['idMenu']."' order by 'order' ASC ");  
  27.         if($db->num_rows($queryChild) != 0)  // Đếm số menu con, nếu ko có menu thì không thực hiện lặp menu con  
  28.     {  
  29.         echo "<ul>";  
  30.             while($ch = $db->fetch($queryChild))  
  31.             {  
  32.     ?>  
  33.                <li>  
  34.         <a target="<?php echo ($ch['newPageMenu'] == "1") ? "_blank" : "_self"; ?>"   
  35.                                title="<?php echo $ch['titleMenu']; ?>" href="<?php echo $ch['linkMenu']; ?>"><?php echo $ch['nameMenu']; ?></a>  
  36.                </li>  
  37.     <?php  
  38.         } // end menu children  
  39.            echo "</ul>";  
  40.     } // end if  
  41.      } // end menu parent  
  42. ?>  
  43.      </ul>  
  44. </div>   
Hoặc các bạn có thể viết như sau, nếu muốn dữ liệu menu cha và con đều quy về 1 mảng bằng cách ta thêm phần tử là 1 mảng menu con vào mảng menu cha.

VD: ta có 1 menu cha idMenu ="001" và có 2 menu con là "002" và "003"
Menu(idMenu,nameMenu,linkMenu,titleMenu,isParent )
  1. $arrMenuCha = ("idMenu"=>"001","nameMenu"=>"Giới thiệu","linkMenu"=>"gioithieu.php","titleMenu"=>"Giới thiệu","isParent"=>1);  
  2. $arrMenuCon1 = ("idMenu"=>"002","nameMenu"=>"Về công ti","linkMenu"=>"gioithieu.php?p=congti","titleMenu"=>"Giới thiệu về công ti","isParent"=>0);  
  3. $arrMenuCon2 = ("idMenu"=>"003","nameMenu"=>"Về nhà hàng","linkMenu"=>"gioithieu.php?p=nhahang","titleMenu"=>"Giới thiệu về nhà hàng","isParent"=>0);  
Ta thêm 2 menu con vào menu cha:
  1. $arraMenuCha["childMenu"][] = $arrMenuCon1;  
  2. $arraMenuCha["childMenu"][] = $arrMenuCon2;  
Sẽ cho ra:
  1. $arraMenuCha == ("idMenu"=>"001","nameMenu"=>"Giới thiệu","linkMenu"=>"gioithieu.php","titleMenu"=>"Giới thiệu","isParent"=>1,"childMenu"=>array(  
  2.   
  3.  ("idMenu"=>"002","nameMenu"=>"Về công ti","linkMenu"=>"gioithieu.php?p=congti","titleMenu"=>"Giới thiệu về công ti","isParent"=>0) ,   
  4.   
  5. ("idMenu"=>"003","nameMenu"=>"Về nhà hàng","linkMenu"=>"gioithieu.php?p=nhahang","titleMenu"=>"Giới thiệu về nhà hàng","isParent"=>0)  
  6. ))  
Giải thích dài dòng cho các bạn hiểu thôi, chứ code bên dưới vô cùng đơn giản!
  1. $queryParent = $db->query("SELECT idMenu,nameMenu,linkMenu,titleMenu,newPageMenu FROM menu   
  2.   
  3.   WHERE isPublished = '1' and isParent = '1' order by 'order' ASC");  
  4.   
  5.     
  6. while($pr = $db->fetch($queryParent))  
  7. {  
  8.    $queryChild = $db->query("SELECT idMenu,nameMenu,linkMenu,titleMenu,newPageMenu FROM menu   
  9.   
  10. WHERE isPublished = '1' and isParent = '0' and parentId = '".$pr['idMenu']."' order by 'order' ASC");  
  11.   if($db->num_rows($queryChild) != 0){  // Có child menu  
  12.      
  13. while($cr = $db->fetch($queryChild))   
  14.   
  15. {  
  16.   
  17. $pr["childMenu"][] = $cr; // Gán thêm array Child menu  
  18.   
  19. }  
  20.    }  
  21.    $arrMenu[] = $pr;  
  22. }  
Như vậy sau đó ta chỉ cần lặp $arrMenu để xuất ra menu thôi!
  1.   <div class="content_menu">  
  2.         <ul>  
  3.        <?php  
  4.         foreach ($arrMenu as $parent)  
  5.   
  6. {  
  7.   
  8. ?>  
  9.        
  10. <li><a title="<?php echo $parent['titleMenu']; ?>" href="<?php echo $parent['linkMenu']; ?>"><?php echo $parent['nameMenu']; ?></a></li>  
  11.             <?php  
  12.   
  13. if(count($parent['childMenu'] != 0)  
  14.   
  15. {  
  16.   
  17. ?>  
  18.               
  19. <ul>  
  20.                  <?php  
  21.                  foreach ($parent['childMenu'] as $child)  
  22.   
  23.  {  
  24.   
  25.  ?>  
  26.                         <li><a title="<?php echo $child['titleMenu']; ?>" href="<?php echo $child['linkMenu']; ?>"><?php echo $child['nameMenu']; ?></a></li>  
  27.                <?php  
  28.   
  29.      
  30.  } // end foreach $child  
  31.   
  32.    ?>  
  33.                 </ul>  
  34.             <?php   
  35.   
  36.   } // end if  
  37.   
  38. // end foreach $parent  
  39.   
  40. ?>  
  41.         </ul>  
  42.     </div>  
Như vậy là tôi đã giới thiệu xong lớp Database và cách sử dụng nó, các bạn có thể viết lại các phương thức tùy thích các bạn, làm sao để sử dụng nhanh chóng và hiểu quả là tốt! Chúc các bạn thành công!

0 nhận xét:

Đăng nhận xét

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Blogger Templates