内核更新
This commit is contained in:
@@ -203,6 +203,8 @@ return [
|
|||||||
'type' => '',
|
'type' => '',
|
||||||
// 是否自动开启 SESSION
|
// 是否自动开启 SESSION
|
||||||
'auto_start' => true,
|
'auto_start' => true,
|
||||||
|
'httponly' => true,
|
||||||
|
'secure' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@@ -438,7 +438,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
// 类型转换
|
// 类型转换
|
||||||
$value = $this->readTransform($value, $this->type[$name]);
|
$value = $this->readTransform($value, $this->type[$name]);
|
||||||
} elseif (in_array($name, [$this->createTime, $this->updateTime])) {
|
} elseif (in_array($name, [$this->createTime, $this->updateTime])) {
|
||||||
|
if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
||||||
|
$value = $this->formatDateTime(strtotime($value), $this->dateFormat);
|
||||||
|
} else {
|
||||||
$value = $this->formatDateTime($value, $this->dateFormat);
|
$value = $this->formatDateTime($value, $this->dateFormat);
|
||||||
|
}
|
||||||
} elseif ($notFound) {
|
} elseif ($notFound) {
|
||||||
$method = Loader::parseName($name, 1, false);
|
$method = Loader::parseName($name, 1, false);
|
||||||
if (method_exists($this, $method) && $this->$method() instanceof Relation) {
|
if (method_exists($this, $method) && $this->$method() instanceof Relation) {
|
||||||
@@ -724,7 +728,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->autoCompleteData($this->auto);
|
$this->autoCompleteData($this->auto);
|
||||||
|
|
||||||
// 自动写入更新时间
|
// 自动写入更新时间
|
||||||
if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) {
|
if ($this->autoWriteTimestamp && $this->updateTime && (empty($this->change) || !in_array($this->updateTime, $this->change))) {
|
||||||
$this->setAttr($this->updateTime, null);
|
$this->setAttr($this->updateTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,7 +785,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->autoCompleteData($this->insert);
|
$this->autoCompleteData($this->insert);
|
||||||
|
|
||||||
// 自动写入创建时间
|
// 自动写入创建时间
|
||||||
if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) {
|
if ($this->autoWriteTimestamp && $this->createTime && (empty($this->change) || !in_array($this->createTime, $this->change))) {
|
||||||
$this->setAttr($this->createTime, null);
|
$this->setAttr($this->createTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1097,7 +1097,7 @@ class Route
|
|||||||
* 绑定到模块/控制器
|
* 绑定到模块/控制器
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $url URL地址
|
* @param string $url URL地址
|
||||||
* @param string $class 控制器类名(带命名空间)
|
* @param string $controller 控制器类名(带命名空间)
|
||||||
* @param string $depr URL分隔符
|
* @param string $depr URL分隔符
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -77,7 +77,12 @@ class Session
|
|||||||
ini_set('session.gc_maxlifetime', $config['expire']);
|
ini_set('session.gc_maxlifetime', $config['expire']);
|
||||||
ini_set('session.cookie_lifetime', $config['expire']);
|
ini_set('session.cookie_lifetime', $config['expire']);
|
||||||
}
|
}
|
||||||
|
if (isset($config['secure'])) {
|
||||||
|
ini_set('session.cookie_secure', $config['secure']);
|
||||||
|
}
|
||||||
|
if (isset($config['httponly'])) {
|
||||||
|
ini_set('session.cookie_httponly', $config['httponly']);
|
||||||
|
}
|
||||||
if (isset($config['use_cookies'])) {
|
if (isset($config['use_cookies'])) {
|
||||||
ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0);
|
ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1222,9 +1222,9 @@ class Validate
|
|||||||
$msg = Lang::get(substr($msg, 2, -1));
|
$msg = Lang::get(substr($msg, 2, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($msg) && is_string($rule) && false !== strpos($msg, ':')) {
|
if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) {
|
||||||
// 变量替换
|
// 变量替换
|
||||||
if (strpos($rule, ',')) {
|
if (is_string($rule) && strpos($rule, ',')) {
|
||||||
$array = array_pad(explode(',', $rule), 3, '');
|
$array = array_pad(explode(',', $rule), 3, '');
|
||||||
} else {
|
} else {
|
||||||
$array = array_pad([], 3, '');
|
$array = array_pad([], 3, '');
|
||||||
|
|||||||
2
core/library/think/cache/driver/File.php
vendored
2
core/library/think/cache/driver/File.php
vendored
@@ -21,7 +21,7 @@ class File extends Driver
|
|||||||
{
|
{
|
||||||
protected $options = [
|
protected $options = [
|
||||||
'expire' => 0,
|
'expire' => 0,
|
||||||
'cache_subdir' => false,
|
'cache_subdir' => true,
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
'path' => CACHE_PATH,
|
'path' => CACHE_PATH,
|
||||||
'data_compress' => false,
|
'data_compress' => false,
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ abstract class Builder
|
|||||||
throw new Exception('where express error:' . $exp);
|
throw new Exception('where express error:' . $exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$bindName = $bindName ?: 'where_' . str_replace('.', '_', $field);
|
$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);
|
||||||
if (preg_match('/\W/', $bindName)) {
|
if (preg_match('/\W/', $bindName)) {
|
||||||
// 处理带非单词字符的字段名
|
// 处理带非单词字符的字段名
|
||||||
$bindName = md5($bindName);
|
$bindName = md5($bindName);
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ abstract class Connection
|
|||||||
'slave_no' => '',
|
'slave_no' => '',
|
||||||
// 是否严格检查字段是否存在
|
// 是否严格检查字段是否存在
|
||||||
'fields_strict' => true,
|
'fields_strict' => true,
|
||||||
|
// 数据返回类型
|
||||||
|
'result_type' => PDO::FETCH_ASSOC,
|
||||||
// 数据集返回类型
|
// 数据集返回类型
|
||||||
'resultset_type' => 'array',
|
'resultset_type' => 'array',
|
||||||
// 自动写入时间戳字段
|
// 自动写入时间戳字段
|
||||||
@@ -118,6 +120,9 @@ abstract class Connection
|
|||||||
PDO::ATTR_EMULATE_PREPARES => false,
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 绑定参数
|
||||||
|
protected $bind = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 架构函数 读取数据库配置信息
|
* 架构函数 读取数据库配置信息
|
||||||
* @access public
|
* @access public
|
||||||
@@ -269,6 +274,10 @@ abstract class Connection
|
|||||||
if (isset($config['resultset_type'])) {
|
if (isset($config['resultset_type'])) {
|
||||||
$this->resultSetType = $config['resultset_type'];
|
$this->resultSetType = $config['resultset_type'];
|
||||||
}
|
}
|
||||||
|
// 数据返回类型
|
||||||
|
if (isset($config['result_type'])) {
|
||||||
|
$this->fetchType = $config['result_type'];
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (empty($config['dsn'])) {
|
if (empty($config['dsn'])) {
|
||||||
$config['dsn'] = $this->parseDsn($config);
|
$config['dsn'] = $this->parseDsn($config);
|
||||||
@@ -321,20 +330,28 @@ abstract class Connection
|
|||||||
* @access public
|
* @access public
|
||||||
* @param string $sql sql指令
|
* @param string $sql sql指令
|
||||||
* @param array $bind 参数绑定
|
* @param array $bind 参数绑定
|
||||||
|
* @param bool $master 是否在主服务器读操作
|
||||||
|
* @param bool $class 是否返回PDO对象
|
||||||
|
* @param string $sql sql指令
|
||||||
|
* @param array $bind 参数绑定
|
||||||
* @param boolean $master 是否在主服务器读操作
|
* @param boolean $master 是否在主服务器读操作
|
||||||
* @param bool|string $class 指定返回的数据集对象
|
* @param bool $pdo 是否返回PDO对象
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws BindParamException
|
* @throws BindParamException
|
||||||
* @throws PDOException
|
* @throws PDOException
|
||||||
*/
|
*/
|
||||||
public function query($sql, $bind = [], $master = false, $class = false)
|
public function query($sql, $bind = [], $master = false, $pdo = false)
|
||||||
{
|
{
|
||||||
$this->initConnect($master);
|
$this->initConnect($master);
|
||||||
if (!$this->linkID) {
|
if (!$this->linkID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 根据参数绑定组装最终的SQL语句
|
|
||||||
$this->queryStr = $this->getRealSql($sql, $bind);
|
// 记录SQL语句
|
||||||
|
$this->queryStr = $sql;
|
||||||
|
if ($bind) {
|
||||||
|
$this->bind = $bind;
|
||||||
|
}
|
||||||
|
|
||||||
//释放前次的查询结果
|
//释放前次的查询结果
|
||||||
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
||||||
@@ -349,16 +366,22 @@ abstract class Connection
|
|||||||
if (empty($this->PDOStatement)) {
|
if (empty($this->PDOStatement)) {
|
||||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||||
}
|
}
|
||||||
|
// 是否为存储过程调用
|
||||||
|
$procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
|
||||||
// 参数绑定
|
// 参数绑定
|
||||||
|
if ($procedure) {
|
||||||
|
$this->bindParam($bind);
|
||||||
|
} else {
|
||||||
$this->bindValue($bind);
|
$this->bindValue($bind);
|
||||||
|
}
|
||||||
// 执行查询
|
// 执行查询
|
||||||
$this->PDOStatement->execute();
|
$this->PDOStatement->execute();
|
||||||
// 调试结束
|
// 调试结束
|
||||||
$this->debug(false);
|
$this->debug(false);
|
||||||
$procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
|
// 返回结果集
|
||||||
return $this->getResult($class, $procedure);
|
return $this->getResult($pdo, $procedure);
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
throw new PDOException($e, $this->config, $this->queryStr);
|
throw new PDOException($e, $this->config, $this->getLastsql());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +400,12 @@ abstract class Connection
|
|||||||
if (!$this->linkID) {
|
if (!$this->linkID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 根据参数绑定组装最终的SQL语句
|
|
||||||
$this->queryStr = $this->getRealSql($sql, $bind);
|
// 记录SQL语句
|
||||||
|
$this->queryStr = $sql;
|
||||||
|
if ($bind) {
|
||||||
|
$this->bind = $bind;
|
||||||
|
}
|
||||||
|
|
||||||
//释放前次的查询结果
|
//释放前次的查询结果
|
||||||
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
||||||
@@ -393,8 +420,14 @@ abstract class Connection
|
|||||||
if (empty($this->PDOStatement)) {
|
if (empty($this->PDOStatement)) {
|
||||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||||
}
|
}
|
||||||
// 参数绑定操作
|
// 是否为存储过程调用
|
||||||
|
$procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
|
||||||
|
// 参数绑定
|
||||||
|
if ($procedure) {
|
||||||
|
$this->bindParam($bind);
|
||||||
|
} else {
|
||||||
$this->bindValue($bind);
|
$this->bindValue($bind);
|
||||||
|
}
|
||||||
// 执行语句
|
// 执行语句
|
||||||
$this->PDOStatement->execute();
|
$this->PDOStatement->execute();
|
||||||
// 调试结束
|
// 调试结束
|
||||||
@@ -403,7 +436,7 @@ abstract class Connection
|
|||||||
$this->numRows = $this->PDOStatement->rowCount();
|
$this->numRows = $this->PDOStatement->rowCount();
|
||||||
return $this->numRows;
|
return $this->numRows;
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
throw new PDOException($e, $this->config, $this->queryStr);
|
throw new PDOException($e, $this->config, $this->getLastsql());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +449,6 @@ abstract class Connection
|
|||||||
*/
|
*/
|
||||||
public function getRealSql($sql, array $bind = [])
|
public function getRealSql($sql, array $bind = [])
|
||||||
{
|
{
|
||||||
if ($bind) {
|
|
||||||
foreach ($bind as $key => $val) {
|
foreach ($bind as $key => $val) {
|
||||||
$value = is_array($val) ? $val[0] : $val;
|
$value = is_array($val) ? $val[0] : $val;
|
||||||
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
||||||
@@ -433,7 +465,6 @@ abstract class Connection
|
|||||||
[$value . ')', $value . ',', $value . ' '],
|
[$value . ')', $value . ',', $value . ' '],
|
||||||
$sql . ' ');
|
$sql . ' ');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return rtrim($sql);
|
return rtrim($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +475,7 @@ abstract class Connection
|
|||||||
* @access public
|
* @access public
|
||||||
* @param array $bind 要绑定的参数列表
|
* @param array $bind 要绑定的参数列表
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \think\Exception
|
* @throws BindParamException
|
||||||
*/
|
*/
|
||||||
protected function bindValue(array $bind = [])
|
protected function bindValue(array $bind = [])
|
||||||
{
|
{
|
||||||
@@ -463,7 +494,34 @@ abstract class Connection
|
|||||||
throw new BindParamException(
|
throw new BindParamException(
|
||||||
"Error occurred when binding parameters '{$param}'",
|
"Error occurred when binding parameters '{$param}'",
|
||||||
$this->config,
|
$this->config,
|
||||||
$this->queryStr,
|
$this->getLastsql(),
|
||||||
|
$bind
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储过程的输入输出参数绑定
|
||||||
|
* @access public
|
||||||
|
* @param array $bind 要绑定的参数列表
|
||||||
|
* @return void
|
||||||
|
* @throws BindParamException
|
||||||
|
*/
|
||||||
|
protected function bindParam($bind)
|
||||||
|
{
|
||||||
|
foreach ($bind as $key => $val) {
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
$key = $key + 1;
|
||||||
|
}
|
||||||
|
array_unshift($val, $key);
|
||||||
|
$result = call_user_func_array([$this->PDOStatement, 'bindParam'], $val);
|
||||||
|
if (!$result) {
|
||||||
|
$param = array_shift($val);
|
||||||
|
throw new BindParamException(
|
||||||
|
"Error occurred when binding parameters '{$param}'",
|
||||||
|
$this->config,
|
||||||
|
$this->getLastsql(),
|
||||||
$bind
|
$bind
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -473,19 +531,19 @@ abstract class Connection
|
|||||||
/**
|
/**
|
||||||
* 获得数据集
|
* 获得数据集
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param bool|string $class true 返回PDOStatement 字符串用于指定返回的类名
|
* @param bool $pdo 是否返回PDOStatement
|
||||||
* @param bool $procedure 是否存储过程
|
* @param bool $procedure 是否存储过程
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function getResult($class = '', $procedure = false)
|
protected function getResult($pdo = false, $procedure = false)
|
||||||
{
|
{
|
||||||
if (true === $class) {
|
if ($pdo) {
|
||||||
// 返回PDOStatement对象处理
|
// 返回PDOStatement对象处理
|
||||||
return $this->PDOStatement;
|
return $this->PDOStatement;
|
||||||
}
|
}
|
||||||
if ($procedure) {
|
if ($procedure) {
|
||||||
// 存储过程返回结果
|
// 存储过程返回结果
|
||||||
return $this->procedure($class);
|
return $this->procedure();
|
||||||
}
|
}
|
||||||
$result = $this->PDOStatement->fetchAll($this->fetchType);
|
$result = $this->PDOStatement->fetchAll($this->fetchType);
|
||||||
$this->numRows = count($result);
|
$this->numRows = count($result);
|
||||||
@@ -500,14 +558,13 @@ abstract class Connection
|
|||||||
/**
|
/**
|
||||||
* 获得存储过程数据集
|
* 获得存储过程数据集
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param bool|string $class true 返回PDOStatement 字符串用于指定返回的类名
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function procedure($class)
|
protected function procedure()
|
||||||
{
|
{
|
||||||
$item = [];
|
$item = [];
|
||||||
do {
|
do {
|
||||||
$result = $this->getResult($class);
|
$result = $this->getResult();
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$item[] = $result;
|
$item[] = $result;
|
||||||
}
|
}
|
||||||
@@ -698,7 +755,7 @@ abstract class Connection
|
|||||||
*/
|
*/
|
||||||
public function getLastSql()
|
public function getLastSql()
|
||||||
{
|
{
|
||||||
return $this->queryStr;
|
return $this->getRealSql($this->queryStr, $this->bind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -736,7 +793,7 @@ abstract class Connection
|
|||||||
$error = '';
|
$error = '';
|
||||||
}
|
}
|
||||||
if ('' != $this->queryStr) {
|
if ('' != $this->queryStr) {
|
||||||
$error .= "\n [ SQL语句 ] : " . $this->queryStr;
|
$error .= "\n [ SQL语句 ] : " . $this->getLastsql();
|
||||||
}
|
}
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
@@ -771,7 +828,7 @@ abstract class Connection
|
|||||||
// 记录操作结束时间
|
// 记录操作结束时间
|
||||||
Debug::remark('queryEndTime', 'time');
|
Debug::remark('queryEndTime', 'time');
|
||||||
$runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime');
|
$runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime');
|
||||||
$sql = $sql ?: $this->queryStr;
|
$sql = $sql ?: $this->getLastsql();
|
||||||
$log = $sql . ' [ RunTime:' . $runtime . 's ]';
|
$log = $sql . ' [ RunTime:' . $runtime . 's ]';
|
||||||
$result = [];
|
$result = [];
|
||||||
// SQL性能分析
|
// SQL性能分析
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ class Query
|
|||||||
if (isset($this->options['field'])) {
|
if (isset($this->options['field'])) {
|
||||||
unset($this->options['field']);
|
unset($this->options['field']);
|
||||||
}
|
}
|
||||||
$pdo = $this->field($field)->fetchPdo(true)->find();
|
$pdo = $this->field($field)->limit(1)->getPdo();
|
||||||
if (is_string($pdo)) {
|
if (is_string($pdo)) {
|
||||||
// 返回SQL语句
|
// 返回SQL语句
|
||||||
return $pdo;
|
return $pdo;
|
||||||
@@ -459,7 +459,7 @@ class Query
|
|||||||
if ($key && '*' != $field) {
|
if ($key && '*' != $field) {
|
||||||
$field = $key . ',' . $field;
|
$field = $key . ',' . $field;
|
||||||
}
|
}
|
||||||
$pdo = $this->field($field)->fetchPdo(true)->select();
|
$pdo = $this->field($field)->getPdo();
|
||||||
if (is_string($pdo)) {
|
if (is_string($pdo)) {
|
||||||
// 返回SQL语句
|
// 返回SQL语句
|
||||||
return $pdo;
|
return $pdo;
|
||||||
@@ -522,7 +522,7 @@ class Query
|
|||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
* @return float|int
|
* @return float|int
|
||||||
*/
|
*/
|
||||||
public function sum($field = '*')
|
public function sum($field)
|
||||||
{
|
{
|
||||||
return $this->value('SUM(' . $field . ') AS tp_sum', 0, true);
|
return $this->value('SUM(' . $field . ') AS tp_sum', 0, true);
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ class Query
|
|||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function min($field = '*')
|
public function min($field)
|
||||||
{
|
{
|
||||||
return $this->value('MIN(' . $field . ') AS tp_min', 0, true);
|
return $this->value('MIN(' . $field . ') AS tp_min', 0, true);
|
||||||
}
|
}
|
||||||
@@ -544,7 +544,7 @@ class Query
|
|||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function max($field = '*')
|
public function max($field)
|
||||||
{
|
{
|
||||||
return $this->value('MAX(' . $field . ') AS tp_max', 0, true);
|
return $this->value('MAX(' . $field . ') AS tp_max', 0, true);
|
||||||
}
|
}
|
||||||
@@ -555,7 +555,7 @@ class Query
|
|||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
* @return float|int
|
* @return float|int
|
||||||
*/
|
*/
|
||||||
public function avg($field = '*')
|
public function avg($field)
|
||||||
{
|
{
|
||||||
return $this->value('AVG(' . $field . ') AS tp_avg', 0, true);
|
return $this->value('AVG(' . $field . ') AS tp_avg', 0, true);
|
||||||
}
|
}
|
||||||
@@ -972,6 +972,156 @@ class Query
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Null查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNull($field, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'null', null);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定NotNull查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNotNull($field, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'notnull', null);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Exists查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereExists($condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->options['where'][strtoupper($logic)][] = ['exists', $condition];
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定NotExists查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNotExists($condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->options['where'][strtoupper($logic)][] = ['not exists', $condition];
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定In查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereIn($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'in', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定NotIn查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNotIn($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'not in', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Like查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereLike($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'like', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定NotLike查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNotLike($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'not like', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Between查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereBetween($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'between', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定NotBetween查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereNotBetween($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'not between', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Exp查询条件
|
||||||
|
* @access public
|
||||||
|
* @param mixed $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whereExp($field, $condition, $logic = 'AND')
|
||||||
|
{
|
||||||
|
$this->parseWhereExp($logic, $field, 'exp', $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分析查询表达式
|
* 分析查询表达式
|
||||||
* @access public
|
* @access public
|
||||||
@@ -984,6 +1134,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
protected function parseWhereExp($logic, $field, $op, $condition, $param = [])
|
protected function parseWhereExp($logic, $field, $op, $condition, $param = [])
|
||||||
{
|
{
|
||||||
|
$logic = strtoupper($logic);
|
||||||
if ($field instanceof \Closure) {
|
if ($field instanceof \Closure) {
|
||||||
$this->options['where'][$logic][] = is_string($op) ? [$op, $field] : $field;
|
$this->options['where'][$logic][] = is_string($op) ? [$op, $field] : $field;
|
||||||
return;
|
return;
|
||||||
@@ -1003,20 +1154,23 @@ class Query
|
|||||||
// 数组批量查询
|
// 数组批量查询
|
||||||
$where = $field;
|
$where = $field;
|
||||||
foreach ($where as $k => $val) {
|
foreach ($where as $k => $val) {
|
||||||
$this->options['multi'][$k][] = $val;
|
$this->options['multi'][$logic][$k][] = $val;
|
||||||
}
|
}
|
||||||
} elseif ($field && is_string($field)) {
|
} elseif ($field && is_string($field)) {
|
||||||
// 字符串查询
|
// 字符串查询
|
||||||
$where[$field] = ['null', ''];
|
$where[$field] = ['null', ''];
|
||||||
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
}
|
}
|
||||||
} elseif (is_array($op)) {
|
} elseif (is_array($op)) {
|
||||||
$where[$field] = $param;
|
$where[$field] = $param;
|
||||||
} elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) {
|
} elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) {
|
||||||
// null查询
|
// null查询
|
||||||
$where[$field] = [$op, ''];
|
$where[$field] = [$op, ''];
|
||||||
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
} elseif (is_null($condition)) {
|
} elseif (is_null($condition)) {
|
||||||
// 字段相等查询
|
// 字段相等查询
|
||||||
$where[$field] = ['eq', $op];
|
$where[$field] = ['eq', $op];
|
||||||
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
} else {
|
} else {
|
||||||
$where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];
|
$where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];
|
||||||
if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {
|
if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {
|
||||||
@@ -1024,18 +1178,18 @@ class Query
|
|||||||
$this->bind($param[2]);
|
$this->bind($param[2]);
|
||||||
}
|
}
|
||||||
// 记录一个字段多次查询条件
|
// 记录一个字段多次查询条件
|
||||||
$this->options['multi'][$field][] = $where[$field];
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
}
|
}
|
||||||
if (!empty($where)) {
|
if (!empty($where)) {
|
||||||
if (!isset($this->options['where'][$logic])) {
|
if (!isset($this->options['where'][$logic])) {
|
||||||
$this->options['where'][$logic] = [];
|
$this->options['where'][$logic] = [];
|
||||||
}
|
}
|
||||||
if (is_string($field) && $this->checkMultiField($field)) {
|
if (is_string($field) && $this->checkMultiField($field, $logic)) {
|
||||||
$where[$field] = $this->options['multi'][$field];
|
$where[$field] = $this->options['multi'][$logic][$field];
|
||||||
} elseif (is_array($field)) {
|
} elseif (is_array($field)) {
|
||||||
foreach ($field as $key => $val) {
|
foreach ($field as $key => $val) {
|
||||||
if ($this->checkMultiField($key)) {
|
if ($this->checkMultiField($key, $logic)) {
|
||||||
$where[$key] = $this->options['multi'][$key];
|
$where[$key] = $this->options['multi'][$logic][$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1043,10 +1197,16 @@ class Query
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否存在一个字段多次查询条件
|
/**
|
||||||
private function checkMultiField($field)
|
* 检查是否存在一个字段多次查询条件
|
||||||
|
* @access public
|
||||||
|
* @param string $field 查询字段
|
||||||
|
* @param string $logic 查询逻辑 and or xor
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkMultiField($field, $logic)
|
||||||
{
|
{
|
||||||
return isset($this->options['multi'][$field]) && count($this->options['multi'][$field]) > 1;
|
return isset($this->options['multi'][$logic][$field]) && count($this->options['multi'][$logic][$field]) > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1115,8 +1275,8 @@ class Query
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询
|
* 分页查询
|
||||||
* @param int|null $listRows 每页数量
|
* @param int|array $listRows 每页数量 数组表示配置参数
|
||||||
* @param int|bool $simple 简洁模式或者总记录数
|
* @param int|bool $simple 是否简洁模式或者总记录数
|
||||||
* @param array $config 配置参数
|
* @param array $config 配置参数
|
||||||
* page:当前页,
|
* page:当前页,
|
||||||
* path:url路径,
|
* path:url路径,
|
||||||
@@ -1134,8 +1294,13 @@ class Query
|
|||||||
$total = $simple;
|
$total = $simple;
|
||||||
$simple = false;
|
$simple = false;
|
||||||
}
|
}
|
||||||
|
if (is_array($listRows)) {
|
||||||
|
$config = array_merge(Config::get('paginate'), $listRows);
|
||||||
|
$listRows = $config['list_rows'];
|
||||||
|
} else {
|
||||||
$config = array_merge(Config::get('paginate'), $config);
|
$config = array_merge(Config::get('paginate'), $config);
|
||||||
$listRows = $listRows ?: $config['list_rows'];
|
$listRows = $listRows ?: $config['list_rows'];
|
||||||
|
}
|
||||||
|
|
||||||
/** @var Paginator $class */
|
/** @var Paginator $class */
|
||||||
$class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']);
|
$class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']);
|
||||||
@@ -1400,7 +1565,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function fetchPdo($pdo = true)
|
public function fetchPdo($pdo = true)
|
||||||
{
|
{
|
||||||
$this->options['fetch_class'] = $pdo;
|
$this->options['fetch_pdo'] = $pdo;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1479,7 +1644,7 @@ class Query
|
|||||||
switch (strtolower($op)) {
|
switch (strtolower($op)) {
|
||||||
case 'today':
|
case 'today':
|
||||||
case 'd':
|
case 'd':
|
||||||
$range = 'today';
|
$range = ['today', 'tomorrow'];
|
||||||
break;
|
break;
|
||||||
case 'week':
|
case 'week':
|
||||||
case 'w':
|
case 'w':
|
||||||
@@ -1505,6 +1670,8 @@ class Query
|
|||||||
case 'last year':
|
case 'last year':
|
||||||
$range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])];
|
$range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])];
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
$range = $op;
|
||||||
}
|
}
|
||||||
$op = is_array($range) ? 'between' : '>';
|
$op = is_array($range) ? 'between' : '>';
|
||||||
}
|
}
|
||||||
@@ -2023,6 +2190,27 @@ class Query
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行查询但只返回PDOStatement对象
|
||||||
|
* @access public
|
||||||
|
* @return \PDOStatement|string
|
||||||
|
*/
|
||||||
|
public function getPdo()
|
||||||
|
{
|
||||||
|
// 分析查询表达式
|
||||||
|
$options = $this->parseExpress();
|
||||||
|
// 生成查询SQL
|
||||||
|
$sql = $this->builder->select($options);
|
||||||
|
// 获取参数绑定
|
||||||
|
$bind = $this->getBind();
|
||||||
|
if ($options['fetch_sql']) {
|
||||||
|
// 获取实际执行的SQL语句
|
||||||
|
return $this->connection->getRealSql($sql, $bind);
|
||||||
|
}
|
||||||
|
// 执行查询操作
|
||||||
|
return $this->query($sql, $bind, $options['master'], true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找记录
|
* 查找记录
|
||||||
* @access public
|
* @access public
|
||||||
@@ -2071,7 +2259,7 @@ class Query
|
|||||||
if ($resultSet = $this->trigger('before_select', $options)) {
|
if ($resultSet = $this->trigger('before_select', $options)) {
|
||||||
} else {
|
} else {
|
||||||
// 执行查询操作
|
// 执行查询操作
|
||||||
$resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
$resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']);
|
||||||
|
|
||||||
if ($resultSet instanceof \PDOStatement) {
|
if ($resultSet instanceof \PDOStatement) {
|
||||||
// 返回PDOStatement对象
|
// 返回PDOStatement对象
|
||||||
@@ -2174,7 +2362,7 @@ class Query
|
|||||||
if ($result = $this->trigger('before_find', $options)) {
|
if ($result = $this->trigger('before_find', $options)) {
|
||||||
} else {
|
} else {
|
||||||
// 执行查询
|
// 执行查询
|
||||||
$result = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
$result = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']);
|
||||||
|
|
||||||
if ($result instanceof \PDOStatement) {
|
if ($result instanceof \PDOStatement) {
|
||||||
// 返回PDOStatement对象
|
// 返回PDOStatement对象
|
||||||
@@ -2454,7 +2642,7 @@ class Query
|
|||||||
$options['strict'] = $this->getConfig('fields_strict');
|
$options['strict'] = $this->getConfig('fields_strict');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (['master', 'lock', 'fetch_class', 'fetch_sql', 'distinct'] as $name) {
|
foreach (['master', 'lock', 'fetch_pdo', 'fetch_sql', 'distinct'] as $name) {
|
||||||
if (!isset($options[$name])) {
|
if (!isset($options[$name])) {
|
||||||
$options[$name] = false;
|
$options[$name] = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ class BelongsToMany extends Relation
|
|||||||
* @param bool $relationDel 是否同时删除关联表数据
|
* @param bool $relationDel 是否同时删除关联表数据
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function detach($data, $relationDel = false)
|
public function detach($data = null, $relationDel = false)
|
||||||
{
|
{
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
$id = $data;
|
$id = $data;
|
||||||
|
|||||||
Reference in New Issue
Block a user