mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 12:42:48 +08:00
增加Expression类及相关方法
This commit is contained in:
@@ -1093,7 +1093,7 @@ class Request
|
||||
public function filterExp(&$value)
|
||||
{
|
||||
// 过滤查询特殊字符
|
||||
if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {
|
||||
if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOT EXISTS|NOTEXISTS|EXISTS|NOT NULL|NOTNULL|NULL|BETWEEN TIME|NOT BETWEEN TIME|NOTBETWEEN TIME|NOTIN|NOT IN|IN)$/i', $value)) {
|
||||
$value .= ' ';
|
||||
}
|
||||
// TODO 其他安全过滤
|
||||
|
||||
@@ -99,8 +99,11 @@ abstract class Builder
|
||||
|
||||
$result = [];
|
||||
foreach ($data as $key => $val) {
|
||||
$item = $this->parseKey($key, $options);
|
||||
if (is_object($val) && method_exists($val, '__toString')) {
|
||||
$item = $this->parseKey($key, $options, true);
|
||||
if ($val instanceof Expression) {
|
||||
$result[$item] = $val->getValue();
|
||||
continue;
|
||||
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||
// 对象数据写入
|
||||
$val = $val->__toString();
|
||||
}
|
||||
@@ -143,7 +146,7 @@ abstract class Builder
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
protected function parseKey($key, $options = [])
|
||||
protected function parseKey($key, $options = [], $strict = false)
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
@@ -184,10 +187,12 @@ abstract class Builder
|
||||
// 支持 'field1'=>'field2' 这样的字段别名定义
|
||||
$array = [];
|
||||
foreach ($fields as $key => $field) {
|
||||
if (!is_numeric($key)) {
|
||||
$array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options);
|
||||
if ($field instanceof Expression) {
|
||||
$array[] = $field->getValue();
|
||||
} elseif (!is_numeric($key)) {
|
||||
$array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options, true);
|
||||
} else {
|
||||
$array[] = $this->parseKey($field, $options);
|
||||
$array[] = $this->parseKey($field, $options, true);
|
||||
}
|
||||
}
|
||||
$fieldsStr = implode(',', $array);
|
||||
@@ -264,6 +269,10 @@ abstract class Builder
|
||||
foreach ($where as $key => $val) {
|
||||
$str = [];
|
||||
foreach ($val as $field => $value) {
|
||||
if ($value instanceof Expression) {
|
||||
$str[] = ' ' . $logic . ' ( ' . $value->getValue() . ' )';
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof \Closure) {
|
||||
// 使用闭包查询
|
||||
$query = new Query($this->connection);
|
||||
@@ -305,7 +314,7 @@ abstract class Builder
|
||||
protected function parseWhereItem($field, $val, $rule = '', $options = [], $binds = [], $bindName = null)
|
||||
{
|
||||
// 字段分析
|
||||
$key = $field ? $this->parseKey($field, $options) : '';
|
||||
$key = $field ? $this->parseKey($field, $options, true) : '';
|
||||
|
||||
// 查询规则和条件
|
||||
if (!is_array($val)) {
|
||||
@@ -344,7 +353,9 @@ abstract class Builder
|
||||
$bindName = md5($bindName);
|
||||
}
|
||||
|
||||
if (is_object($value) && method_exists($value, '__toString')) {
|
||||
if ($value instanceof Expression) {
|
||||
|
||||
} elseif (is_object($value) && method_exists($value, '__toString')) {
|
||||
// 对象数据写入
|
||||
$value = $value->__toString();
|
||||
}
|
||||
@@ -556,7 +567,9 @@ abstract class Builder
|
||||
if (is_array($order)) {
|
||||
$array = [];
|
||||
foreach ($order as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
if ($val instanceof Expression) {
|
||||
$array[] = $val->getValue();
|
||||
} elseif (is_numeric($key)) {
|
||||
if ('[rand]' == $val) {
|
||||
if (method_exists($this, 'parseRand')) {
|
||||
$array[] = $this->parseRand();
|
||||
|
||||
48
library/think/db/Expression.php
Normal file
48
library/think/db/Expression.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db;
|
||||
|
||||
class Expression
|
||||
{
|
||||
/**
|
||||
* 查询表达式
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* 创建一个查询表达式
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表达式
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
@@ -800,6 +800,24 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定查询字段
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param array $bind 参数绑定
|
||||
* @return $this
|
||||
*/
|
||||
public function fieldRaw($field, array $bind = [])
|
||||
{
|
||||
$this->options['field'][] = $this->raw($field);
|
||||
|
||||
if ($bind) {
|
||||
$this->bind($bind);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据
|
||||
* @access public
|
||||
@@ -862,6 +880,17 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用表达式设置数据
|
||||
* @access public
|
||||
* @param mixed $value 表达式
|
||||
* @return Expression
|
||||
*/
|
||||
public function raw($value)
|
||||
{
|
||||
return new Expression($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定JOIN查询字段
|
||||
* @access public
|
||||
@@ -975,6 +1004,37 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定表达式查询条件
|
||||
* @access public
|
||||
* @param string $where 查询条件
|
||||
* @param array $bind 参数绑定
|
||||
* @param string $logic 查询逻辑 and or xor
|
||||
* @return $this
|
||||
*/
|
||||
public function whereRaw($where, $bind = [], $logic = 'AND')
|
||||
{
|
||||
$this->options['where'][$logic][] = $this->raw($where);
|
||||
|
||||
if ($bind) {
|
||||
$this->bind($bind);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定表达式查询条件 OR
|
||||
* @access public
|
||||
* @param string $where 查询条件
|
||||
* @param array $bind 参数绑定
|
||||
* @return $this
|
||||
*/
|
||||
public function whereOrRaw($where, $bind = [])
|
||||
{
|
||||
return $this->whereRaw($where, $bind, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定Null查询条件
|
||||
* @access public
|
||||
@@ -1163,7 +1223,9 @@ class Query
|
||||
$field = $this->options['via'] . '.' . $field;
|
||||
}
|
||||
|
||||
if ($strict) {
|
||||
if ($field instanceof Expression) {
|
||||
return $this->whereRaw($field, is_array($op) ? $op : []);
|
||||
} elseif ($strict) {
|
||||
// 使用严格模式查询
|
||||
$where[$field] = [$op, $condition];
|
||||
|
||||
@@ -1451,6 +1513,24 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定Field排序
|
||||
* @access public
|
||||
* @param string $field 排序字段
|
||||
* @param array $bind 参数绑定
|
||||
* @return $this
|
||||
*/
|
||||
public function orderRaw($field, array $bind = [])
|
||||
{
|
||||
$this->options['order'][] = $this->raw($field);
|
||||
|
||||
if ($bind) {
|
||||
$this->bind($bind);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询缓存
|
||||
* @access public
|
||||
|
||||
@@ -86,13 +86,16 @@ class Mysql extends Builder
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
protected function parseKey($key, $options = [])
|
||||
protected function parseKey($key, $options = [], $strict = false)
|
||||
{
|
||||
if (is_int($key)) {
|
||||
return $key;
|
||||
}
|
||||
$key = trim($key);
|
||||
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||
// JSON字段支持
|
||||
list($field, $name) = explode('$.', $key);
|
||||
$key = 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
||||
return 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
||||
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
|
||||
list($table, $key) = explode('.', $key, 2);
|
||||
if ('__TABLE__' == $table) {
|
||||
@@ -102,7 +105,7 @@ class Mysql extends Builder
|
||||
$table = $options['alias'][$table];
|
||||
}
|
||||
}
|
||||
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
||||
if ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
||||
$key = '`' . $key . '`';
|
||||
}
|
||||
if (isset($table)) {
|
||||
|
||||
@@ -48,7 +48,7 @@ class Pgsql extends Builder
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
protected function parseKey($key, $options = [])
|
||||
protected function parseKey($key, $options = [], $strict = false)
|
||||
{
|
||||
$key = trim($key);
|
||||
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||
|
||||
@@ -56,7 +56,7 @@ class Sqlite extends Builder
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
protected function parseKey($key, $options = [])
|
||||
protected function parseKey($key, $options = [], $strict = false)
|
||||
{
|
||||
$key = trim($key);
|
||||
if (strpos($key, '.')) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace think\db\builder;
|
||||
|
||||
use think\db\Builder;
|
||||
use think\db\Expression;
|
||||
|
||||
/**
|
||||
* Sqlsrv数据库驱动
|
||||
@@ -37,7 +38,9 @@ class Sqlsrv extends Builder
|
||||
if (is_array($order)) {
|
||||
$array = [];
|
||||
foreach ($order as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
if ($val instanceof Expression) {
|
||||
$array[] = $val->getValue();
|
||||
} elseif (is_numeric($key)) {
|
||||
if (false === strpos($val, '(')) {
|
||||
$array[] = $this->parseKey($val, $options);
|
||||
} elseif ('[rand]' == $val) {
|
||||
@@ -72,8 +75,11 @@ class Sqlsrv extends Builder
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
protected function parseKey($key, $options = [])
|
||||
protected function parseKey($key, $options = [], $strict = false)
|
||||
{
|
||||
if (is_int($key)) {
|
||||
return $key;
|
||||
}
|
||||
$key = trim($key);
|
||||
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
|
||||
list($table, $key) = explode('.', $key, 2);
|
||||
@@ -84,7 +90,7 @@ class Sqlsrv extends Builder
|
||||
$table = $options['alias'][$table];
|
||||
}
|
||||
}
|
||||
if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
||||
if ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
||||
$key = '[' . $key . ']';
|
||||
}
|
||||
if (isset($table)) {
|
||||
|
||||
Reference in New Issue
Block a user