thinkphp5配合datatable插件分页后端处理程序
thinkphp5配合datatable插件分页后端处理程序
第一版DataTable.php v.1.0
1 <?php 2 use think\Db; 3 /** 4 * DataTable.php. 5 */ 6 /** 7 * datatable结合thinkphp5使用的分页后台处理程序. 8 * 9 * @author B.I.T. 10 * @copyright Copyright (c) 2018-2019, B.I.T. 11 * @license 12 * 13 * @see 初始化 14 * 15 * @version v.1.0 16 */ 17 class DataTable 18 { 19 /** 20 * 数据库对象 21 * 22 * @var objectc 23 */ 24 public $_db; 25 /** 26 * 表名. 27 * 28 * @var string 29 */ 30 protected $_table; 31 /** 32 * 表格重绘次数. 33 * 34 * @var int 35 */ 36 protected $_draw; 37 /** 38 * 排序的是哪行. 39 * 40 * @var int 41 */ 42 protected $_order_column; //排序的行 43 /** 44 * 排序方式 45 * asc desc. 46 * 47 * @var string 48 */ 49 protected $_order_dir; //排序方式 asc desc 50 /** 51 * 查询的数据. 52 * 53 * @var string 54 */ 55 protected $_search = ''; //查询的字符串 56 /** 57 * 查询开始的位置. 58 * 59 * @var int 60 */ 61 protected $_start; //开始的位置 62 /** 63 * 每页显示的条目数. 64 * 65 * @var int 66 */ 67 protected $_length; //查询的长度 68 /** 69 * 过滤后的条目数量. 70 * 71 * @var integer 72 */ 73 protected $_recordsFiltered = 0; //过滤后的条目数量 74 /** 75 * 总的条目数量. 76 * 77 * @var integer 78 */ 79 protected $_recordsTotal = 0; //总的条目数量 80 /** 81 * 返回的数据 没用到. 82 * 83 * @var [type] 84 */ 85 protected $_return; //没用到 86 /** 87 * 存放构造函数的第二个参数. 88 * 89 * @var [type] 90 */ 91 protected $_info; //存放构造函数的第二个参数 92 93 /** 94 * 构造函数 处理datatables发送的数据,用户自定义条件,. 95 * 96 * @param array $dataTableGet dataTable前台传递过来的数组 97 * @param array $info 构造好的数组结构如下 98 * example array( //表示 select ID AS sum,ID,USERNMAE 其中 sum用来统计数据的总条数 99 * "select"=array( 100 * "ID"=>"sum", 101 * "0"=>'ID', 102 * "1"=>"USERNAME", 103 * ), 104 * "order"=>array( //前台会发送过来根据哪一列排序 接收过来的值就是 键值,对应到数据表中的字段就是值,前台有几个列能够排序这里就需要有几个对应的键值队 105 * "0"=>"ID", 106 * "2"=>"USERNAME", 107 * ), 108 * "where"=>array( //and和or可以同时调用 但是or是用来做查询的 and则是初始数据的查询条件 109 * "and"=>array( //表示会查询state=1 and level=2 and (a=1 or a=2) 的数据 110 * "state"=>'1', 111 * "level"=>"2", 112 * "a"=>[1,2] 113 * ), 114 * 115 * 注:"or" 用户搜索的时候存在一个问题,参与搜索查询的列必须为同一类型比如id和name字段就不可以一起搜索会出现输入 116 * "qwer" sql为 (id like 0 or name like %qwer%)的情况 117 * 118 * "or"=>array("ID","USERNAME"), //用户查询的时候回根据这里的参数作为查询的列 例如 当search=root时 就会查询 ID like %root% or USERNAME like %root% 119 * "or2"=>[ //这里面的会用or连接 几乎很少用 例如下面的数组会变成: a=1 or a=2 or b=2 120 * a=>[1,2], 121 * b=>[2] 122 * ] 123 * ), 124 * "join"=>array( 125 * 'class'=>array('student.class_id','class.id'), 126 * 'sex'=>array('student.class_id','sex.id') 127 * ) 128 * ) 129 * @param string $db 数据库对象 130 * 131 * @return object this 132 */ 133 public function __construct($dataTableGet, $info = array(), $table = '') 134 { 135 $this->_init($dataTableGet); 136 $this->_table = $table; 137 $this->_db = Db::table($this->_table); 138 $this->_info = $info; 139 } 140 141 /** 142 * 初始化参数,检查数据格式. 143 * 144 * @param array $data datatables发送过来的数据 145 */ 146 protected function _init($data) 147 { 148 if (isset($data)) { 149 $this->_draw = isset($data['draw']) ? $data['draw'] : null; 150 $this->_length = isset($data['length']) ? intval($data['length']) : null; 151 $this->_start = isset($data['start']) ? intval($data['start']) : null; 152 $this->_order_column = isset($data['order']['0']['column']) ? intval($data['order']['0']['column']) : null; 153 $this->_order_dir = isset($data['order']['0']['dir']) ? $data['order']['0']['dir'] : null; 154 $this->_search = isset($data['search']['value']) ? $data['search']['value'] : null; 155 } 156 } 157 158 /** 159 * 输出datatables需要的数据格式,还需要打成json的格式才行. 160 * 161 * @param bool $debug true 会输出一些调试信息 默认false 162 * 163 * @return array atatables需要的数据格式 164 */ 165 public function output($debug = false) 166 { 167 $data = $this->_info; 168 if (isset($data['select']) && !empty($data['select'])) { 169 $selectSql = $this->_getSelectSql($data['select']); 170 } else { 171 $selectSql = '*'; 172 } 173 $this->_db = $this->_db->field($selectSql); 174 if (isset($data['join']) && !empty($data['join'])) { 175 foreach ($data['join'] as $key => $value) { 176 $this->_db = $this->_db->join($key,$value[0].' = '.$value[1]); 177 } 178 } 179 if (isset($data['order']) && !empty($data['order'])) { 180 $orderSql = $this->_getOrderSql($data['order']); 181 $this->_db = $this->_db->order($orderSql); 182 } 183 if (isset($data['where']) && !empty($data['where'])) { 184 $and = isset($data['where']['and']) && !empty($data['where']['and']) ? $data['where']['and'] : null; 185 $or = isset($data['where']['or']) && !empty($data['where']['or']) ? $data['where']['or'] : null; 186 $or2 = isset($data['where']['or2']) && !empty($data['where']['or2']) ? $data['where']['or2'] : null; 187 if(!is_null($and)){ 188 foreach ($and as $key => $value) { 189 if(is_array($value)){ 190 foreach ($value as $k => $v) { 191 $this->_db = $this->_db->whereOr($key,$v); 192 } 193 unset($and[$key]); 194 } 195 } 196 $this->_db = $this->_db->where($and); 197 } 198 if(!is_null($or)){ 199 $or_val = ''; 200 for ($i=0; $i < count($or); $i++) { 201 $or_val .= $i == count($or)-1 ? $or[$i] : $or[$i].'|'; 202 } 203 if(!is_null($this->_search)&&$this->_search!=''){ 204 $this->_db = $this->_db->where($or_val,'like','%'.$this->_search.'%'); 205 } 206 } 207 if(!is_null($or2)){ 208 foreach ($or2 as $key => $value) { 209 if(!is_array($value)) return false; 210 foreach ($value as $k => $v) { 211 $this->_db = $this->_db->whereOr($key,$v); 212 } 213 } 214 } 215 } 216 if (isset($this->_start) && isset($this->_length)) { 217 $this->_db = $this->_db->limit($this->_start,$this->_length); 218 } 219 if ($debug) { 220 var_dump($this->_db->fetchSql(true)->select());die; 221 } 222 $db1 = clone $this->_db; 223 $info = $this->_db->select(); 224 $this->_recordsTotal = $db1->count(); 225 $this->_recordsFiltered = $this->_recordsTotal; 226 return array( 227 'draw' => intval($this->_draw), 228 'recordsTotal' => intval($this->_recordsTotal), 229 'recordsFiltered' => intval($this->_recordsFiltered), 230 'data' => $info, 231 ); 232 } 233 234 /** 235 * 当前台需要排序的时候会根据需要排序的列对应的表中的值排序 236 * 构建排序的sql. 237 * 238 * @param array $data 构造函数第二个参数order部分 239 * 240 * @return string 排序部分的sql语句 241 */ 242 protected function _getOrderSql($data) 243 { 244 $sql = ''; 245 if (is_array($data)) { 246 foreach ($data as $key => $value) { 247 if ($key == $this->_order_column) { 248 $sql = "{$value} ".$this->_order_dir; 249 break; 250 } 251 } 252 } 253 return $sql; 254 } 255 256 /** 257 * 构建select部分的sql语句. 258 * 259 * @param array $data 构造函数第二个参数select部分 260 * 261 * @return string select部分的语句 262 */ 263 protected function _getSelectSql($data) 264 { 265 $list = array(); 266 foreach ($data as $key => $value) { 267 if (is_numeric($key)) { 268 array_push($list, $value); 269 } else { 270 array_push($list, $key.' AS '.$value); 271 } 272 } 273 if (!empty($list)) { 274 $selectSql = implode(',', $list); 275 } else { 276 $selectSql = '*'; 277 } 278 return $selectSql; 279 } 280 }
控制器类调用
1 <?php 2 3 namespace app\index\controller; 4 5 use think\Controller; 6 use think\Db; 7 use DataTable; 8 9 class Index extends Controller 10 { 11 public function list() 12 { 13 return view('index/list'); 14 } 15 16 public function list_ajax() 17 { 18 $get = input('get.'); 19 $where = []; 20 $data['select'] = ['think_user.id'=>'t_id','think_user.uname','think_user.upwd','think_banji.banji_name','think_user.status']; 21 $data['order'] = ['0'=>'think_user.id','1'=>'think_user.uname','2'=>'think_user.upwd','3'=>'think_banji.banji_name']; 22 // $data['where']['and'] = ['think_user.status'=>1,'think_user.id'=>[1,2]]; 23 $data['where']['or'] = ['think_user.uname','think_user.upwd']; 24 $data['join'] = [ 25 'think_banji'=>['think_user.banji_id','think_banji.id'], 26 ]; 27 $a = new DataTable($get, $data, 'think_user'); 28 return $a->output(); 29 } 30 }