PHP – EasyUI DataGrid 资料存取标准化
延续上篇 PHP – EasyUI DataGrid 资料存的方式 ,本篇将上篇其中资料存取的 dal_user.php 予以标准化,藉由标准化的 dal 才能将知识传承下去并可将程式撰写的方式标准化下来。
一般我们要将程式撰写的方式标准化,都会撰写程式撰写规范文件的方式,来告诉开发人员要如何来撰写程式。
接下来,要来定义 DAL 的 interface,也就是设定 DAL 标准该有的介面有哪些(有关本文所讲述 DAL 的概念,读者 可参阅 PHP – 架構設計 Data Access Layer 篇,看过以后会更容易了解本文所说的概念),介面说明如下。
首先,要能实现之前在 PHP – EasyUI DataGrid 资料存的方式 中 type 所定义的四个动作
add 新增
mod 修改
del 删除
data 取得资料
这些 都要能有对应的资料处理介面,而这四个动作,也都跟业务逻辑没有关联,所以算是很单纯的资料存取,很容易就能写出,标准化介面如下所示:
IDAL.php
1 <?php 2 3 /** 4 * @file IDAL.php 5 * @brief 設定 DAL 標準該有的介面 6 * @author watson 7 * @version 1.0 8 * @date 2012-10-05 9 */ 10 interface IDAL 11 { 12 /** 13 * @brief 設定要操作的資料庫 14 * 15 * @param $id 要操作的資料庫 16 * 17 * @return 無回傳值 18 */ 19 public function setDB($fdb); 20 21 /** 22 * @brief 藉由table 的唯一主 key 來刪除特定資料 23 * 24 * @param $id 要刪除資料的 key 值 25 * 26 * @return 成功回傳 'true', 失敗回傳 錯誤信息 27 */ 28 public function delete($id); 29 30 /** 31 * @brief 更新資料,資料從 $_REQUEST 取得,索引名稱需與 資料庫 table 的欄位名稱一致 32 * 33 * @return 成功回傳 'true', 失敗回傳 錯誤信息 34 */ 35 public function update(); 36 37 /** 38 * @brief 新增資料,資料從 $_REQUEST 取得,索引名稱需與 資料庫 table 的欄位名稱一致 39 * 40 * @return 成功回傳 'true', 失敗回傳 錯誤信息 41 */ 42 public function insert(); 43 44 /** 45 * @brief 取得目前資料的總筆數 46 * 47 * @return 回傳資料的總筆數 48 */ 49 public function getTotalCount(); 50 51 /** 52 * @brief 藉由查詢條件 criValues 來取得資料 53 * 54 * @param $criValues 該網頁資料處理對應的 DAL 55 * 56 * @return 回傳資料集陣列 57 */ 58 public function getData($criValues); 59 } 60 61 ?>
接下来,当然就是 要对上面定义的介面来实现 各个 table 对应的 DAL 来处理资料。
这部分的实现,并不复杂,但跟技术比较有关西,为了避免偏离原先要讲架购的主题,还请读者自行去实做,只要能实现上述界面所要功能就可以了。
DAL 这部分用好后,在来就是思考,如何来应用在 UI 层了,这部分需要思考几个问题,第一,是希望程式的档案数要能减少,最好是一支程式就能完成。
第二,UI 层 牵涉到 DAL 的呼叫,也就是 MVC 中的控制部分,也要能标准化起来,如此后面每一支系统程式,就不用每一支都要来去控制 DAL 的呼叫,尽量把会重复使用的控制跟操作的方法,封装起来,藉此简化,后面应用时的复杂度,而能在应用时专心该系统要解决的问题上就好。
在这,一條小龍 把控制 DAL 的程式码,封装成一个 DG_Page 的 class 来处理,如此, UI 层 就只需要在简单来呼叫使用即可。
这部分程式码,如下所示:
DG_Page.php
1 <?php 2 3 /** 4 * @file DG_Page.php 5 * @brief 基本檔網頁的資料處理 6 * @author watson 7 * @version 1.0 8 * @date 2012-10-05 9 */ 10 class DG_Page 11 { 12 var $db; 13 var $dal; 14 15 /** 16 * @brief 建構式 17 * 18 * @param $fdal 該網頁資料處理對應的 DAL 19 * 20 * @return 21 */ 22 public function __construct(IDAL $fdal) 23 { 24 require_once("..\..\db\DB_config.php"); 25 require_once("..\..\db\DB_class.php"); 26 27 //if (!empty($fdal)) 28 //{ 29 //return die(get_class($this)."->".__FUNCTION__." => DAL not define"); 30 //} 31 32 $this->db = new DB(); 33 $this->db->connect_db($_DB['host'], $_DB['username'], $_DB['password'], $_DB['dbname']); 34 35 $this->dal = $fdal; 36 $this->dal->setDB($this->db); 37 } 38 39 /** 40 * @brief 處理 Post 回來的資料,$_REQUEST['type'] 不能為空 41 * 42 * @return Type=Insert, Update 成功 回傳 array('success'=>true) 43 * Type=Data 回傳 EasyUI 用的資料集 44 * Type=Qry 回傳 JSON 資料集 45 */ 46 public function dealPost() 47 { 48 $result = false; 49 50 $type = $_REQUEST['type']; 51 $msg = ""; 52 53 if (!empty($_REQUEST["forKey"])) 54 { 55 $_REQUEST[$this->dal->Foreignkey] = $_REQUEST["forKey"]; 56 } 57 58 if($type == "del") 59 { 60 $id = $_REQUEST['id']; 61 $result = $this->dal->delete($id); 62 63 }else if($type == "data"){ 64 65 $res = array(); 66 67 $res["total"] = $this->dal->getTotalCount(); 68 69 $items = $this->dal->getData($_REQUEST); 70 71 $res["rows"] = $items; 72 73 echo json_encode($res); 74 }else if($type == "qry"){ 75 76 $items = $this->dal->getData($_REQUEST); 77 78 echo json_encode($items); 79 80 }else{ 81 82 if (!empty($_REQUEST['id']) ) { 83 $result = $this->dal->update(); 84 }else{ // is add 85 $result = $this->dal->insert(); 86 } 87 } 88 89 if($type != "data" && $type != "qry") 90 { 91 if ($result == "true"){ 92 echo json_encode(array('success'=>true)); 93 } else { 94 95 echo json_encode(array('msg'=>'had errors occured. ' . $result)); 96 } 97 } 98 } 99 } 100 ?>
由程式码,可以看到一條小龍,把 在 PHP – EasyUI DataGrid 资料存的方式 中 type 所定义的四个动作,DG_Page 在实做一次,跟 DAL 层不同的是这边重点,主要在把 DAL 取出的资料,予以处理,将其格式调整成 UI 控件,在这范例中,也就是 EasyUI DataGrid 能接受的资料格式。
如此,后面需要更换 控件时,就只需改写 这个 class 即可,而且 DAL 的部分,它的功能也比在前篇的 dal_user class 更加明确,如此一来,本文的 dal 只单纯在做资料处理,应用范围就会更宽广。
最后,为了应用,前面写的两支程式,需在改写 datagrid.php 这支程式,让其在后面应用上,EasyUI DataGrid 都只需要呼叫自己本身来处理即可,不需在像前篇PHP – EasyUI DataGrid 资料存的方式 中所述,还需要 呼叫另外一支 dal_user.php 的程式,如此一来,可大大 减少后须维护的程式相关档案的数量,不用为了维护一支程式要找好几支档案来处理。
datagrid.php
1 <?php 2 require_once("..\..\db\DAL\STDAL.php"); 3 4 $prgName = "User"; 5 $dal = DALFactory::getInstance($prgName); 6 7 $LoginPath = "datagrid.php"; 8 9 if (!empty($_REQUEST['type']) ) 10 { 11 require_once("..\..\util\DG_Page.php"); 12 13 $myPage = new DG_Page($dal); 14 15 $myPage->dealPost(); 16 }else{ 17 ?> 18 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 19 <html> 20 <head> 21 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 22 <title>一條小龍 easyUI datagrid</title> 23 24 25 <link rel="stylesheet" type="text/css" href="http://www.cnblogs.com/JS/EasyUI/themes/default/easyui.css"> 26 <link rel="stylesheet" type="text/css" href="http://www.cnblogs.com/JS/EasyUI/themes/icon.css"> 27 28 <script type="text/javascript" src="http://www.cnblogs.com/JS/jquery.js"></script> 29 <script type="text/javascript" src="http://www.cnblogs.com/JS/EasyUI/jquery.easyui.min.js"></script> 30 <script type="text/javascript" src="http://www.cnblogs.com/JS/EasyUI/easyui-lang-zh_CN.js"></script> 31 32 <style type="text/css"> 33 #fm{ 34 margin:0; 35 padding:10px 30px; 36 } 37 .ftitle{ 38 font-size:14px; 39 font-weight:bold; 40 color:#666; 41 padding:5px 0; 42 margin-bottom:10px; 43 border-bottom:1px solid #ccc; 44 } 45 .fitem{ 46 margin-bottom:5px; 47 } 48 .fitem label{ 49 display:inline-block; 50 width:80px; 51 } 52 </style> 53 54 <script type="text/javascript"> 55 <?php 56 echo "post_prg = '$LoginPath';"; 57 echo "primay_key = '$dal->PrimaryKey';"; 58 ?> 59 var url; 60 61 $(function(){ 62 furl = post_prg+ '?type=data'; 63 $('#myDG').datagrid({ 64 url:furl 65 }); 66 }); 67 68 function newUser(){ 69 $('#dlg').dialog('open').dialog('setTitle','New User'); 70 $('#fm').form('clear'); 71 url = post_prg + '?type=add'; 72 } 73 function editUser(){ 74 var row = $('#myDG').datagrid('getSelected'); 75 if (row){ 76 77 if(typeof(row.UNum) !== 'undefined') 78 { 79 $('#dlg').dialog('open').dialog('setTitle','Edit User'); 80 $('#fm').form('load',row); 81 url = post_prg + '?type=mod&id='+row.UNum; 82 }else{ 83 alert("undefined"); 84 } 85 } 86 } 87 function saveUser(){ 88 $('#fm').form('submit',{ 89 url: url, 90 onSubmit: function(){ 91 //alert('sub :'+ url); 92 return $(this).form('validate'); 93 }, 94 success: function(result){ 95 var result = eval('('+result+')'); 96 //alert(result.success); 97 if (result.success){ 98 $('#dlg').dialog('close'); // close the dialog 99 $('#myDG').datagrid('reload'); // reload the user data 100 } else { 101 $.messager.show({ 102 title: 'Error', 103 msg: result.msg 104 }); 105 } 106 } 107 }); 108 } 109 function removeUser(){ 110 var row = $('#myDG').datagrid('getSelected'); 111 if (row){ 112 $.messager.confirm('Confirm','Are you sure you want to remove this user?',function(r){ 113 if (r){ 114 //alert(row.UNum); 115 $.post(post_prg, {type:'del', id:row.UNum}, function(result){ 116 if (result.success){ 117 $('#myDG').datagrid('reload'); // reload the user data 118 } else { 119 $.messager.show({ // show error message 120 title: 'Error', 121 msg: result.msg 122 }); 123 } 124 },'json'); 125 } 126 }); 127 } 128 } 129 </script> 130 </head> 131 <body> 132 <h2>一條小龍 easyUI datagrid url 存取測試2</h2> 133 134 <table id="myDG" class="easyui-datagrid" style="width:700px;height:450px" 135 toolbar="#toolbar" 136 title="Load Data" iconCls="icon-save" pagination="true" 137 toolbar="#toolbar" rownumbers="true" fitColumns="true" singleSelect="true"> 138 <thead> 139 <tr> 140 <th field="STUID" width="120">User ID</th> 141 <th field="Password" width="80" align="right">Password</th> 142 <th field="Birthday" width="80" align="right">Birthday</th> 143 <th field="Nickname" width="200">Nickname</th> 144 <th field="DBSTS" width="60" align="center">DBSTS</th> 145 </tr> 146 </thead> 147 </table> 148 <div id="toolbar"> 149 <a href="#" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="newUser()">New User</a> 150 <a href="#" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="editUser()">Edit User</a> 151 <a href="#" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="removeUser()">Remove User</a> 152 </div> 153 154 <div id="dlg" class="easyui-dialog" style="width:400px;height:350px;padding:10px 20px" 155 closed="true" buttons="#dlg-buttons"> 156 <div class="ftitle">User Information</div> 157 <form id="fm" method="post" novalidate> 158 <div class="fitem"> 159 <label>User ID:</label> 160 <input name="STUID" class="easyui-validatebox" required="true"> 161 </div> 162 <div class="fitem"> 163 <label>Password:</label> 164 <input name="Password" class="easyui-validatebox" required="true"> 165 </div> 166 <div class="fitem"> 167 <label>Nickname:</label> 168 <input name="Nickname"> 169 </div> 170 <div class="fitem"> 171 <label>Birthday:</label> 172 <input name="Birthday" class="easyui-validatebox" validType="email"> 173 </div> 174 </form> 175 </div> 176 <div id="dlg-buttons"> 177 <a href="#" class="easyui-linkbutton" iconCls="icon-ok" onclick="saveUser()">Save</a> 178 <a href="#" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">Cancel</a> 179 </div> 180 181 </body> 182 </html> 183 184 <?php 185 186 } 187 188 ?>
在这支程式中,UI 层还可以在用一个 Layout 来处理,把 整各画面的排版方式,用一支 Layout 的 php or html 档,来描述好再给这支程式来呼叫使用即可,如此就可让 程式人员减少接触太多的 HTML,并把 Layout 可以给专业网页开发人员来处理,来达到前后台分离开发的目的。