db, $this->prefix) = \Frame\Model::_load_db(); $this->uid = \Phpcmf\Service::C()->uid; $this->site = \Phpcmf\Service::C()->site; $this->admin = \Phpcmf\Service::C()->admin; $this->member = \Phpcmf\Service::C()->member; $this->siteid = defined('SITE_ID') ? SITE_ID : 0; } // 设置初始化查询条件 public function init($data) { isset($data['id']) && $this->id = $this->key = $data['id']; isset($data['table']) && $this->table = $data['table']; isset($data['stable']) && $this->stable = $data['stable']; isset($data['sfield']) && $this->sfield = $data['sfield']; isset($data['field']) && $this->field = $data['field']; isset($data['date_field']) && $this->date_field = $data['date_field']; isset($data['order_by']) && $this->param['order_list'] = $data['order_by']; isset($data['group_by']) && $this->param['group_list'] = $data['group_by']; isset($data['order_list']) && $this->param['order_list'] = $data['order_list']; isset($data['where_list']) && $this->param['where_list'] = $data['where_list']; isset($data['is_diy_where_list']) && $this->param['is_diy_where_list'] = $data['is_diy_where_list']; isset($data['join_list']) && $this->param['join_list'] = $data['join_list']; isset($data['select_list']) && $this->param['select_list'] = $data['select_list']; $this->init = $data; // 方便调用 return $this; } // 设置列表搜索条件 public function set_where_list($where) { $this->param['where_list'] = $where; } // 追加列表搜索条件 public function add_where_list($where) { $this->param['where'][] = $where; } // 设置操作主键 public function id($id = '') { if ($id) { $this->key = $id; } else { $this->key = $this->id; } return $this; } // 设置数据源 public function db_source($name = '') { if ($name) { $this->db_temp = $this->db; list($this->db, $this->prefix) = \Frame\Model::_load_db_source($name); } return $this; } // 设置操作表 public function table($name) { $this->table = $name; return $this; } // 设置操作站点的表 public function table_site($name, $site = 0) { if (!$site) { $site = $this->siteid ? $this->siteid : SITE_ID; } $this->table = dr_site_table_prefix($name, $site); return $this; } // 获取表前缀 public function dbprefix($name = '') { return $this->prefix.$name; } // 执行sql public function query($sql) { if (!$this->db->simpleQuery($sql)) { $error = $this->db->error(); $this->_clear(); log_message('error', $sql.': '.$error['message'].'
'.FC_NOW_URL); return $this->_return_error($error['message']); } $this->_clear(); return dr_return_data(1); } // 附表不存在时创建附表 public function is_data_table($table, $tid) { if ($tid > 0 && !$this->is_table_exists($this->dbprefix($table.$tid))) { // 附表不存在时创建附表 list($a, $sql, $name) = \Phpcmf\Service::M('table')->create_table_sql($this->dbprefix($table).'0'); $this->query(str_replace( [$name, 'CREATE TABLE '], [$this->dbprefix($table.$tid), 'CREATE TABLE IF NOT EXISTS '], $a )); } $this->_clear(); } // 表是否存在 public function is_table_exists($table) { if (!$table) { $this->_clear(); return 0; } $table = strpos($table, $this->prefix) === 0 ? $table : $this->dbprefix($table); $rt = $this->db->tableExists($table) ? 1 : 0; $this->_clear(); return $rt; } // 表字段是否存在 public function is_field_exists($table, $name) { if (!$table || !$name) { $this->_clear(); return 0; } $table = strpos($table, $this->prefix) === 0 ? $table : $this->dbprefix($table); $rt = $this->db->fieldExists($name, $table) ? 1 : 0; $this->_clear(); return $rt; } // 字段值是否存在 public function is_exists($id, $name, $value) { $builder = $this->db->table($this->table); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false); } } $rt = $builder->where($name, $value)->where($this->key.'<>'. $id)->countAllResults(); $this->_clear(); return $rt; } // 统计数量 public function counts($table = '', $where = '') { $table = !$table ? $this->table : $table; if (!$table) { return 0; } $builder = $this->db->table($table); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false); } } // 分组 $this->param['group'] && $builder->groupBy($this->param['group']); $where && $builder->where($where); $this->_clear(); return $builder->countAllResults(); } // 插入数据 public function insert($data) { $this->db->table($this->table)->insert($data); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); log_message('error', $this->table.': '.$rt['message'].'
'.FC_NOW_URL); return $this->_return_error($this->table.': '.$rt['message']); } $id = $this->db->insertID(); !$id && $id = intval($data[$this->key]); if (!$id) { $this->_clear(); log_message('debug', $this->table.': 主键获取失败
'.FC_NOW_URL); return $this->_return_error($this->table.': 主键获取失败'); } $this->_clear(); return dr_return_data($id); } // 插入数据 public function replace($data) { $this->db->table($this->table)->replace($data); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); log_message('error', $this->table.': '.$rt['message'].'
'.FC_NOW_URL); return $this->_return_error($this->table.': '.$rt['message']); } $id = $this->db->insertID(); !$id && $id = intval($data[$this->key]); if (!$id) { $this->_clear(); log_message('debug', $this->table.': 主键获取失败
'.FC_NOW_URL); return $this->_return_error($this->table.': 主键获取失败'); } $this->_clear(); return dr_return_data($id); } // 批量插入 public function insert_batch($data) { if (!$this->table || !$data) { return; } $rt = $this->db->table($this->table)->insertBatch($data); $this->_clear(); return $rt; } // 批量更新 public function update_batch($data, $key = 'id') { if (!$this->table || !$data) { return; } $this->db->table($this->table)->updateBatch($data, $key ? $key : $this->key); $this->_clear(); } // 更新数据 public function update($id, $data, $where = '') { if (!$data) { $this->_clear(); return $this->_return_error($this->table.': update() data值为空'); } $db = $this->db->table($this->table); $id && $db->where($this->key, (int)$id); $where && $db->where($where, null, false); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false); } } $db->update($data); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); log_message('error', $this->table.': '.$rt['message'].'
'.FC_NOW_URL); return $this->_return_error($this->table.': '.$rt['message']); } $this->_clear(); return dr_return_data($id); } // 删除数据 /* * 主键 * */ public function delete($id = 0 , $where = '') { $db = $this->db->table($this->table); $where && $db->where($where, null, false); $id && $db->where($this->key, (int)$id); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false); } } // 执行删除 $db->delete(); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); log_message('error', $this->table.': '.$rt['message'].'
'.FC_NOW_URL); return $this->_return_error($this->table.': '.$rt['message']); } $this->_clear(); return dr_return_data(1); } // 执行”写入”类型的语句(insert,update等)时返回有多少行受影响 public function affected_rows() { return $this->db->affectedRows(); } // 启动事务 public function trans_start(){ $this->db->transBegin(); } // 回滚事务 public function trans_rollback(){ $this->db->transRollback(); } // 执行事务提交 public function trans_comment(){ if ($this->db->transStatus() === FALSE) { $this->db->transRollback(); return false; } else { $this->db->transCommit(); return true; } } // 删除全部内容 public function clear_all() { return $this->db->table($this->table)->truncate(); } // 批量删除数据 /* * 主键数组 * */ public function delete_all($ids, $where = '') { $this->deleteAll($ids, $where); } public function deleteAll($ids, $where = '') { $db = $this->db->table($this->table); $where && $db->where($where, null, false); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false); } } $db->whereIn($this->key, (array)$ids)->delete(); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); log_message('error', $this->table.': '.$rt['message'].'
'.FC_NOW_URL); return $this->_return_error($this->table.': '.$rt['message']); } $this->_clear(); return dr_return_data(1); } /* * 保存单个数据 * 主键 * 字段名 * 字段值 * */ public function save($id, $name, $value, $where = '') { $db = $this->db->table($this->table); $where && $db->where($where, null, false); $db->where($this->key, (int)$id)->update([$name => $value]); $rt = $this->db->error(); if ($rt['code']) { $this->_clear(); return $this->_return_error($this->table.': '.$rt['message']); } $this->_clear(); return dr_return_data($id); } /* * 获取单个数据 * 主键 * */ public function get($id) { $query = $this->db->table($this->table)->where($this->key, (int)$id)->get(); if (!$query) { $this->_clear(); return []; } $rt = $query->getRowArray(); $this->_clear(); return $rt; } /* * 获取全部数据 * 指定数量 * 数组主键id * */ public function get_all($num = 0, $key = '') { return $this->getAll($num, $key); } public function getAll($num = 0, $key = '') { $builder = $this->db->table($this->table); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false); } } // select字段 $this->_apply_builder_select($builder); // 排序 $this->param['order'] && $builder->orderBy($this->param['order']); // 分组 $this->param['group'] && $builder->groupBy($this->param['group']); // 数量控制 if ($this->param['limit']) { list($a, $b) = explode(',', $this->param['limit']); if ($b) { $builder->limit($a, $b); } else { $builder->limit($a); } } elseif ($num) { $builder->limit($num); } $query = $builder->get(); if (!$query) { $this->_clear(); return []; } $rt = $query->getResultArray(); if ($rt && $key) { $rt2 = $rt; $rt = []; foreach ($rt2 as $i => $t) { $rt[(isset($t[$key]) ? $t[$key] : $i)] = $t; } } $this->_clear(); return $rt; } /* * 获取单个数据 * */ public function getRow() { $builder = $this->db->table($this->table); // 条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false); } } // in条件 if ($this->param['where_in']) { foreach ($this->param['where_in'] as $v) { dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false); } } // select字段 $this->_apply_builder_select($builder); if (!$builder) { $this->_clear(); return []; } // 排序 $this->param['order'] && $builder->orderBy($this->param['order']); // 分组 $this->param['group'] && $builder->groupBy($this->param['group']); $builder->limit(1); $rt = $builder->get(); $data = []; $rt && $data = $rt->getRowArray(); $this->_clear(); return $data; } /* * 获取单个字段值 * */ public function getField($name) { $data = $this->getRow(); return isset($data[$name]) ? $data[$name] : ''; } /* * 操作数据 * 数据不存在-1, 变更值0, 变更至1 * */ public function used($id, $name) { $data = $this->db->table($this->table)->select($name)->where('id', (int)$id)->get()->getRowArray(); if ($data) { $value = $data[$name] ? 0 : 1; // 更新 $this->db->table($this->table)->where('id', $id)->update([$name => $value]); $this->_clear(); return $value; } $this->_clear(); return -1; } ///////////////////////////////////////////////////////////////////////// // 条件组合(按字段类型分发到 where_field_*) public function _where($table, $name, $value, $field, $is_like = false) { if (!$value && dr_strlen($value) == 0) { return ''; //空值 } $name = dr_safe_replace($name, ['\\', '/']); $ft = isset($field['fieldtype']) ? $field['fieldtype'] : ''; if ($ft == 'Date' || in_array($name, ['inputtime', 'updatetime'])) { list($s, $e) = explode(',', (string) $value); $s = (int) strtotime((string) $s); $e = (int) strtotime((string) $e); if ($s == $e && $s == 0) { return ''; } $col = $this->_where_field_col($table, $name); // 无结束日期:开区间(各库语法一致,不必走驱动) if (!$e) { return $col.' > '.$s; } return $this->where_between($col, $s, $e); } if ($ft == 'File' && isset($field['fieldname']) && $field['fieldname'] == 'thumb' && $value == 1) { return $this->where_field_thumb($table, $name, $value); } if ($ft && strpos($ft, 'map') !== false) { return $this->where_field_map($table, $name, $value); } if ($ft == 'Diy' && !empty($field['setting']['option']['file']) && function_exists('dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_search')) { return $this->where_field_diy($table, $name, $value, $field); } if ($ft == 'Linkage') { return $this->where_field_linkage($table, $name, $value, $field, $is_like); } if ($ft == 'Linkages') { return $this->where_field_linkages($table, $name, $value, $field, $is_like); } if (in_array($ft, ['Selects', 'Checkbox', 'Cats'])) { return $this->where_field_checkbox($table, $name, $value, $field, $is_like); } if (in_array($ft, ['Members', 'Related'])) { return $this->where_field_members($table, $name, $value); } if (in_array($ft, ['Radio', 'Select'])) { return $this->where_field_select($table, $name, $value, $field, $is_like); } if (substr_count($value, ',') == 1 && preg_match('/[\+\-0-9\.]+,[\+\-0-9\.]+/', $value)) { list($s, $e) = explode(',', (string) $value); $s = floatval($s); $e = floatval($e); $col = $this->_where_field_col($table, $name); if ($s == $e && $s == 0) { return $col.' = 0'; } if (!$e && $s > 0) { return $col.' > '.$s; } if (!$e) { $e = 0; } return $this->where_between($col, $s, $e); } if ($is_like || strpos($value, '%') !== false || strpos($value, ' ') !== false) { return $this->where_field_like($table, $name, $value); } return $this->where_field_eq($table, $name, $value); } protected function _limit_where(&$select, $param, $field, $table) { $table = $this->dbprefix($table); if (isset($param['keyword']) && $param['keyword']) { $param['keyword'] = htmlspecialchars(urldecode($param['keyword'])); } $fname = $param['field']; $kw = $param['keyword']; $finfo = isset($field[$fname]) && is_array($field[$fname]) ? $field[$fname] : []; $ft = isset($finfo['fieldtype']) ? $finfo['fieldtype'] : ''; if ($fname == $this->id) { $sql = $this->where_limit_id($table, $this->id, $kw); } elseif (!empty($finfo['myfunc'])) { $sql = $this->where_limit_myfunc($param, $finfo); } elseif ($fname == 'uid' || $ft == 'Uid') { $sql = $this->where_limit_uid($table, $fname, $kw); } elseif ($ft == 'INT' || !empty($finfo['isint'])) { $sql = $this->where_limit_int($table, $fname, $kw); } elseif (!empty($finfo['isemoji'])) { $sql = $this->where_limit_emoji($table, $fname, $kw); } elseif (!empty($finfo['iswhere'])) { $sql = $this->where_limit_eq($table, $fname, $kw); } else { $sql = $this->_where($table, $fname, $kw, $finfo, true); } if ($sql !== null && $sql !== '') { $select->where($sql, null, false); } return $select; } /** * 日期字符串转时间戳(无时分秒时:开始补 00:00:00,结束补 23:59:59) */ protected function _limit_date_to_time($date, $is_end = false) { $date = trim((string) $date); if ($date === '') { return $is_end ? SYS_TIME : 1; } if (strpos($date, ' ') === false) { $date .= $is_end ? ' 23:59:59' : ' 00:00:00'; } return (int) strtotime($date); } /** * 条件查询 * * @param object $select 查询对象 * @param intval $where 是否搜索 * @return intval */ protected function _limit_page_where(&$select, $param) { // 默认搜索条件 $this->param['where_list'] && $select->where($this->param['where_list']); // 默认搜索条件 关联查询 $this->param['join_list'] && $select->join( $this->param['join_list'][0], $this->param['join_list'][1], $this->param['join_list'][2] ); // 定义的条件 if ($this->param['where']) { foreach ($this->param['where'] as $v) { dr_count($v) == 2 ? $select->where($v[0], $v[1]) : $select->where($v, null, false); } } // 条件搜索 if ($param) { $field = $this->field; $field[$this->id] = $this->id; // 关键字 + 自定义字段搜索 if (isset($param['keyword']) && $param['keyword'] != '') { if (isset($this->init['is_swhere']) && $this->init['is_swhere']) { if (isset($this->sfield[$param['field']]) && $this->stable) { $select = $this->_limit_where($select, $param, $this->sfield, $this->stable); } elseif (isset($field[$param['field']])) { $select = $this->_limit_where($select, $param, $field, $this->table); } } else { if (isset($field[$param['field']])) { $select = $this->_limit_where($select, $param, $field, $this->table); } elseif (isset($this->sfield[$param['field']]) && $this->stable) { $select = $this->_limit_where($select, $param, $this->sfield, $this->stable); } } } // 时间搜索(date_form / date_to → BETWEEN) if ($this->date_field) { $date_form = isset($param['date_form']) ? trim((string) $param['date_form']) : ''; $date_to = isset($param['date_to']) ? trim((string) $param['date_to']) : ''; if ($date_form !== '' || $date_to !== '') { if ($date_form !== '') { $start = max($this->_limit_date_to_time($date_form, false), 1); $end = $date_to !== '' ? $this->_limit_date_to_time($date_to, true) : SYS_TIME; } else { $start = 1; $end = $this->_limit_date_to_time($date_to, true); } $sql = $this->where_between($this->date_field, $start, $end); if ($sql) { $select->where($sql, null, false); } } } // 栏目查询 if (isset($param['catid']) && $param['catid'] && function_exists('dr_cat_value')) { $mid = defined('MOD_DIR') ? MOD_DIR : (APP_DIR ? APP_DIR : 'share'); $cat = dr_cat_value($mid, $param['catid']); $cat && $cat['child'] ? $select->whereIn('catid', explode(',', $cat['childids'])) : $select->where('catid', (int)$param['catid']); } // 其他自定义字段查询 if (isset($this->param['is_diy_where_list']) && $this->param['is_diy_where_list']) { $where = []; foreach ($param as $i => $v) { if (!in_array($i, ['id', 'keyword', 'catid', 'date_form', 'date_to', 'field', 'total']) && isset($field[$i]) && $field[$i]['ismain'] && strlen($v)) { $where[] = str_replace('`{finecms_table}`.', '', $this->_where('{finecms_table}', $i, $v, $field)); } } $where && $select->where(implode(' AND ', $where), null, false); } } return $param; } // 分页 public function limit_page($size = SYS_ADMIN_PAGESIZE, $where = '') { $page = max(1, (int)\Phpcmf\Service::L('input')->get('page')); $total = (int)\Phpcmf\Service::L('input')->get('total'); $param = \Phpcmf\Service::L('input')->get(); unset($param['s'], $param['c'], $param['m'], $param['d'], $param['page']); if (isset($param['keyword']) && $param['keyword']) { $param['keyword'] = trim(urldecode($param['keyword'])); } if ($size > 0 && !$total) { $select = $this->db->table($this->table); if ($this->param['group_list']) { $select->select('count(DISTINCT '.$this->param['group_list'].') as total'); } else { $select->select('count(*) as total'); } // 自定义查询闭包函数 if (isset($this->init['select_function'])) { $this->init['select_function']($select); } $where && $select->where($where); $param = $this->_limit_page_where($select, $param); $query = $select->get(); if (!$query) { log_message('debug', '数据查询失败:'.$this->table); $this->_clear(); return [[], $total, $param]; } $data = $query->getRowArray(); $total = (int)$data['total']; $param['total'] = $total; unset($select); if (!$total) { $this->_clear(); return [[], $total, $param]; } } $select = $this->db->table($this->table); $this->param['select_list'] && $select->select($this->param['select_list']); // 自定义查询闭包函数 if (isset($this->init['select_function'])) { $this->init['select_function']($select); } $where && $select->where($where); $param = $this->_limit_page_where($select, $param); if ($size > 0) { $select->limit($size, intval($size * ($page - 1))); } $this->param['group_list'] && $select->groupBy($this->param['group_list']); //分析参数合法性 $order = isset($param['order']) && $param['order'] ? urldecode($param['order']) : ''; // 获取的排序参数 $order_str = dr_safe_replace($this->param['order_list']); if ($order) { $arr = explode(',', $order); $order_arr = []; foreach ($arr as $t) { list($order_field, $b) = explode(' ', $t); if ($this->is_field_exists($this->table, $order_field)) { if ($this->stable && $this->is_field_exists($this->stable, $order_field)) { // 两个表都有这个字段 $order_arr[] = $this->table.'.'.$order_field.' '.($b && $b=='asc' ? 'asc' : 'desc'); } else { $order_arr[] = $order_field.' '.($b && $b=='asc' ? 'asc' : 'desc'); } } elseif ($this->stable && $this->is_field_exists($this->stable, $order_field)) { $order_arr[] = $this->stable.'.'.$order_field.' '.($b && $b=='asc' ? 'asc' : 'desc'); } } if ($order_arr) { $order_str = implode(',', $order_arr); } } $query = $select->orderBy($order_str ? $order_str : 'id desc')->get(); if (!$query) { log_message('debug', '数据查询失败:'.$this->table); $this->_clear(); return [[], $total, $param]; } $data = $query->getResultArray(); $param['order'] = $order; $param['total'] = $total; // 收尾工作 $this->_clear(); return [$data, $total, $param]; } /** * 是否含标识符引号字符(` " [) */ public function has_id_quotes($expr) { return (bool) preg_match('/[`"\[]/', (string) $expr); } /** * 是否已是列表达式(含表.字段 或已加引) */ public function is_column_expr($expr) { $expr = (string) $expr; return strpos($expr, '.') !== false || $this->has_id_quotes($expr); } /** * 去掉标识符外层引号(单段) */ public function strip_id_quotes($id) { return trim(preg_replace('/^[`"\[\]]+|[`"\[\]]+$/', '', (string) $id)); } /** * 去掉表达式中全部标识符引号,保留点号 */ public function unquote_id($expr) { return trim(preg_replace('/[`"\[\]]+/', '', (string) $expr)); } /** * 取裸字段名(剥引号后取最后一段,如 `t`.`thumb` → thumb) */ public function bare_field($expr) { $bare = $this->unquote_id($expr); if ($bare === '') { return ''; } if (strpos($bare, '.') !== false) { $parts = explode('.', $bare); return (string) end($parts); } return $bare; } /** * 单段标识符加引(走驱动 escapeIdentifiers) */ public function quote_id($id) { $id = $this->strip_id_quotes($id); if ($id === '') { return ''; } if ($this->db && method_exists($this->db, 'escapeIdentifiers')) { return $this->db->escapeIdentifiers($id); } return '`'.$id.'`'; } /** * 表名加引 */ public function quote_table($table) { return $this->quote_id($table); } /** * 表.字段 加引(table、name 均可为已加引旧串,会先剥再加) */ public function quote_field($table, $name = '') { if ($name === '' || $name === null) { return $this->quote_column($table); } return $this->quote_id($table).'.'.$this->quote_id($name); } /** * 列表达式规范化加引(支持 thumb / table.thumb / `t`.`f` / "t"."f") */ public function quote_column($expr) { $bare = $this->unquote_id($expr); if ($bare === '') { return ''; } if (strpos($bare, '.') !== false) { $parts = explode('.', $bare); $field = array_pop($parts); $table = implode('.', $parts); return $this->quote_field($table, $field); } return $this->quote_id($bare); } ///////////////////////////////////////////////////////////////////////// /** 字段条件:表列标识(驱动加引) */ protected function _where_field_col($table, $name) { if ($table === '' || $table === null) { return $this->quote_column($name); } // name 已是完整列表达式时只规范化 if ($this->is_column_expr($name)) { return $this->quote_column($name); } return $this->quote_field($table, $name); } /** 多条件 OR/AND 合并(value 含 || 时用 AND) */ protected function _where_field_join($value, array $where, $table) { if (!$where) { return $this->_where_field_col($table, 'id').' = 0'; } $op = strpos((string) $value, '||') !== false ? ' AND ' : ' OR '; return '('.implode($op, $where).')'; } /** * 尝试调用当前数据库驱动的 where 表达式方法 * @return array{0:bool,1:mixed} [是否已由驱动处理, 驱动返回值] */ protected function _try_db_where($method, ...$args) { if ($this->db && method_exists($this->db, $method)) { return [true, call_user_func_array([$this->db, $method], $args)]; } return [false, null]; } /** * FIND_IN_SET 表达式(优先驱动 whereFindInSet;默认 MySQL) * @param string $column 已带标识符的列,如 `dr_x`.`uid` */ public function where_find_in_set($column, $value) { list($ok, $sql) = $this->_try_db_where('whereFindInSet', (string) $column, $value); if ($ok) { return $sql; } // 默认 MySQL if (dr_is_numeric($value)) { return 'FIND_IN_SET('.intval($value).','.(string) $column.')'; } return 'FIND_IN_SET("'.dr_safe_replace($value).'",'.(string) $column.')'; } /** * BETWEEN 条件(日期时间戳 / 数值区间统一入口;驱动可选实现 whereBetween) * @param string $column 已拼好的列名 * @param float|int $start * @param float|int $end */ public function where_between($column, $start, $end) { list($ok, $sql) = $this->_try_db_where('whereBetween', (string) $column, $start, $end); if ($ok) { return $sql; } $column = (string) $column; if ($column === '') { return ''; } return $column.' BETWEEN '.$start.' AND '.$end; } /** * 不等于(驱动可选 whereNe;默认 !=,避免部分库不支持 <>) * @param string $column 已拼好的列名 * @param mixed $value 比较值;空字符串表示 != '' */ public function where_ne($column, $value = '') { list($ok, $sql) = $this->_try_db_where('whereNe', (string) $column, $value); if ($ok) { return $sql; } $column = (string) $column; if ($column === '') { return ''; } if ($value === '' || $value === null) { return $column." != ''"; } if (dr_is_numeric($value)) { return $column.' != '.$value; } return $column." != '".dr_safe_replace($value)."'"; } /** * LIKE 条件(驱动可选 whereLike) * @param string $column 已拼好的列名 * @param string $keyword 关键词(可不带 %) * @param string $side both|left|right|none(none 表示 keyword 已含通配符) */ public function where_like($column, $keyword, $side = 'both') { list($ok, $sql) = $this->_try_db_where('whereLike', (string) $column, $keyword, $side); if ($ok) { return $sql; } $column = (string) $column; if ($column === '') { return ''; } $kw = trim($this->db->escapeString((string) $keyword, true), '%'); if ($side === 'right') { $pat = $kw.'%'; } elseif ($side === 'left') { $pat = '%'.$kw; } elseif ($side === 'none') { $pat = $kw; } else { $pat = '%'.$kw.'%'; } return $column.' LIKE \''.$pat.'\''; } /** * IN / NOT IN 表达式(驱动可选 whereInExpr;与链式 where_in 区分) * @param string $column 已拼好的列名 * @param array|string $values 数组或逗号分隔字符串 * @param bool $not true 为 NOT IN */ public function where_in_expr($column, $values, $not = false) { list($ok, $sql) = $this->_try_db_where('whereInExpr', (string) $column, $values, $not); if ($ok) { return $sql; } $column = (string) $column; if ($column === '') { return ''; } if (!is_array($values)) { $values = explode(',', (string) $values); } $str = ''; foreach ($values as $a) { if (is_string($a)) { $a = trim($a); } if ($a === '' || $a === null) { continue; } $str .= dr_is_numeric($a) ? ','.$a : ',\''.dr_safe_replace($a).'\''; } $str = trim($str, ','); if ($str === '') { return ''; } return $column.($not ? ' NOT IN (' : ' IN (').$str.')'; } /** * 大小比较(驱动可选 whereCmp) * @param string $column 已拼好的列名 * @param string $op >|>=|<|<= * @param mixed $value 比较值(数值不强转时原样;模板 GT 等传 intval) */ public function where_cmp($column, $op, $value) { list($ok, $sql) = $this->_try_db_where('whereCmp', (string) $column, $op, $value); if ($ok) { return $sql; } $column = (string) $column; $op = (string) $op; if ($column === '' || !in_array($op, ['>', '>=', '<', '<='], true)) { return ''; } if (dr_is_numeric($value)) { return $column.' '.$op.' '.$value; } return $column.' '.$op.' \''.dr_safe_replace($value).'\''; } // 缩略图 File/thumb(value=1 有图;否则无图;name 可已带表前缀) public function where_field_thumb($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereFieldThumb', $table, $name, $value); if ($ok) { return $sql; } $col = $this->_where_field_col($table, $name); if ($value == 1) { return $this->where_ne($col, ''); } return $col." = ''"; } // 地图范围 public function where_field_map($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereFieldMap', $table, $name, $value); if ($ok) { return $sql; } list($a, $km) = explode('|', $value); list($lng, $lat) = explode(',', $a); if ($km && $lat && $lng) { $squares = dr_square_point($lng, $lat, $km); $lat_col = $this->quote_field($table, $name.'_lat'); $lng_col = $this->quote_field($table, $name.'_lng'); return '('.$this->where_between($lat_col, $squares['right-bottom']['lat'], $squares['left-top']['lat']) .' AND '.$this->where_between($lng_col, $squares['left-top']['lng'], $squares['right-bottom']['lng']).')'; } return '1=1'; } // DIY 字段搜索回调 public function where_field_diy($table, $name, $value, $field) { list($ok, $sql) = $this->_try_db_where('whereFieldDiy', $table, $name, $value, $field); if ($ok) { return $sql; } return call_user_func( 'dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_search', $table, $name, $value, $field ); } // 联动菜单 public function where_field_linkage($table, $name, $value, $field, $is_like = false) { list($ok, $sql) = $this->_try_db_where('whereFieldLinkage', $table, $name, $value, $field, $is_like); if ($ok) { return $sql; } $arr = explode('|', $value); $where = []; if ($is_like && $value) { $key = \Phpcmf\Service::L('cache')->get_file('key', 'linkage/'.SITE_ID.'_'.$field['setting']['option']['linkage'].'/'); if ($key) { $query = $this->db->table($this->dbprefix('linkage_data_'.$key))->like('name', $value)->get(); $row = $query ? $query->getRowArray() : null; if ($row) { $arr[] = $row['cname']; } } } $col = $this->_where_field_col($table, $name); foreach ($arr as $val) { $data = dr_linkage($field['setting']['option']['linkage'], $val); if ($data) { if ($data['child']) { $where[] = $col.' IN ('.$data['childids'].')'; } else { $where[] = $col.'='.intval($data['ii']); } } } return $this->_where_field_join($value, $where, $table); } // 联动菜单多选 public function where_field_linkages($table, $name, $value, $field, $is_like = false) { list($ok, $sql) = $this->_try_db_where('whereFieldLinkages', $table, $name, $value, $field, $is_like); if ($ok) { return $sql; } $arr = explode('|', $value); $where = []; if ($is_like && $value) { $key = \Phpcmf\Service::L('cache')->get_file('key', 'linkage/'.SITE_ID.'_'.$field['setting']['option']['linkage'].'/'); if ($key) { $query = $this->db->table($this->dbprefix('linkage_data_'.$key))->like('name', $value)->get(); $row = $query ? $query->getRowArray() : null; if ($row) { $arr[] = $row['cname']; } } } foreach ($arr as $val) { $data = dr_linkage($field['setting']['option']['linkage'], $val); if ($data) { if ($data['child']) { $ids = explode(',', $data['childids']); foreach ($ids as $id) { if ($id) { $where[] = $this->where_json($table, $name, $id); } } } else { $where[] = $this->where_json($table, $name, intval($data['ii'])); } } } return $this->_where_field_join($value, $where, $table); } // 复选 Selects / Checkbox / Cats public function where_field_checkbox($table, $name, $value, $field, $is_like = false) { list($ok, $sql) = $this->_try_db_where('whereFieldCheckbox', $table, $name, $value, $field, $is_like); if ($ok) { return $sql; } $arr = explode('|', $value); $where = []; if ($is_like && $value) { $option = dr_format_option_array($field['setting']['option']['options']); if ($option) { $new = []; foreach ($option as $k => $v) { if (strpos($v, (string) $value) !== false) { $new[] = $k; } } if ($new) { $arr = $new; } } } foreach ($arr as $val) { if ($val) { $where[] = $this->where_json($table, $name, $this->db->escapeString(dr_safe_replace($val), true)); } } return $this->_where_field_join($value, $where, $table); } // Members / Related(FIND_IN_SET) public function where_field_members($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereFieldMembers', $table, $name, $value); if ($ok) { return $sql; } $arr = explode('|', $value); $where = []; $col = $this->_where_field_col($table, $name); foreach ($arr as $val) { if ($val === '' || $val === null) { continue; } $where[] = $this->where_find_in_set($col, $val); } return $this->_where_field_join($value, $where, $table); } // Radio / Select public function where_field_select($table, $name, $value, $field, $is_like = false) { list($ok, $sql) = $this->_try_db_where('whereFieldSelect', $table, $name, $value, $field, $is_like); if ($ok) { return $sql; } $arr = explode('|', $value); if ($is_like && $value) { $option = dr_format_option_array($field['setting']['option']['options']); if ($option) { $new = []; foreach ($option as $k => $v) { if (strpos($v, $value) !== false) { $new[] = $k; } } if ($new) { $arr = $new; } } } $where = []; $col = $this->_where_field_col($table, $name); foreach ($arr as $val) { if (dr_is_numeric($val)) { $where[] = $col.'='.$val; } else { $where[] = $col.'=\''.dr_safe_replace($val, ['\\', '/']).'\''; } } return $this->_where_field_join($value, $where, $table); } // LIKE / 多关键词 public function where_field_like($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereFieldLike', $table, $name, $value); if ($ok) { return $sql; } $col = $this->_where_field_col($table, $name); $arr = explode('%', str_replace(' ', '%', $value)); if (count($arr) == 1) { return $this->where_like($col, $value, 'both'); } $wh = []; foreach ($arr as $c) { $c && $wh[] = $this->where_like($col, $c, 'both'); } return $wh ? ('('.implode(strpos($value, '%%') !== false ? ' AND ' : ' OR ', $wh).')') : ''; } // 等值 public function where_field_eq($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereFieldEq', $table, $name, $value); if ($ok) { return $sql; } $col = $this->_where_field_col($table, $name); if (dr_is_numeric($value)) { return $col.'='.$value; } return $col.'=\''.dr_safe_replace($value, ['\\', '/']).'\''; } // 列表搜索:按主键 id(单值或 IN) public function where_limit_id($table, $name, $keyword) { list($ok, $sql) = $this->_try_db_where('whereLimitId', $table, $name, $keyword); if ($ok) { return $sql; } $ids = []; foreach (explode(',', (string) $keyword) as $i) { $ids[] = (int) $i; } $col = $this->_where_field_col($table, $name); if (dr_count($ids) == 1) { return $col.' = '.(int) $ids[0]; } return $col.' IN ('.implode(',', array_map('intval', $ids)).')'; } // 列表搜索:字段 myfunc 自定义 public function where_limit_myfunc($param, $field) { list($ok, $sql) = $this->_try_db_where('whereLimitMyfunc', $param, $field); if ($ok) { return $sql; } $func = isset($field['myfunc']) ? $field['myfunc'] : ''; if (!$func) { return ''; } if (!function_exists($func)) { CI_DEBUG && log_message('debug', '字段myfunc参数中的函数('.$func.')未定义'); return ''; } $rt = call_user_func_array($func, [$param]); return $rt ? (string) $rt : ''; } // 列表搜索:Uid / uid(数字按会员 id,否则按用户名查 id) public function where_limit_uid($table, $name, $keyword) { list($ok, $sql) = $this->_try_db_where('whereLimitUid', $table, $name, $keyword); if ($ok) { return $sql; } $col = $this->_where_field_col($table, $name); $uid = dr_is_numeric($keyword) ? intval($keyword) : 0; if ($uid && $this->db->table('member')->where('id', $uid)->countAllResults()) { return $col.' = '.$uid; } // 用户名模糊 → 先查 id 再 IN(避免子查询方言差异) $query = $this->db->table('member')->select('id')->like('username', $keyword)->get(); $rows = $query ? $query->getResultArray() : []; if (!$rows) { return '1=0'; } $ids = []; foreach ($rows as $r) { $ids[] = (int) $r['id']; } return $col.' IN ('.implode(',', $ids).')'; } // 列表搜索:整数 public function where_limit_int($table, $name, $keyword) { list($ok, $sql) = $this->_try_db_where('whereLimitInt', $table, $name, $keyword); if ($ok) { return $sql; } return $this->_where_field_col($table, $name).' = '.intval($keyword); } // 列表搜索:表情(原文 + unicode 转义) public function where_limit_emoji($table, $name, $keyword) { list($ok, $sql) = $this->_try_db_where('whereLimitEmoji', $table, $name, $keyword); if ($ok) { return $sql; } $col = $this->_where_field_col($table, $name); $key = $this->db->escapeString($keyword, true); $key2 = $this->db->escapeString( str_replace('\u', '\\\\\\\\u', trim(str_replace('\\', '|', json_encode($keyword)), '"')), true ); return '('.$col.' LIKE \'%'.$key.'%\' OR '.$col.' LIKE \'%'.$key2.'%\')'; } // 列表搜索:准确匹配 public function where_limit_eq($table, $name, $keyword) { list($ok, $sql) = $this->_try_db_where('whereLimitEq', $table, $name, $keyword); if ($ok) { return $sql; } return $this->where_field_eq($table, $name, $keyword); } // 条件 public function field($field) { return $this->select($field); } public function select($field) { if (!$field) { return $this; } $this->param['select'][] = $field; return $this; } /** * 聚合/混合 SELECT(跨库安全,escape=false 交给驱动拼好引号) * 优先驱动 buildSelectAgg;默认 MySQL 反引号 */ public function select_agg($select) { $select = trim((string) $select); if ($select === '') { return $this; } list($ok, $sql) = $this->_try_db_where('buildSelectAgg', $select); if ($ok && $sql !== null && $sql !== '') { $this->param['select_raw'][] = $sql; } else { $this->param['select_raw'][] = $this->_build_select_agg_default($select); } return $this; } /** * COUNT 字段(默认 COUNT(*) AS cnt) */ public function select_count($field = '*', $alias = 'cnt') { return $this->_select_func('COUNT', $field, $alias); } /** * SUM 字段 */ public function select_sum($field, $alias = 'sum') { return $this->_select_func('SUM', $field, $alias); } /** * AVG 字段 */ public function select_avg($field, $alias = 'avg') { return $this->_select_func('AVG', $field, $alias); } /** * MAX 字段 */ public function select_max($field, $alias = 'max') { return $this->_select_func('MAX', $field, $alias); } /** * MIN 字段 */ public function select_min($field, $alias = 'min') { return $this->_select_func('MIN', $field, $alias); } /** * 单个聚合函数 → select_raw */ protected function _select_func($fn, $field, $alias = '') { $fn = strtoupper(trim((string) $fn)); $field = trim((string) $field); $alias = trim((string) $alias); if ($field === '' || !in_array($fn, ['COUNT', 'SUM', 'AVG', 'MAX', 'MIN'], true)) { return $this; } list($ok, $sql) = $this->_try_db_where('buildSelectFunc', $fn, $field, $alias); if ($ok && $sql !== null && $sql !== '') { $this->param['select_raw'][] = $sql; } else { $this->param['select_raw'][] = $this->_build_select_func_default($fn, $field, $alias); } return $this; } /** * 把 select / select_raw 应用到构建器 */ protected function _apply_builder_select($builder) { if (!empty($this->param['select'])) { $builder->select(implode(',', $this->param['select'])); } if (!empty($this->param['select_raw'])) { foreach ($this->param['select_raw'] as $raw) { if ($raw !== '' && $raw !== null) { $builder->select($raw, false); } } } } /** * 默认(MySQL)聚合 SELECT 片段 */ protected function _build_select_agg_default($select) { $parts = $this->_split_select_parts($select); $out = []; foreach ($parts as $part) { $part = trim($part); if ($part === '') { continue; } if (preg_match('/^(COUNT|SUM|AVG|MAX|MIN)\s*\(\s*(.+?)\s*\)\s*(?:AS\s+([`"]?[\w]+[`"]?))?\s*$/i', $part, $m)) { $out[] = $this->_build_select_func_default(strtoupper($m[1]), trim($m[2]), isset($m[3]) ? trim($m[3], '`"[]') : ''); continue; } if (preg_match('/^(.+?)\s+AS\s+([`"]?[\w]+[`"]?)\s*$/i', $part, $m)) { $out[] = $this->_quote_select_ident(trim($m[1])).' AS '.$this->quote_id(trim($m[2], '`"[]')); continue; } $out[] = $this->_quote_select_ident($part); } return implode(', ', $out); } /** * 默认(MySQL)单个聚合函数 */ protected function _build_select_func_default($fn, $field, $alias = '') { $fn = strtoupper((string) $fn); $inner = (trim($field) === '*') ? '*' : $this->_quote_select_ident($field); $sql = $fn.'('.$inner.')'; $alias = trim((string) $alias, '`"[]'); if ($alias !== '') { $sql .= ' AS '.$this->quote_id($alias); } return $sql; } /** * 列标识加引(支持 table.field / *) */ protected function _quote_select_ident($expr) { $expr = trim((string) $expr); if ($expr === '' || $expr === '*') { return $expr === '*' ? '*' : ''; } // 已是函数或复杂表达式:原样返回(调用方应走 select_agg 解析) if (preg_match('/[()\s]/', $expr) && !preg_match('/^[\w.`"\[\]]+$/u', $expr)) { return $expr; } return $this->quote_column($expr); } /** * 按逗号拆 SELECT 列表(忽略括号内逗号) */ protected function _split_select_parts($select) { $parts = []; $buf = ''; $depth = 0; $len = strlen($select); $quote = null; for ($i = 0; $i < $len; $i++) { $ch = $select[$i]; if ($quote !== null) { $buf .= $ch; if ($ch === $quote) { if (($ch === "'" || $ch === '"') && $i + 1 < $len && $select[$i + 1] === $ch) { $buf .= $select[++$i]; continue; } $quote = null; } continue; } if ($ch === "'" || $ch === '"' || $ch === '`') { $quote = $ch; $buf .= $ch; continue; } if ($ch === '(') { $depth++; $buf .= $ch; continue; } if ($ch === ')') { $depth = max(0, $depth - 1); $buf .= $ch; continue; } if ($ch === ',' && $depth === 0) { $parts[] = $buf; $buf = ''; continue; } $buf .= $ch; } if (trim($buf) !== '') { $parts[] = $buf; } return $parts; } // 条件 public function where($name, $value = '') { if (!$name) { return $this; } if (is_array($name)) { foreach ($name as $f => $v) { $this->param['where'][] = !dr_is_numeric($f) ? [$f, $v] : $v; } } else { $this->param['where'][] = dr_strlen($value) ? [$name, $value] : $name; } return $this; } // 条件 public function like($name, $value = '') { if (!$name) { return $this; } if (method_exists($this->db, 'whereLike')) { $this->param['where'][] = $this->db->whereLike($name, $value); } else { $this->param['where'][] = $name.' LIKE "%'.$value.'%"'; } return $this; } // json(优先驱动 whereJson;默认 MySQL) public function where_json($table, $name, $value) { list($ok, $sql) = $this->_try_db_where('whereJson', $table, $name, $value); if ($ok) { return $sql; } if ($this->is_column_expr($name)) { $name = $this->quote_column($name); } else { $name = $table ? $this->quote_field($table, $name) : $this->quote_id($name); } if (version_compare($this->db->getVersion(), '5.7.0') < 0) { return $name.' LIKE \'%"'.$value.'"%\''; } return "(CASE WHEN JSON_VALID({$name}) THEN JSON_CONTAINS ({$name}->'$[*]', '\"".$value."\"', '$') ELSE null END)"; } // in条件 public function where_in($name, $value) { if (!$name) { return $this; } if (is_array($value) && $value) { $this->param['where_in'][] = [$name, $value]; } return $this; } public function where_date($name, $value) { if (!$name) { return $this; } //$where = 'DATEDIFF(from_unixtime('.$name.'),now())='.$value; $where = ''; if (!$value) { // 今天 $stime = strtotime(date('Y-m-d', SYS_TIME).' 00:00:00'); $etime = strtotime(date('Y-m-d 23:59:59', $stime)); $where = $name." BETWEEN ".$stime." AND ".$etime; } $this->param['where'][] = $where; return $this; } /** * 指定查询数量 * @access public * @param int $offset 起始位置 * @param int $length 查询数量 * @return $this */ public function limit($offset, $length = 0) { $this->param['limit'] = $offset . ($length ? ',' . $length : ''); return $this; } // 排序 public function order_by($value, $value2 = null) { $this->param['order'] = $value2 ? $value.' '.$value2 : $value; return $this; } public function group_by($value) { $this->param['group'] = $value; return $this; } // 运行SQL public function query_sql($sql, $more = 0) { $sql = str_replace('{dbprefix}', $this->prefix, $sql); $query = $this->db->query($sql); if (!$query || !is_object($query)) { $this->_clear(); return []; } $rt = $more ? $query->getResultArray() : $query->getRowArray(); $this->_clear(); return $rt; } // 批量执行(插件 Install/Uninstall.sql 等) // 经 dr_format_create_sql → 驱动 formatCreateSql 做方言转换 public function query_all($sql, $replace = []) { if (!$sql) { $this->_clear(); return ''; } $rt = $this->_query_batch($sql, $replace); $this->_clear(); return $rt['code'] ? '' : $rt['msg']; } /** * 批量执行 SQL(按分号拆分),成功返回 dr_return_data(1, …) * * @param string $sql * @param array $replace [0=>搜索, 1=>替换],默认含 {dbprefix} * @return array */ public function _query_batch($sql, $replace = []) { if (!isset($replace[0]) || !is_array($replace[0])) { $replace[0] = []; } if (!isset($replace[1]) || !is_array($replace[1])) { $replace[1] = []; } $replace[0][] = '{dbprefix}'; $replace[1][] = $this->db->DBPrefix; $todo = []; $count = 0; $sql_data = explode(';SQL_FINECMS_EOL', trim(str_replace([PHP_EOL, chr(13), chr(10)], 'SQL_FINECMS_EOL', str_replace($replace[0], $replace[1], $sql)))); if ($sql_data) { foreach ($sql_data as $query) { if (!$query) { continue; } $ret = ''; $queries = explode('SQL_FINECMS_EOL', trim($query)); foreach ($queries as $query) { $ret .= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query; } $ret = trim($ret); if (!$ret) { continue; } if ($this->db->simpleQuery(dr_format_create_sql($ret))) { $todo[] = $ret; $count++; } else { $err = $this->db->error(); return dr_return_data(0, ($err['message'] ?? '').'
'.$ret); } } } return dr_return_data(1, '', [$count, $todo]); } // 获取当前执行后的sql语句 public function get_sql_query() { if (!$this->db) { return ''; } elseif (!method_exists($this->db, 'getLastQuery')) { return ''; } $my = $this->db->getLastQuery(); if (!$my) { $this->_clear(); return ''; } if ($my && !method_exists($my, 'getQuery')) { $this->_clear(); return (string)$my; } $rt = str_replace(PHP_EOL, ' ', $my->getQuery()); $this->_clear(); return $rt; } // 关闭数据库 public function close() { if (method_exists($this->db, 'close')) { $this->db->close(); } } private function _clear() { $this->key = $this->id; $this->date_field = 'inputtime'; $this->field = []; $this->param = []; if ($this->db_temp) { // 还原默认库 $this->db = $this->db_temp; $this->prefix = $this->db_temp->DBPrefix; $this->db_temp = NULL; } } // 附表分表规则 public function get_table_id($id) { return floor($id / 100000); } // 显示数据库错误 private function _return_error($msg) { return IS_ADMIN || IS_DEV ? dr_return_data(0, $msg) : dr_return_data(0, dr_lang('系统错误')); } }