mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-06 15:02:47 +08:00
改进model类order方法
添加json类型支持 支持json字段查询例如 $map['user$.name'] = 'thinkphp' escapeString方法采用PDO::quote方法
This commit is contained in:
@@ -379,7 +379,7 @@ abstract class Driver
|
|||||||
// 记录错误日志
|
// 记录错误日志
|
||||||
Log::record($this->error, 'ERR');
|
Log::record($this->error, 'ERR');
|
||||||
if ($this->config['debug']) {
|
if ($this->config['debug']) {
|
||||||
// 开启数据库调试模式
|
// 开启数据库调试模式
|
||||||
throw new Exception($this->error);
|
throw new Exception($this->error);
|
||||||
} else {
|
} else {
|
||||||
return $this->error;
|
return $this->error;
|
||||||
@@ -410,7 +410,7 @@ abstract class Driver
|
|||||||
} elseif (is_null($val)) {
|
} elseif (is_null($val)) {
|
||||||
$set[] = $this->parseKey($key) . '=NULL';
|
$set[] = $this->parseKey($key) . '=NULL';
|
||||||
} elseif (is_scalar($val)) {
|
} elseif (is_scalar($val)) {
|
||||||
// 过滤非标量数据
|
// 过滤非标量数据
|
||||||
if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
|
if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
|
||||||
$set[] = $this->parseKey($key) . '=' . $this->escapeString($val);
|
$set[] = $this->parseKey($key) . '=' . $this->escapeString($val);
|
||||||
} else {
|
} else {
|
||||||
@@ -510,7 +510,7 @@ abstract class Driver
|
|||||||
protected function parseTable($tables)
|
protected function parseTable($tables)
|
||||||
{
|
{
|
||||||
if (is_array($tables)) {
|
if (is_array($tables)) {
|
||||||
// 支持别名定义
|
// 支持别名定义
|
||||||
$array = [];
|
$array = [];
|
||||||
foreach ($tables as $table => $alias) {
|
foreach ($tables as $table => $alias) {
|
||||||
if (!is_numeric($table)) {
|
if (!is_numeric($table)) {
|
||||||
@@ -601,7 +601,7 @@ abstract class Driver
|
|||||||
// 比较运算
|
// 比较运算
|
||||||
$whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($val[1]);
|
$whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($val[1]);
|
||||||
} elseif (preg_match('/^(notlike|like)$/', $exp)) {
|
} elseif (preg_match('/^(notlike|like)$/', $exp)) {
|
||||||
// 模糊查找
|
// 模糊查找
|
||||||
if (is_array($val[1])) {
|
if (is_array($val[1])) {
|
||||||
$likeLogic = isset($val[2]) ? strtoupper($val[2]) : 'OR';
|
$likeLogic = isset($val[2]) ? strtoupper($val[2]) : 'OR';
|
||||||
if (in_array($likeLogic, ['AND', 'OR', 'XOR'])) {
|
if (in_array($likeLogic, ['AND', 'OR', 'XOR'])) {
|
||||||
@@ -741,17 +741,18 @@ abstract class Driver
|
|||||||
*/
|
*/
|
||||||
protected function parseOrder($order)
|
protected function parseOrder($order)
|
||||||
{
|
{
|
||||||
if (is_array($order)) {
|
$array = [];
|
||||||
$array = [];
|
foreach ($order as $key => $val) {
|
||||||
foreach ($order as $key => $val) {
|
if (is_numeric($key)) {
|
||||||
if (is_numeric($key)) {
|
if (false === strpos($val, '(')) {
|
||||||
$array[] = $this->parseKey($val);
|
$array[] = $this->parseKey($val);
|
||||||
} else {
|
|
||||||
$array[] = $this->parseKey($key) . ' ' . $val;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';
|
||||||
|
$array[] = $this->parseKey($key) . ' ' . $sort;
|
||||||
}
|
}
|
||||||
$order = implode(',', $array);
|
|
||||||
}
|
}
|
||||||
|
$order = implode(',', $array);
|
||||||
return !empty($order) ? ' ORDER BY ' . $order : '';
|
return !empty($order) ? ' ORDER BY ' . $order : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,7 +982,7 @@ abstract class Driver
|
|||||||
$table = $this->parseTable($options['table']);
|
$table = $this->parseTable($options['table']);
|
||||||
$sql = 'UPDATE ' . $table . $this->parseSet($data);
|
$sql = 'UPDATE ' . $table . $this->parseSet($data);
|
||||||
if (strpos($table, ',')) {
|
if (strpos($table, ',')) {
|
||||||
// 多表更新支持JOIN操作
|
// 多表更新支持JOIN操作
|
||||||
$sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : '');
|
$sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : '');
|
||||||
}
|
}
|
||||||
$sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : '');
|
$sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : '');
|
||||||
@@ -1007,7 +1008,7 @@ abstract class Driver
|
|||||||
$table = $this->parseTable($options['table']);
|
$table = $this->parseTable($options['table']);
|
||||||
$sql = 'DELETE FROM ' . $table;
|
$sql = 'DELETE FROM ' . $table;
|
||||||
if (strpos($table, ',')) {
|
if (strpos($table, ',')) {
|
||||||
// 多表删除支持USING和JOIN操作
|
// 多表删除支持USING和JOIN操作
|
||||||
if (!empty($options['using'])) {
|
if (!empty($options['using'])) {
|
||||||
$sql .= ' USING ' . $this->parseTable($options['using']) . ' ';
|
$sql .= ' USING ' . $this->parseTable($options['using']) . ' ';
|
||||||
}
|
}
|
||||||
@@ -1125,7 +1126,7 @@ abstract class Driver
|
|||||||
*/
|
*/
|
||||||
public function escapeString($str)
|
public function escapeString($str)
|
||||||
{
|
{
|
||||||
return addslashes($str);
|
return $this->_linkID->quote($str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1147,7 +1148,7 @@ abstract class Driver
|
|||||||
protected function debug($start)
|
protected function debug($start)
|
||||||
{
|
{
|
||||||
if ($this->config['debug']) {
|
if ($this->config['debug']) {
|
||||||
// 开启数据库调试模式
|
// 开启数据库调试模式
|
||||||
if ($start) {
|
if ($start) {
|
||||||
Debug::remark('queryStartTime', 'time');
|
Debug::remark('queryStartTime', 'time');
|
||||||
} else {
|
} else {
|
||||||
@@ -1207,7 +1208,7 @@ abstract class Driver
|
|||||||
$r = $m;
|
$r = $m;
|
||||||
} else {
|
} else {
|
||||||
if (is_numeric($this->config['slave_no'])) {
|
if (is_numeric($this->config['slave_no'])) {
|
||||||
// 指定服务器读
|
// 指定服务器读
|
||||||
$r = $this->config['slave_no'];
|
$r = $this->config['slave_no'];
|
||||||
} else {
|
} else {
|
||||||
// 读操作连接从服务器
|
// 读操作连接从服务器
|
||||||
|
|||||||
@@ -89,6 +89,11 @@ class Mysql extends Driver
|
|||||||
protected function parseKey(&$key)
|
protected function parseKey(&$key)
|
||||||
{
|
{
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
|
// JSON字段支持
|
||||||
|
list($field, $name) = explode($key, '$.');
|
||||||
|
$key = 'jsn_extract(' . $field . ', \'$.\'.' . $name . ')';
|
||||||
|
}
|
||||||
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
||||||
$key = '`' . $key . '`';
|
$key = '`' . $key . '`';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,17 +132,6 @@ class Oracle extends Driver
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL指令安全过滤
|
|
||||||
* @access public
|
|
||||||
* @param string $str SQL指令
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function escapeString($str)
|
|
||||||
{
|
|
||||||
return str_ireplace("'", "''", $str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* limit
|
* limit
|
||||||
* @access public
|
* @access public
|
||||||
@@ -176,4 +165,21 @@ class Oracle extends Driver
|
|||||||
|
|
||||||
return ' FOR UPDATE NOWAIT ';
|
return ' FOR UPDATE NOWAIT ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段和表名处理
|
||||||
|
* @access protected
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parseKey(&$key)
|
||||||
|
{
|
||||||
|
$key = trim($key);
|
||||||
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
|
// JSON字段支持
|
||||||
|
list($field, $name) = explode($key, '$.');
|
||||||
|
$key = $field . '."' . $name . '"';
|
||||||
|
}
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,4 +94,20 @@ class Pgsql extends Driver
|
|||||||
return $limitStr;
|
return $limitStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段和表名处理
|
||||||
|
* @access protected
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parseKey(&$key)
|
||||||
|
{
|
||||||
|
$key = trim($key);
|
||||||
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
|
// JSON字段支持
|
||||||
|
list($field, $name) = explode($key, '$.');
|
||||||
|
$key = $field . '->>\'' . $name . '\'';
|
||||||
|
}
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,17 +73,6 @@ class Sqlite extends Driver
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL指令安全过滤
|
|
||||||
* @access public
|
|
||||||
* @param string $str SQL指令
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function escapeString($str)
|
|
||||||
{
|
|
||||||
return str_ireplace("'", "''", $str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* limit
|
* limit
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -100,6 +100,16 @@ class Sqlsrv extends Driver
|
|||||||
*/
|
*/
|
||||||
protected function parseOrder($order)
|
protected function parseOrder($order)
|
||||||
{
|
{
|
||||||
|
$array = [];
|
||||||
|
foreach ($order as $key => $val) {
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
$array[] = $this->parseKey($val);
|
||||||
|
} else {
|
||||||
|
$sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';
|
||||||
|
$array[] = $this->parseKey($key) . ' ' . $sort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$order = implode(',', $array);
|
||||||
return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()';
|
return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class Model
|
|||||||
const MODEL_UPDATE = 2; // 更新
|
const MODEL_UPDATE = 2; // 更新
|
||||||
const MODEL_BOTH = 3; // 全部
|
const MODEL_BOTH = 3; // 全部
|
||||||
// 当前数据库操作对象
|
// 当前数据库操作对象
|
||||||
protected $db = null;
|
protected $db = null;
|
||||||
// 数据库对象池
|
// 数据库对象池
|
||||||
private $_db = [];
|
private $_db = [];
|
||||||
// 主键名称
|
// 主键名称
|
||||||
@@ -546,7 +546,7 @@ class Model
|
|||||||
$options['model'] = $this->name;
|
$options['model'] = $this->name;
|
||||||
|
|
||||||
if (isset($options['table'])) {
|
if (isset($options['table'])) {
|
||||||
// 动态指定表名
|
// 动态指定表名
|
||||||
$fields = $this->db->getFields($options['table']);
|
$fields = $this->db->getFields($options['table']);
|
||||||
$fields = $fields ? array_keys($fields) : false;
|
$fields = $fields ? array_keys($fields) : false;
|
||||||
} else {
|
} else {
|
||||||
@@ -596,6 +596,8 @@ class Model
|
|||||||
$data[$key] = floatval($data[$key]);
|
$data[$key] = floatval($data[$key]);
|
||||||
} elseif (false !== strpos($fieldType, 'bool')) {
|
} elseif (false !== strpos($fieldType, 'bool')) {
|
||||||
$data[$key] = (bool) $data[$key];
|
$data[$key] = (bool) $data[$key];
|
||||||
|
} elseif (false !== strpos($fieldType, 'json') && is_array($data[$key])) {
|
||||||
|
$data[$key] = json_encode($data[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -653,7 +655,7 @@ class Model
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (empty($resultSet)) {
|
if (empty($resultSet)) {
|
||||||
// 查询结果为空
|
// 查询结果为空
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (is_string($resultSet)) {
|
if (is_string($resultSet)) {
|
||||||
@@ -917,16 +919,11 @@ class Model
|
|||||||
* SQL查询
|
* SQL查询
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $sql SQL指令
|
* @param string $sql SQL指令
|
||||||
* @param mixed $parse 是否需要解析SQL
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function query($sql, $parse = false)
|
public function query($sql)
|
||||||
{
|
{
|
||||||
if (!is_bool($parse) && !is_array($parse)) {
|
$sql = $this->parseSql($sql);
|
||||||
$parse = func_get_args();
|
|
||||||
array_shift($parse);
|
|
||||||
}
|
|
||||||
$sql = $this->parseSql($sql, $parse);
|
|
||||||
return $this->db->query($sql);
|
return $this->db->query($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,16 +931,11 @@ class Model
|
|||||||
* 执行SQL语句
|
* 执行SQL语句
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $sql SQL指令
|
* @param string $sql SQL指令
|
||||||
* @param mixed $parse 是否需要解析SQL
|
|
||||||
* @return false | integer
|
* @return false | integer
|
||||||
*/
|
*/
|
||||||
public function execute($sql, $parse = false)
|
public function execute($sql)
|
||||||
{
|
{
|
||||||
if (!is_bool($parse) && !is_array($parse)) {
|
$sql = $this->parseSql($sql);
|
||||||
$parse = func_get_args();
|
|
||||||
array_shift($parse);
|
|
||||||
}
|
|
||||||
$sql = $this->parseSql($sql, $parse);
|
|
||||||
return $this->db->execute($sql);
|
return $this->db->execute($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,24 +943,14 @@ class Model
|
|||||||
* 解析SQL语句
|
* 解析SQL语句
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $sql SQL指令
|
* @param string $sql SQL指令
|
||||||
* @param boolean $parse 是否需要解析SQL
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parseSql($sql, $parse)
|
protected function parseSql($sql)
|
||||||
{
|
{
|
||||||
// 分析表达式
|
// 分析表达式
|
||||||
if (true === $parse) {
|
$sql = strtr($sql, ['__TABLE__' => $this->getTableName(), '__PREFIX__' => $this->tablePrefix]);
|
||||||
$options = $this->_parseOptions();
|
$prefix = $this->tablePrefix;
|
||||||
$sql = $this->db->parseSql($sql, $options);
|
$sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $sql);
|
||||||
} elseif (is_array($parse)) {
|
|
||||||
// SQL预处理
|
|
||||||
$parse = array_map([$this->db, 'escapeString'], $parse);
|
|
||||||
$sql = vsprintf($sql, $parse);
|
|
||||||
} else {
|
|
||||||
$sql = strtr($sql, ['__TABLE__' => $this->getTableName(), '__PREFIX__' => $this->tablePrefix]);
|
|
||||||
$prefix = $this->tablePrefix;
|
|
||||||
$sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $sql);
|
|
||||||
}
|
|
||||||
$this->db->setModel($this->name);
|
$this->db->setModel($this->name);
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
@@ -1088,11 +1070,11 @@ class Model
|
|||||||
public function field($field, $except = false)
|
public function field($field, $except = false)
|
||||||
{
|
{
|
||||||
if (true === $field) {
|
if (true === $field) {
|
||||||
// 获取全部字段
|
// 获取全部字段
|
||||||
$fields = $this->getDbFields();
|
$fields = $this->getDbFields();
|
||||||
$field = $fields ?: '*';
|
$field = $fields ?: '*';
|
||||||
} elseif ($except) {
|
} elseif ($except) {
|
||||||
// 字段排除
|
// 字段排除
|
||||||
if (is_string($field)) {
|
if (is_string($field)) {
|
||||||
$field = explode(',', $field);
|
$field = explode(',', $field);
|
||||||
}
|
}
|
||||||
@@ -1247,14 +1229,23 @@ class Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定排序
|
* 指定排序 order('id','desc') 或者 order(['id'=>'desc','create_time'=>'desc'])
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param string|array $field 排序字段
|
||||||
* @param string $order 排序
|
* @param string $order 排序
|
||||||
* @return Model
|
* @return Model
|
||||||
*/
|
*/
|
||||||
public function order($order)
|
public function order($field, $order = '')
|
||||||
{
|
{
|
||||||
$this->options['order'] = $order;
|
if (is_array($field)) {
|
||||||
|
$this->options['order'] = $field;
|
||||||
|
} else {
|
||||||
|
if (!empty($order)) {
|
||||||
|
$this->options['order'][$field] = $order;
|
||||||
|
} else {
|
||||||
|
$this->options['order'][] = $field;
|
||||||
|
}
|
||||||
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user