内核更新
This commit is contained in:
@@ -29,5 +29,5 @@ return array(
|
|||||||
'prefix' => 'admin',
|
'prefix' => 'admin',
|
||||||
'type' => '',
|
'type' => '',
|
||||||
'auto_start' => true,
|
'auto_start' => true,
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
// | Author: liu21st <liu21st@gmail.com>
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
define('THINK_VERSION', '5.0.6');
|
define('THINK_VERSION', '5.0.7');
|
||||||
define('THINK_START_TIME', microtime(true));
|
define('THINK_START_TIME', microtime(true));
|
||||||
define('THINK_START_MEM', memory_get_usage());
|
define('THINK_START_MEM', memory_get_usage());
|
||||||
define('EXT', '.php');
|
define('EXT', '.php');
|
||||||
|
|||||||
@@ -85,14 +85,14 @@ class App
|
|||||||
|
|
||||||
$request->filter($config['default_filter']);
|
$request->filter($config['default_filter']);
|
||||||
|
|
||||||
|
// 默认语言
|
||||||
|
Lang::range($config['default_lang']);
|
||||||
if ($config['lang_switch_on']) {
|
if ($config['lang_switch_on']) {
|
||||||
// 开启多语言机制 检测当前语言
|
// 开启多语言机制 检测当前语言
|
||||||
Lang::detect();
|
Lang::detect();
|
||||||
} else {
|
|
||||||
// 读取默认语言
|
|
||||||
Lang::range($config['default_lang']);
|
|
||||||
}
|
}
|
||||||
$request->langset(Lang::range());
|
$request->langset(Lang::range());
|
||||||
|
|
||||||
// 加载系统语言包
|
// 加载系统语言包
|
||||||
Lang::load([
|
Lang::load([
|
||||||
THINK_PATH . 'lang' . DS . $request->langset() . EXT,
|
THINK_PATH . 'lang' . DS . $request->langset() . EXT,
|
||||||
@@ -120,35 +120,7 @@ class App
|
|||||||
// 请求缓存检查
|
// 请求缓存检查
|
||||||
$request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);
|
$request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);
|
||||||
|
|
||||||
switch ($dispatch['type']) {
|
$data = self::exec($dispatch, $config);
|
||||||
case 'redirect':
|
|
||||||
// 执行重定向跳转
|
|
||||||
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
|
|
||||||
break;
|
|
||||||
case 'module':
|
|
||||||
// 模块/控制器/操作
|
|
||||||
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
|
|
||||||
break;
|
|
||||||
case 'controller':
|
|
||||||
// 执行控制器操作
|
|
||||||
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
|
||||||
$data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);
|
|
||||||
break;
|
|
||||||
case 'method':
|
|
||||||
// 执行回调方法
|
|
||||||
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
|
||||||
$data = self::invokeMethod($dispatch['method'], $vars);
|
|
||||||
break;
|
|
||||||
case 'function':
|
|
||||||
// 执行闭包
|
|
||||||
$data = self::invokeFunction($dispatch['function']);
|
|
||||||
break;
|
|
||||||
case 'response':
|
|
||||||
$data = $dispatch['response'];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new \InvalidArgumentException('dispatch type not support');
|
|
||||||
}
|
|
||||||
} catch (HttpResponseException $exception) {
|
} catch (HttpResponseException $exception) {
|
||||||
$data = $exception->getResponse();
|
$data = $exception->getResponse();
|
||||||
}
|
}
|
||||||
@@ -245,7 +217,7 @@ class App
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定参数
|
* 绑定参数
|
||||||
* @access public
|
* @access private
|
||||||
* @param \ReflectionMethod|\ReflectionFunction $reflect 反射类
|
* @param \ReflectionMethod|\ReflectionFunction $reflect 反射类
|
||||||
* @param array $vars 变量
|
* @param array $vars 变量
|
||||||
* @return array
|
* @return array
|
||||||
@@ -261,43 +233,90 @@ class App
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$args = [];
|
$args = [];
|
||||||
// 判断数组类型 数字数组时按顺序绑定参数
|
|
||||||
reset($vars);
|
|
||||||
$type = key($vars) === 0 ? 1 : 0;
|
|
||||||
if ($reflect->getNumberOfParameters() > 0) {
|
if ($reflect->getNumberOfParameters() > 0) {
|
||||||
|
// 判断数组类型 数字数组时按顺序绑定参数
|
||||||
|
reset($vars);
|
||||||
|
$type = key($vars) === 0 ? 1 : 0;
|
||||||
$params = $reflect->getParameters();
|
$params = $reflect->getParameters();
|
||||||
foreach ($params as $param) {
|
foreach ($params as $param) {
|
||||||
$name = $param->getName();
|
$args[] = self::getParamValue($param, $vars, $type);
|
||||||
$class = $param->getClass();
|
|
||||||
if ($class) {
|
|
||||||
$className = $class->getName();
|
|
||||||
$bind = Request::instance()->$name;
|
|
||||||
if ($bind instanceof $className) {
|
|
||||||
$args[] = $bind;
|
|
||||||
} else {
|
|
||||||
if (method_exists($className, 'invoke')) {
|
|
||||||
$method = new \ReflectionMethod($className, 'invoke');
|
|
||||||
if ($method->isPublic() && $method->isStatic()) {
|
|
||||||
$args[] = $className::invoke(Request::instance());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$args[] = method_exists($className, 'instance') ? $className::instance() : new $className;
|
|
||||||
}
|
|
||||||
} elseif (1 == $type && !empty($vars)) {
|
|
||||||
$args[] = array_shift($vars);
|
|
||||||
} elseif (0 == $type && isset($vars[$name])) {
|
|
||||||
$args[] = $vars[$name];
|
|
||||||
} elseif ($param->isDefaultValueAvailable()) {
|
|
||||||
$args[] = $param->getDefaultValue();
|
|
||||||
} else {
|
|
||||||
throw new \InvalidArgumentException('method param miss:' . $name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取参数值
|
||||||
|
* @access private
|
||||||
|
* @param \ReflectionParameter $param
|
||||||
|
* @param array $vars 变量
|
||||||
|
* @param string $type
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function getParamValue($param, &$vars, $type)
|
||||||
|
{
|
||||||
|
$name = $param->getName();
|
||||||
|
$class = $param->getClass();
|
||||||
|
if ($class) {
|
||||||
|
$className = $class->getName();
|
||||||
|
$bind = Request::instance()->$name;
|
||||||
|
if ($bind instanceof $className) {
|
||||||
|
$result = $bind;
|
||||||
|
} else {
|
||||||
|
if (method_exists($className, 'invoke')) {
|
||||||
|
$method = new \ReflectionMethod($className, 'invoke');
|
||||||
|
if ($method->isPublic() && $method->isStatic()) {
|
||||||
|
return $className::invoke(Request::instance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result = method_exists($className, 'instance') ? $className::instance() : new $className;
|
||||||
|
}
|
||||||
|
} elseif (1 == $type && !empty($vars)) {
|
||||||
|
$result = array_shift($vars);
|
||||||
|
} elseif (0 == $type && isset($vars[$name])) {
|
||||||
|
$result = $vars[$name];
|
||||||
|
} elseif ($param->isDefaultValueAvailable()) {
|
||||||
|
$result = $param->getDefaultValue();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('method param miss:' . $name);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function exec($dispatch, $config)
|
||||||
|
{
|
||||||
|
switch ($dispatch['type']) {
|
||||||
|
case 'redirect':
|
||||||
|
// 执行重定向跳转
|
||||||
|
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
|
||||||
|
break;
|
||||||
|
case 'module':
|
||||||
|
// 模块/控制器/操作
|
||||||
|
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
|
||||||
|
break;
|
||||||
|
case 'controller':
|
||||||
|
// 执行控制器操作
|
||||||
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
|
$data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);
|
||||||
|
break;
|
||||||
|
case 'method':
|
||||||
|
// 执行回调方法
|
||||||
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
|
$data = self::invokeMethod($dispatch['method'], $vars);
|
||||||
|
break;
|
||||||
|
case 'function':
|
||||||
|
// 执行闭包
|
||||||
|
$data = self::invokeFunction($dispatch['function']);
|
||||||
|
break;
|
||||||
|
case 'response':
|
||||||
|
$data = $dispatch['response'];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException('dispatch type not support');
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行模块
|
* 执行模块
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use SplFileInfo;
|
|
||||||
use SplFileObject;
|
use SplFileObject;
|
||||||
|
|
||||||
class File extends SplFileObject
|
class File extends SplFileObject
|
||||||
@@ -281,7 +280,7 @@ class File extends SplFileObject
|
|||||||
* @param string $path 保存路径
|
* @param string $path 保存路径
|
||||||
* @param string|bool $savename 保存的文件名 默认自动生成
|
* @param string|bool $savename 保存的文件名 默认自动生成
|
||||||
* @param boolean $replace 同名文件是否覆盖
|
* @param boolean $replace 同名文件是否覆盖
|
||||||
* @return false|SplFileInfo false-失败 否则返回SplFileInfo实例
|
* @return false|File false-失败 否则返回File实例
|
||||||
*/
|
*/
|
||||||
public function move($path, $savename = true, $replace = true)
|
public function move($path, $savename = true, $replace = true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -369,8 +369,9 @@ class Loader
|
|||||||
if (isset(self::$instance[$guid])) {
|
if (isset(self::$instance[$guid])) {
|
||||||
return self::$instance[$guid];
|
return self::$instance[$guid];
|
||||||
}
|
}
|
||||||
if (strpos($name, '\\')) {
|
if (false !== strpos($name, '\\')) {
|
||||||
$class = $name;
|
$class = $name;
|
||||||
|
$module = Request::instance()->module();
|
||||||
} else {
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name, 2);
|
list($module, $name) = explode('/', $name, 2);
|
||||||
@@ -404,8 +405,9 @@ class Loader
|
|||||||
*/
|
*/
|
||||||
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
|
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
|
||||||
{
|
{
|
||||||
if (strpos($name, '\\')) {
|
if (false !== strpos($name, '\\')) {
|
||||||
$class = $name;
|
$class = $name;
|
||||||
|
$module = Request::instance()->module();
|
||||||
} else {
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name);
|
list($module, $name) = explode('/', $name);
|
||||||
@@ -440,8 +442,9 @@ class Loader
|
|||||||
if (isset(self::$instance[$guid])) {
|
if (isset(self::$instance[$guid])) {
|
||||||
return self::$instance[$guid];
|
return self::$instance[$guid];
|
||||||
}
|
}
|
||||||
if (strpos($name, '\\')) {
|
if (false !== strpos($name, '\\')) {
|
||||||
$class = $name;
|
$class = $name;
|
||||||
|
$module = Request::instance()->module();
|
||||||
} else {
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name);
|
list($module, $name) = explode('/', $name);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class Log
|
|||||||
public static function record($msg, $type = 'log')
|
public static function record($msg, $type = 'log')
|
||||||
{
|
{
|
||||||
self::$log[$type][] = $msg;
|
self::$log[$type][] = $msg;
|
||||||
if (IS_CLI && count(self::$log[$type]) > 100) {
|
if (IS_CLI) {
|
||||||
// 命令行下面日志写入改进
|
// 命令行下面日志写入改进
|
||||||
self::save();
|
self::save();
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ class Log
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前日志记录的授权key
|
* 当前日志记录的授权key
|
||||||
* @param string $key 授权key
|
* @param string $key 授权key
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function key($key)
|
public static function key($key)
|
||||||
@@ -111,7 +111,7 @@ class Log
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查日志写入权限
|
* 检查日志写入权限
|
||||||
* @param array $config 当前日志配置参数
|
* @param array $config 当前日志配置参数
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function check($config)
|
public static function check($config)
|
||||||
@@ -166,13 +166,14 @@ class Log
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 实时写入日志信息 并支持行为
|
* 实时写入日志信息 并支持行为
|
||||||
* @param mixed $msg 调试信息
|
* @param mixed $msg 调试信息
|
||||||
* @param string $type 信息类型
|
* @param string $type 信息类型
|
||||||
* @param bool $force 是否强制写入
|
* @param bool $force 是否强制写入
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function write($msg, $type = 'log', $force = false)
|
public static function write($msg, $type = 'log', $force = false)
|
||||||
{
|
{
|
||||||
|
$log = self::$log;
|
||||||
// 封装日志信息
|
// 封装日志信息
|
||||||
if (true === $force || empty(self::$config['level'])) {
|
if (true === $force || empty(self::$config['level'])) {
|
||||||
$log[$type][] = $msg;
|
$log[$type][] = $msg;
|
||||||
@@ -188,7 +189,11 @@ class Log
|
|||||||
self::init(Config::get('log'));
|
self::init(Config::get('log'));
|
||||||
}
|
}
|
||||||
// 写入日志
|
// 写入日志
|
||||||
return self::$driver->save($log, false);
|
$result = self::$driver->save($log);
|
||||||
|
if ($result) {
|
||||||
|
self::$log = [];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -290,9 +290,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 标记字段更改
|
// 标记字段更改
|
||||||
if (isset($this->data[$name]) && is_scalar($this->data[$name]) && is_scalar($value) && 0 !== strcmp($this->data[$name], $value)) {
|
if (!isset($this->data[$name])) {
|
||||||
$this->change[] = $name;
|
$this->change[] = $name;
|
||||||
} elseif (!isset($this->data[$name]) || $value != $this->data[$name]) {
|
} elseif (is_scalar($value) && is_scalar($this->data[$name]) && 0 !== strcmp($this->data[$name], $value)) {
|
||||||
|
$this->change[] = $name;
|
||||||
|
} elseif (!is_object($value) && $value != $this->data[$name]) {
|
||||||
$this->change[] = $name;
|
$this->change[] = $name;
|
||||||
}
|
}
|
||||||
// 设置数据对象属性
|
// 设置数据对象属性
|
||||||
@@ -378,7 +380,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
if (empty($param)) {
|
if (empty($param)) {
|
||||||
$value = (float) $value;
|
$value = (float) $value;
|
||||||
} else {
|
} else {
|
||||||
$value = (float) number_format($value, $param);
|
$value = (float) number_format($value, $param, '.', '');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
@@ -486,7 +488,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
if (empty($param)) {
|
if (empty($param)) {
|
||||||
$value = (float) $value;
|
$value = (float) $value;
|
||||||
} else {
|
} else {
|
||||||
$value = (float) number_format($value, $param);
|
$value = (float) number_format($value, $param, '.', '');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
@@ -508,7 +510,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$value = json_decode($value, true);
|
$value = json_decode($value, true);
|
||||||
break;
|
break;
|
||||||
case 'array':
|
case 'array':
|
||||||
$value = is_null($value) ? [] : json_decode($value, true);
|
$value = empty($value) ? [] : json_decode($value, true);
|
||||||
break;
|
break;
|
||||||
case 'object':
|
case 'object':
|
||||||
$value = empty($value) ? new \stdClass() : json_decode($value);
|
$value = empty($value) ? new \stdClass() : json_decode($value);
|
||||||
@@ -837,11 +839,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
// 数据自动完成
|
// 数据自动完成
|
||||||
$this->autoCompleteData($this->auto);
|
$this->autoCompleteData($this->auto);
|
||||||
|
|
||||||
// 自动写入更新时间
|
|
||||||
if ($this->autoWriteTimestamp && $this->updateTime && (empty($this->change) || !in_array($this->updateTime, $this->change))) {
|
|
||||||
$this->setAttr($this->updateTime, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 事件回调
|
// 事件回调
|
||||||
if (false === $this->trigger('before_write', $this)) {
|
if (false === $this->trigger('before_write', $this)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -873,6 +870,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) {
|
||||||
|
// 没有更新
|
||||||
|
return 0;
|
||||||
|
} elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {
|
||||||
|
// 自动写入更新时间
|
||||||
|
$data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($where) && !empty($this->updateWhere)) {
|
if (empty($where) && !empty($this->updateWhere)) {
|
||||||
$where = $this->updateWhere;
|
$where = $this->updateWhere;
|
||||||
}
|
}
|
||||||
@@ -919,10 +924,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
} else {
|
} else {
|
||||||
// 自动写入
|
// 自动写入
|
||||||
$this->autoCompleteData($this->insert);
|
$this->autoCompleteData($this->insert);
|
||||||
|
// 自动写入创建时间和更新时间
|
||||||
// 自动写入创建时间
|
if ($this->autoWriteTimestamp) {
|
||||||
if ($this->autoWriteTimestamp && $this->createTime && (empty($this->change) || !in_array($this->createTime, $this->change))) {
|
if ($this->createTime && !isset($this->data[$this->createTime])) {
|
||||||
$this->setAttr($this->createTime, null);
|
$this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime);
|
||||||
|
}
|
||||||
|
if ($this->updateTime && !isset($this->data[$this->updateTime])) {
|
||||||
|
$this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === $this->trigger('before_insert', $this)) {
|
if (false === $this->trigger('before_insert', $this)) {
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$total = $this->total();
|
$total = $this->total();
|
||||||
} catch (Exception $e) {
|
} catch (\DomainException $e) {
|
||||||
$total = null;
|
$total = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
|||||||
'total' => $total,
|
'total' => $total,
|
||||||
'per_page' => $this->listRows(),
|
'per_page' => $this->listRows(),
|
||||||
'current_page' => $this->currentPage(),
|
'current_page' => $this->currentPage(),
|
||||||
'data' => $this->items->toArray()
|
'data' => $this->items->toArray(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ class Request
|
|||||||
if (true === $name) {
|
if (true === $name) {
|
||||||
// 获取包含文件上传信息的数组
|
// 获取包含文件上传信息的数组
|
||||||
$file = $this->file();
|
$file = $this->file();
|
||||||
$data = array_merge($this->param, $file);
|
$data = is_array($file) ? array_merge($this->param, $file) : $this->param;
|
||||||
return $this->input($data, '', $default, $filter);
|
return $this->input($data, '', $default, $filter);
|
||||||
}
|
}
|
||||||
return $this->input($this->param, $name, $default, $filter);
|
return $this->input($this->param, $name, $default, $filter);
|
||||||
@@ -688,7 +688,7 @@ class Request
|
|||||||
{
|
{
|
||||||
if (empty($this->post)) {
|
if (empty($this->post)) {
|
||||||
$content = $this->input;
|
$content = $this->input;
|
||||||
if (empty($_POST) && 'application/json' == $this->contentType()) {
|
if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) {
|
||||||
$this->post = (array) json_decode($content, true);
|
$this->post = (array) json_decode($content, true);
|
||||||
} else {
|
} else {
|
||||||
$this->post = $_POST;
|
$this->post = $_POST;
|
||||||
@@ -713,7 +713,7 @@ class Request
|
|||||||
{
|
{
|
||||||
if (is_null($this->put)) {
|
if (is_null($this->put)) {
|
||||||
$content = $this->input;
|
$content = $this->input;
|
||||||
if ('application/json' == $this->contentType()) {
|
if (false !== strpos($this->contentType(), 'application/json')) {
|
||||||
$this->put = (array) json_decode($content, true);
|
$this->put = (array) json_decode($content, true);
|
||||||
} else {
|
} else {
|
||||||
parse_str($content, $this->put);
|
parse_str($content, $this->put);
|
||||||
@@ -1357,7 +1357,11 @@ class Request
|
|||||||
{
|
{
|
||||||
$contentType = $this->server('CONTENT_TYPE');
|
$contentType = $this->server('CONTENT_TYPE');
|
||||||
if ($contentType) {
|
if ($contentType) {
|
||||||
list($type) = explode(';', $contentType);
|
if (strpos($contentType, ';')) {
|
||||||
|
list($type) = explode(';', $contentType);
|
||||||
|
} else {
|
||||||
|
$type = $contentType;
|
||||||
|
}
|
||||||
return trim($type);
|
return trim($type);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
@@ -833,7 +833,7 @@ class Route
|
|||||||
// 分隔符替换 确保路由定义使用统一的分隔符
|
// 分隔符替换 确保路由定义使用统一的分隔符
|
||||||
$url = str_replace($depr, '|', $url);
|
$url = str_replace($depr, '|', $url);
|
||||||
|
|
||||||
if (strpos($url, '|') && isset(self::$rules['alias'][strstr($url, '|', true)])) {
|
if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) {
|
||||||
// 检测路由别名
|
// 检测路由别名
|
||||||
$result = self::checkRouteAlias($request, $url, $depr);
|
$result = self::checkRouteAlias($request, $url, $depr);
|
||||||
if (false !== $result) {
|
if (false !== $result) {
|
||||||
@@ -1057,7 +1057,7 @@ class Route
|
|||||||
if (!empty($array[1])) {
|
if (!empty($array[1])) {
|
||||||
self::parseUrlParams($array[1]);
|
self::parseUrlParams($array[1]);
|
||||||
}
|
}
|
||||||
return ['type' => 'method', 'method' => [$class, $action]];
|
return ['type' => 'method', 'method' => [$class, $action], 'var' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1077,7 +1077,7 @@ class Route
|
|||||||
if (!empty($array[2])) {
|
if (!empty($array[2])) {
|
||||||
self::parseUrlParams($array[2]);
|
self::parseUrlParams($array[2]);
|
||||||
}
|
}
|
||||||
return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method]];
|
return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method], 'var' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1096,7 +1096,7 @@ class Route
|
|||||||
if (!empty($array[1])) {
|
if (!empty($array[1])) {
|
||||||
self::parseUrlParams($array[1]);
|
self::parseUrlParams($array[1]);
|
||||||
}
|
}
|
||||||
return ['type' => 'controller', 'controller' => $controller . '/' . $action];
|
return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'var' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1281,9 +1281,6 @@ class Route
|
|||||||
} elseif (strpos($url, '/')) {
|
} elseif (strpos($url, '/')) {
|
||||||
// [模块/控制器/操作]
|
// [模块/控制器/操作]
|
||||||
$path = explode('/', $url);
|
$path = explode('/', $url);
|
||||||
} elseif (false !== strpos($url, '=')) {
|
|
||||||
// 参数1=值1&参数2=值2...
|
|
||||||
parse_str($url, $var);
|
|
||||||
} else {
|
} else {
|
||||||
$path = [$url];
|
$path = [$url];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -927,7 +927,7 @@ class Template
|
|||||||
if (false === strpos($name, '(')) {
|
if (false === strpos($name, '(')) {
|
||||||
$name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')';
|
$name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')';
|
||||||
} else {
|
} else {
|
||||||
$name = '(' . $name . ' !== \'\'?' . $name . ':' . $args[1] . ')';
|
$name = '(' . $name . ' ?: ' . $args[1] . ')';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // 通用模板函数
|
default: // 通用模板函数
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class Url
|
|||||||
$host = $request->host();
|
$host = $request->host();
|
||||||
$rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host;
|
$rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host;
|
||||||
}
|
}
|
||||||
if (!strpos($domain, $rootDomain)) {
|
if (substr_count($domain, '.') < 2 && !strpos($domain, $rootDomain)) {
|
||||||
$domain .= '.' . $rootDomain;
|
$domain .= '.' . $rootDomain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,14 +98,18 @@ abstract class Builder
|
|||||||
$result = [];
|
$result = [];
|
||||||
foreach ($data as $key => $val) {
|
foreach ($data as $key => $val) {
|
||||||
$item = $this->parseKey($key, $options);
|
$item = $this->parseKey($key, $options);
|
||||||
|
if (is_object($val) && method_exists($val, '__toString')) {
|
||||||
|
// 对象数据写入
|
||||||
|
$val = $val->__toString();
|
||||||
|
}
|
||||||
if (false === strpos($key, '.') && !in_array($key, $fields, true)) {
|
if (false === strpos($key, '.') && !in_array($key, $fields, true)) {
|
||||||
if ($options['strict']) {
|
if ($options['strict']) {
|
||||||
throw new Exception('fields not exists:[' . $key . ']');
|
throw new Exception('fields not exists:[' . $key . ']');
|
||||||
}
|
}
|
||||||
} elseif (isset($val[0]) && 'exp' == $val[0]) {
|
|
||||||
$result[$item] = $val[1];
|
|
||||||
} elseif (is_null($val)) {
|
} elseif (is_null($val)) {
|
||||||
$result[$item] = 'NULL';
|
$result[$item] = 'NULL';
|
||||||
|
} elseif (isset($val[0]) && 'exp' == $val[0]) {
|
||||||
|
$result[$item] = $val[1];
|
||||||
} elseif (is_scalar($val)) {
|
} elseif (is_scalar($val)) {
|
||||||
// 过滤非标量数据
|
// 过滤非标量数据
|
||||||
if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) {
|
if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) {
|
||||||
@@ -115,9 +119,6 @@ abstract class Builder
|
|||||||
$this->query->bind('__data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
$this->query->bind('__data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||||
$result[$item] = ':__data__' . $key;
|
$result[$item] = ':__data__' . $key;
|
||||||
}
|
}
|
||||||
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
|
||||||
// 对象数据写入
|
|
||||||
$result[$item] = $val->__toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@@ -279,6 +280,13 @@ abstract class Builder
|
|||||||
|
|
||||||
$whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($key) + 1) : implode(' ', $str);
|
$whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($key) + 1) : implode(' ', $str);
|
||||||
}
|
}
|
||||||
|
if (!empty($options['soft_delete'])) {
|
||||||
|
// 附加软删除条件
|
||||||
|
list($field, $condition) = $options['soft_delete'];
|
||||||
|
|
||||||
|
$whereStr = $whereStr ? '( ' . $whereStr . ' ) AND ' : '';
|
||||||
|
$whereStr = $whereStr . $this->parseWhereItem($field, $condition, '', $options, $binds);
|
||||||
|
}
|
||||||
return $whereStr;
|
return $whereStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +387,7 @@ abstract class Builder
|
|||||||
} else {
|
} else {
|
||||||
$zone = implode(',', $this->parseValue($value, $field));
|
$zone = implode(',', $this->parseValue($value, $field));
|
||||||
}
|
}
|
||||||
$whereStr .= $key . ' ' . $exp . ' (' . $zone . ')';
|
$whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')';
|
||||||
}
|
}
|
||||||
} elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) {
|
} elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) {
|
||||||
// BETWEEN 查询
|
// BETWEEN 查询
|
||||||
|
|||||||
@@ -893,7 +893,7 @@ class Query
|
|||||||
} else {
|
} else {
|
||||||
$name = $alias . '.' . $key;
|
$name = $alias . '.' . $key;
|
||||||
}
|
}
|
||||||
$fields[] = $name . ' AS ' . $val;
|
$fields[$name] = $val;
|
||||||
$this->options['map'][$val] = $name;
|
$this->options['map'][$val] = $name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1120,6 +1120,20 @@ class Query
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置软删除字段及条件
|
||||||
|
* @access public
|
||||||
|
* @param false|string $field 查询字段
|
||||||
|
* @param mixed $condition 查询条件
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function useSoftDelete($field, $condition = null)
|
||||||
|
{
|
||||||
|
if ($field) {
|
||||||
|
$this->options['soft_delete'] = [$field, $condition ?: ['null', '']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分析查询表达式
|
* 分析查询表达式
|
||||||
* @access public
|
* @access public
|
||||||
@@ -1895,7 +1909,7 @@ class Query
|
|||||||
$relation = Loader::parseName($relation, 1, false);
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
$model = $class->$relation();
|
$model = $class->$relation();
|
||||||
if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
|
if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
|
||||||
$model->eagerly($this, $relation, $subRelation, $closure, $first);
|
$model->removeOption()->eagerly($this, $relation, $subRelation, $closure, $first);
|
||||||
$first = false;
|
$first = false;
|
||||||
} elseif ($closure) {
|
} elseif ($closure) {
|
||||||
$with[$key] = $closure;
|
$with[$key] = $closure;
|
||||||
@@ -2210,7 +2224,7 @@ class Query
|
|||||||
// 执行操作
|
// 执行操作
|
||||||
$result = '' == $sql ? 0 : $this->execute($sql, $bind);
|
$result = '' == $sql ? 0 : $this->execute($sql, $bind);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
if (isset($where[$pk])) {
|
if (is_string($pk) && isset($where[$pk])) {
|
||||||
$data[$pk] = $where[$pk];
|
$data[$pk] = $where[$pk];
|
||||||
} elseif (is_string($pk) && isset($key) && strpos($key, '|')) {
|
} elseif (is_string($pk) && isset($key) && strpos($key, '|')) {
|
||||||
list($a, $val) = explode('|', $key);
|
list($a, $val) = explode('|', $key);
|
||||||
@@ -2302,7 +2316,7 @@ class Query
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cache)) {
|
if (isset($cache) && $resultSet) {
|
||||||
// 缓存数据集
|
// 缓存数据集
|
||||||
$this->cacheData($key, $resultSet, $cache);
|
$this->cacheData($key, $resultSet, $cache);
|
||||||
}
|
}
|
||||||
@@ -2459,7 +2473,7 @@ class Query
|
|||||||
$result = isset($resultSet[0]) ? $resultSet[0] : null;
|
$result = isset($resultSet[0]) ? $resultSet[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cache)) {
|
if (isset($cache) && $result) {
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
$this->cacheData($key, $result, $cache);
|
$this->cacheData($key, $result, $cache);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,11 @@ class Mysql extends Builder
|
|||||||
$key = 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
$key = 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
||||||
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
|
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
|
if ('__TABLE__' == $table) {
|
||||||
|
$table = $this->query->getTable();
|
||||||
|
}
|
||||||
if (isset($options['alias'][$table])) {
|
if (isset($options['alias'][$table])) {
|
||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
} elseif ('__TABLE__' == $table) {
|
|
||||||
$table = $this->query->getTable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
||||||
|
|||||||
@@ -55,10 +55,11 @@ class Pgsql extends Builder
|
|||||||
$key = $field . '->>\'' . $name . '\'';
|
$key = $field . '->>\'' . $name . '\'';
|
||||||
} elseif (strpos($key, '.')) {
|
} elseif (strpos($key, '.')) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
|
if ('__TABLE__' == $table) {
|
||||||
|
$table = $this->query->getTable();
|
||||||
|
}
|
||||||
if (isset($options['alias'][$table])) {
|
if (isset($options['alias'][$table])) {
|
||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
} elseif ('__TABLE__' == $table) {
|
|
||||||
$table = $this->query->getTable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($table)) {
|
if (isset($table)) {
|
||||||
|
|||||||
@@ -60,10 +60,11 @@ class Sqlite extends Builder
|
|||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '.')) {
|
if (strpos($key, '.')) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
|
if ('__TABLE__' == $table) {
|
||||||
|
$table = $this->query->getTable();
|
||||||
|
}
|
||||||
if (isset($options['alias'][$table])) {
|
if (isset($options['alias'][$table])) {
|
||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
} elseif ('__TABLE__' == $table) {
|
|
||||||
$table = $this->query->getTable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($table)) {
|
if (isset($table)) {
|
||||||
|
|||||||
@@ -73,10 +73,11 @@ class Sqlsrv extends Builder
|
|||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
|
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
|
if ('__TABLE__' == $table) {
|
||||||
|
$table = $this->query->getTable();
|
||||||
|
}
|
||||||
if (isset($options['alias'][$table])) {
|
if (isset($options['alias'][$table])) {
|
||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
} elseif ('__TABLE__' == $table) {
|
|
||||||
$table = $this->query->getTable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ class File
|
|||||||
'apart_level' => [],
|
'apart_level' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $writed = [];
|
||||||
|
|
||||||
// 实例化并传入参数
|
// 实例化并传入参数
|
||||||
public function __construct($config = [])
|
public function __construct($config = [])
|
||||||
{
|
{
|
||||||
@@ -37,45 +39,17 @@ class File
|
|||||||
* 日志写入接口
|
* 日志写入接口
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $log 日志信息
|
* @param array $log 日志信息
|
||||||
* @param bool $depr 是否写入分割线
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function save(array $log = [], $depr = true)
|
public function save(array $log = [])
|
||||||
{
|
{
|
||||||
$now = date($this->config['time_format']);
|
$cli = IS_CLI ? '_cli' : '';
|
||||||
$destination = $this->config['path'] . date('Ym') . DS . date('d') . '.log';
|
$destination = $this->config['path'] . date('Ym') . DS . date('d') . $cli . '.log';
|
||||||
|
|
||||||
$path = dirname($destination);
|
$path = dirname($destination);
|
||||||
!is_dir($path) && mkdir($path, 0755, true);
|
!is_dir($path) && mkdir($path, 0755, true);
|
||||||
|
|
||||||
//检测日志文件大小,超过配置大小则备份日志文件重新生成
|
|
||||||
if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) {
|
|
||||||
rename($destination, dirname($destination) . DS . $_SERVER['REQUEST_TIME'] . '-' . basename($destination));
|
|
||||||
}
|
|
||||||
|
|
||||||
$depr = $depr ? "---------------------------------------------------------------\r\n" : '';
|
|
||||||
$info = '';
|
$info = '';
|
||||||
if (App::$debug) {
|
|
||||||
// 获取基本信息
|
|
||||||
if (isset($_SERVER['HTTP_HOST'])) {
|
|
||||||
$current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
|
||||||
} else {
|
|
||||||
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$runtime = round(microtime(true) - THINK_START_TIME, 10);
|
|
||||||
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
|
||||||
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
|
||||||
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
|
||||||
$memory_str = ' [内存消耗:' . $memory_use . 'kb]';
|
|
||||||
$file_load = ' [文件加载:' . count(get_included_files()) . ']';
|
|
||||||
|
|
||||||
$info = '[ log ] ' . $current_uri . $time_str . $memory_str . $file_load . "\r\n";
|
|
||||||
$server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '0.0.0.0';
|
|
||||||
$remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
|
|
||||||
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI';
|
|
||||||
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
|
||||||
}
|
|
||||||
foreach ($log as $type => $val) {
|
foreach ($log as $type => $val) {
|
||||||
$level = '';
|
$level = '';
|
||||||
foreach ($val as $msg) {
|
foreach ($val as $msg) {
|
||||||
@@ -86,16 +60,60 @@ class File
|
|||||||
}
|
}
|
||||||
if (in_array($type, $this->config['apart_level'])) {
|
if (in_array($type, $this->config['apart_level'])) {
|
||||||
// 独立记录的日志级别
|
// 独立记录的日志级别
|
||||||
$filename = $path . DS . date('d') . '_' . $type . '.log';
|
$filename = $path . DS . date('d') . '_' . $type . $cli . '.log';
|
||||||
error_log("[{$now}] {$level}\r\n{$depr}", 3, $filename);
|
$this->write($level, $filename, true);
|
||||||
} else {
|
} else {
|
||||||
$info .= $level;
|
$info .= $level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (App::$debug) {
|
if ($info) {
|
||||||
$info = "{$server} {$remote} {$method} {$uri}\r\n" . $info;
|
return $this->write($info, $destination);
|
||||||
}
|
}
|
||||||
return error_log("[{$now}] {$info}\r\n{$depr}", 3, $destination);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function write($message, $destination, $apart = false)
|
||||||
|
{
|
||||||
|
//检测日志文件大小,超过配置大小则备份日志文件重新生成
|
||||||
|
if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) {
|
||||||
|
rename($destination, dirname($destination) . DS . $_SERVER['REQUEST_TIME'] . '-' . basename($destination));
|
||||||
|
$this->writed[$destination] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->writed[$destination]) && !IS_CLI) {
|
||||||
|
if (App::$debug && !$apart) {
|
||||||
|
// 获取基本信息
|
||||||
|
if (isset($_SERVER['HTTP_HOST'])) {
|
||||||
|
$current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||||
|
} else {
|
||||||
|
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$runtime = round(microtime(true) - THINK_START_TIME, 10);
|
||||||
|
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
||||||
|
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
||||||
|
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
||||||
|
$memory_str = ' [内存消耗:' . $memory_use . 'kb]';
|
||||||
|
$file_load = ' [文件加载:' . count(get_included_files()) . ']';
|
||||||
|
|
||||||
|
$message = '[ info ] ' . $current_uri . $time_str . $memory_str . $file_load . "\r\n" . $message;
|
||||||
|
}
|
||||||
|
$now = date($this->config['time_format']);
|
||||||
|
$server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '0.0.0.0';
|
||||||
|
$remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
|
||||||
|
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI';
|
||||||
|
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||||||
|
$message = "---------------------------------------------------------------\r\n[{$now}] {$server} {$remote} {$method} {$uri}\r\n" . $message;
|
||||||
|
|
||||||
|
$this->writed[$destination] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_CLI) {
|
||||||
|
$now = date($this->config['time_format']);
|
||||||
|
$message = "[{$now}]" . $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_log($message, 3, $destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,17 @@ use think\Model;
|
|||||||
class Pivot extends Model
|
class Pivot extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var Model */
|
||||||
|
public $parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @access public
|
* @access public
|
||||||
* @param array|object $data 数据
|
* @param Model $parent
|
||||||
* @param string $table 中间数据表名
|
* @param array|object $data 数据
|
||||||
|
* @param string $table 中间数据表名
|
||||||
*/
|
*/
|
||||||
public function __construct($data = [], $table = '')
|
public function __construct(Model $parent, $data = [], $table = '')
|
||||||
{
|
{
|
||||||
if (is_object($data)) {
|
if (is_object($data)) {
|
||||||
$this->data = get_object_vars($data);
|
$this->data = get_object_vars($data);
|
||||||
@@ -30,6 +34,8 @@ class Pivot extends Model
|
|||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->parent = $parent;
|
||||||
|
|
||||||
$this->table = $table;
|
$this->table = $table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ abstract class Relation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行基础查询(进执行一次)
|
* 执行基础查询(仅执行一次)
|
||||||
* @access protected
|
* @access protected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,18 +11,23 @@
|
|||||||
|
|
||||||
namespace think\model\relation;
|
namespace think\model\relation;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
use think\Loader;
|
use think\Loader;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\Pivot;
|
use think\model\Pivot;
|
||||||
use think\model\Relation;
|
use think\model\Relation;
|
||||||
|
use think\Paginator;
|
||||||
|
|
||||||
class BelongsToMany extends Relation
|
class BelongsToMany extends Relation
|
||||||
{
|
{
|
||||||
// 中间表模型
|
// 中间表表名
|
||||||
protected $middle;
|
protected $middle;
|
||||||
|
|
||||||
|
// 中间表模型
|
||||||
|
protected $pivot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @access public
|
* @access public
|
||||||
@@ -42,6 +47,64 @@ class BelongsToMany extends Relation
|
|||||||
$this->query = (new $model)->db();
|
$this->query = (new $model)->db();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置中间表模型
|
||||||
|
* @param $pivot
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function pivot($pivot)
|
||||||
|
{
|
||||||
|
$this->pivot = $pivot;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实例化中间表模型
|
||||||
|
* @param $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function newPivot($data)
|
||||||
|
{
|
||||||
|
$pivot = $this->pivot ?: '\\think\\model\\Pivot';
|
||||||
|
return new $pivot($this->parent, $data, $this->middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合成中间表模型
|
||||||
|
* @param array|Collection|Paginator $models
|
||||||
|
*/
|
||||||
|
protected function hydratePivot($models)
|
||||||
|
{
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$pivot = [];
|
||||||
|
foreach ($model->getData() as $key => $val) {
|
||||||
|
if (strpos($key, '__')) {
|
||||||
|
list($name, $attr) = explode('__', $key, 2);
|
||||||
|
if ('pivot' == $name) {
|
||||||
|
$pivot[$attr] = $val;
|
||||||
|
unset($model->$key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$model->pivot = $this->newPivot($pivot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建关联查询Query对象
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
protected function buildQuery()
|
||||||
|
{
|
||||||
|
$foreignKey = $this->foreignKey;
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$middle = $this->middle;
|
||||||
|
// 关联查询
|
||||||
|
$pk = $this->parent->getPk();
|
||||||
|
$condition['pivot.' . $localKey] = $this->parent->$pk;
|
||||||
|
return $this->belongsToManyQuery($middle, $foreignKey, $localKey, $condition);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 延迟获取关联数据
|
* 延迟获取关联数据
|
||||||
* @param string $subRelation 子关联名
|
* @param string $subRelation 子关联名
|
||||||
@@ -50,32 +113,74 @@ class BelongsToMany extends Relation
|
|||||||
*/
|
*/
|
||||||
public function getRelation($subRelation = '', $closure = null)
|
public function getRelation($subRelation = '', $closure = null)
|
||||||
{
|
{
|
||||||
$foreignKey = $this->foreignKey;
|
|
||||||
$localKey = $this->localKey;
|
|
||||||
$middle = $this->middle;
|
|
||||||
if ($closure) {
|
if ($closure) {
|
||||||
call_user_func_array($closure, [ & $this->query]);
|
call_user_func_array($closure, [& $this->query]);
|
||||||
}
|
|
||||||
// 关联查询
|
|
||||||
$pk = $this->parent->getPk();
|
|
||||||
$condition['pivot.' . $localKey] = $this->parent->$pk;
|
|
||||||
$result = $this->belongsToManyQuery($middle, $foreignKey, $localKey, $condition)->relation($subRelation)->select();
|
|
||||||
foreach ($result as $set) {
|
|
||||||
$pivot = [];
|
|
||||||
foreach ($set->getData() as $key => $val) {
|
|
||||||
if (strpos($key, '__')) {
|
|
||||||
list($name, $attr) = explode('__', $key, 2);
|
|
||||||
if ('pivot' == $name) {
|
|
||||||
$pivot[$attr] = $val;
|
|
||||||
unset($set->$key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$set->pivot = new Pivot($pivot, $this->middle);
|
|
||||||
}
|
}
|
||||||
|
$result = $this->buildQuery()->relation($subRelation)->select();
|
||||||
|
$this->hydratePivot($result);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重载select方法
|
||||||
|
* @param null $data
|
||||||
|
* @return false|\PDOStatement|string|Collection
|
||||||
|
*/
|
||||||
|
public function select($data = null)
|
||||||
|
{
|
||||||
|
$result = $this->buildQuery()->select($data);
|
||||||
|
$this->hydratePivot($result);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重载paginate方法
|
||||||
|
* @param null $listRows
|
||||||
|
* @param bool $simple
|
||||||
|
* @param array $config
|
||||||
|
* @return Paginator
|
||||||
|
*/
|
||||||
|
public function paginate($listRows = null, $simple = false, $config = [])
|
||||||
|
{
|
||||||
|
$result = $this->buildQuery()->paginate($listRows, $simple, $config);
|
||||||
|
$this->hydratePivot($result);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重载find方法
|
||||||
|
* @param null $data
|
||||||
|
* @return array|false|\PDOStatement|string|Model
|
||||||
|
*/
|
||||||
|
public function find($data = null)
|
||||||
|
{
|
||||||
|
$result = $this->buildQuery()->find($data);
|
||||||
|
$this->hydratePivot([$result]);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找多条记录 如果不存在则抛出异常
|
||||||
|
* @access public
|
||||||
|
* @param array|string|Query|\Closure $data
|
||||||
|
* @return array|\PDOStatement|string|Model
|
||||||
|
*/
|
||||||
|
public function selectOrFail($data = null)
|
||||||
|
{
|
||||||
|
return $this->failException(true)->select($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找单条记录 如果不存在则抛出异常
|
||||||
|
* @access public
|
||||||
|
* @param array|string|Query|\Closure $data
|
||||||
|
* @return array|\PDOStatement|string|Model
|
||||||
|
*/
|
||||||
|
public function findOrFail($data = null)
|
||||||
|
{
|
||||||
|
return $this->failException(true)->find($data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据关联条件查询当前模型
|
* 根据关联条件查询当前模型
|
||||||
* @access public
|
* @access public
|
||||||
@@ -95,12 +200,27 @@ class BelongsToMany extends Relation
|
|||||||
* @access public
|
* @access public
|
||||||
* @param mixed $where 查询条件(数组或者闭包)
|
* @param mixed $where 查询条件(数组或者闭包)
|
||||||
* @return Query
|
* @return Query
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function hasWhere($where = [])
|
public function hasWhere($where = [])
|
||||||
{
|
{
|
||||||
throw new Exception('relation not support: hasWhere');
|
throw new Exception('relation not support: hasWhere');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置中间表的查询条件
|
||||||
|
* @param $field
|
||||||
|
* @param null $op
|
||||||
|
* @param null $condition
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function wherePivot($field, $op = null, $condition = null)
|
||||||
|
{
|
||||||
|
$field = 'pivot.' . $field;
|
||||||
|
$this->query->where($field, $op, $condition);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询(数据集)
|
* 预载入关联查询(数据集)
|
||||||
* @access public
|
* @access public
|
||||||
@@ -230,7 +350,7 @@ class BelongsToMany extends Relation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$set->pivot = new Pivot($pivot, $this->middle);
|
$set->pivot = $this->newPivot($pivot);
|
||||||
$data[$pivot[$this->localKey]][] = $set;
|
$data[$pivot[$this->localKey]][] = $set;
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
@@ -250,10 +370,14 @@ class BelongsToMany extends Relation
|
|||||||
// 关联查询封装
|
// 关联查询封装
|
||||||
$tableName = $this->query->getTable();
|
$tableName = $this->query->getTable();
|
||||||
$relationFk = $this->query->getPk();
|
$relationFk = $this->query->getPk();
|
||||||
return $this->query->field($tableName . '.*')
|
$query = $this->query->field($tableName . '.*')
|
||||||
->field(true, false, $table, 'pivot', 'pivot__')
|
->field(true, false, $table, 'pivot', 'pivot__');
|
||||||
->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)
|
|
||||||
->where($condition);
|
if (empty($this->baseQuery)) {
|
||||||
|
$query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)
|
||||||
|
->where($condition);
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -327,7 +451,7 @@ class BelongsToMany extends Relation
|
|||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$pivot[$this->foreignKey] = $id;
|
$pivot[$this->foreignKey] = $id;
|
||||||
$this->query->table($this->middle)->insert($pivot, true);
|
$this->query->table($this->middle)->insert($pivot, true);
|
||||||
$result[] = new Pivot($pivot, $this->middle);
|
$result[] = $this->newPivot($pivot);
|
||||||
}
|
}
|
||||||
if (count($result) == 1) {
|
if (count($result) == 1) {
|
||||||
// 返回中间表模型对象
|
// 返回中间表模型对象
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ class HasMany extends Relation
|
|||||||
* 保存(新增)当前关联数据对象
|
* 保存(新增)当前关联数据对象
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
||||||
* @return integer
|
* @return Model|false
|
||||||
*/
|
*/
|
||||||
public function save($data)
|
public function save($data)
|
||||||
{
|
{
|
||||||
@@ -191,9 +191,9 @@ class HasMany extends Relation
|
|||||||
$data = $data->getData();
|
$data = $data->getData();
|
||||||
}
|
}
|
||||||
// 保存关联表数据
|
// 保存关联表数据
|
||||||
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
|
||||||
$model = new $this->model;
|
$model = new $this->model;
|
||||||
return $model->save($data);
|
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
||||||
|
return $model->save($data) ? $model : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class MorphMany extends Relation
|
|||||||
* 保存(新增)当前关联数据对象
|
* 保存(新增)当前关联数据对象
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
||||||
* @return integer
|
* @return Model|false
|
||||||
*/
|
*/
|
||||||
public function save($data)
|
public function save($data)
|
||||||
{
|
{
|
||||||
@@ -225,10 +225,10 @@ class MorphMany extends Relation
|
|||||||
// 保存关联表数据
|
// 保存关联表数据
|
||||||
$pk = $this->parent->getPk();
|
$pk = $this->parent->getPk();
|
||||||
|
|
||||||
|
$model = new $this->model;
|
||||||
$data[$this->morphKey] = $this->parent->$pk;
|
$data[$this->morphKey] = $this->parent->$pk;
|
||||||
$data[$this->morphType] = $this->type;
|
$data[$this->morphType] = $this->type;
|
||||||
$model = new $this->model;
|
return $model->save($data) ? $model : false;
|
||||||
return $model->save($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -114,6 +114,16 @@ class MorphTo extends Relation
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除关联查询参数
|
||||||
|
* @access public
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function removeOption()
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询
|
* 预载入关联查询
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ abstract class OneToOne extends Relation
|
|||||||
$field = true;
|
$field = true;
|
||||||
}
|
}
|
||||||
$query->field($field, false, $table, $alias);
|
$query->field($field, false, $table, $alias);
|
||||||
|
$field = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预载入封装
|
// 预载入封装
|
||||||
@@ -82,7 +83,7 @@ abstract class OneToOne extends Relation
|
|||||||
|
|
||||||
if ($closure) {
|
if ($closure) {
|
||||||
// 执行闭包查询
|
// 执行闭包查询
|
||||||
call_user_func_array($closure, [& $query]);
|
call_user_func_array($closure, [ & $query]);
|
||||||
// 使用withField指定获取关联的字段,如
|
// 使用withField指定获取关联的字段,如
|
||||||
// $query->where(['id'=>1])->withField('id,name');
|
// $query->where(['id'=>1])->withField('id,name');
|
||||||
if ($query->getOptions('with_field')) {
|
if ($query->getOptions('with_field')) {
|
||||||
@@ -91,10 +92,8 @@ abstract class OneToOne extends Relation
|
|||||||
}
|
}
|
||||||
} elseif (isset($this->option['field'])) {
|
} elseif (isset($this->option['field'])) {
|
||||||
$field = $this->option['field'];
|
$field = $this->option['field'];
|
||||||
} else {
|
|
||||||
$field = true;
|
|
||||||
}
|
}
|
||||||
$query->field($field, false, $joinTable, $joinAlias, $relation . '__');
|
$query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,17 +162,17 @@ abstract class OneToOne extends Relation
|
|||||||
* 保存(新增)当前关联数据对象
|
* 保存(新增)当前关联数据对象
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
||||||
* @return integer
|
* @return Model|false
|
||||||
*/
|
*/
|
||||||
public function save($data)
|
public function save($data)
|
||||||
{
|
{
|
||||||
if ($data instanceof Model) {
|
if ($data instanceof Model) {
|
||||||
$data = $data->getData();
|
$data = $data->getData();
|
||||||
}
|
}
|
||||||
|
$model = new $this->model;
|
||||||
// 保存关联表数据
|
// 保存关联表数据
|
||||||
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
||||||
$model = new $this->model;
|
return $model->save($data) ? $model : false;
|
||||||
return $model->save($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,7 +194,6 @@ abstract class OneToOne extends Relation
|
|||||||
*/
|
*/
|
||||||
public function getEagerlyType()
|
public function getEagerlyType()
|
||||||
{
|
{
|
||||||
$this->removeOption();
|
|
||||||
return $this->eagerlyType;
|
return $this->eagerlyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +288,7 @@ abstract class OneToOne extends Relation
|
|||||||
{
|
{
|
||||||
// 预载入关联查询 支持嵌套预载入
|
// 预载入关联查询 支持嵌套预载入
|
||||||
if ($closure) {
|
if ($closure) {
|
||||||
call_user_func_array($closure, [& $model]);
|
call_user_func_array($closure, [ & $model]);
|
||||||
if ($field = $model->getOptions('with_field')) {
|
if ($field = $model->getOptions('with_field')) {
|
||||||
$model->field($field)->removeOption('with_field');
|
$model->field($field)->removeOption('with_field');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class TagLib
|
|||||||
* @param boolean $close 是否为闭合标签
|
* @param boolean $close 是否为闭合标签
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getRegex($tags, $close)
|
public function getRegex($tags, $close)
|
||||||
{
|
{
|
||||||
$begin = $this->tpl->config('taglib_begin');
|
$begin = $this->tpl->config('taglib_begin');
|
||||||
$end = $this->tpl->config('taglib_end');
|
$end = $this->tpl->config('taglib_end');
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ trait SoftDelete
|
|||||||
{
|
{
|
||||||
$model = new static();
|
$model = new static();
|
||||||
$field = $model->getDeleteTimeField(true);
|
$field = $model->getDeleteTimeField(true);
|
||||||
return $model->db(false)->removeWhereField($field);
|
return $model->db(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +42,8 @@ trait SoftDelete
|
|||||||
{
|
{
|
||||||
$model = new static();
|
$model = new static();
|
||||||
$field = $model->getDeleteTimeField(true);
|
$field = $model->getDeleteTimeField(true);
|
||||||
return $model->db(false)->whereNotNull($field);
|
return $model->db(false)
|
||||||
|
->useSoftDelete($field, ['not null', '']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,12 +113,14 @@ trait SoftDelete
|
|||||||
{
|
{
|
||||||
$name = $this->getDeleteTimeField();
|
$name = $this->getDeleteTimeField();
|
||||||
if (empty($where)) {
|
if (empty($where)) {
|
||||||
$pk = $this->getPk();
|
$pk = $this->getPk();
|
||||||
$where[$pk] = $this->getData($pk);
|
$where[$pk] = $this->getData($pk);
|
||||||
$where[$name] = ['not null', ''];
|
|
||||||
}
|
}
|
||||||
// 恢复删除
|
// 恢复删除
|
||||||
return $this->db(false)->removeWhereField($this->getDeleteTimeField(true))->where($where)->update([$name => null]);
|
return $this->db(false)
|
||||||
|
->useSoftDelete($name, ['not null', ''])
|
||||||
|
->where($where)
|
||||||
|
->update([$name => null]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +132,7 @@ trait SoftDelete
|
|||||||
protected function base($query)
|
protected function base($query)
|
||||||
{
|
{
|
||||||
$field = $this->getDeleteTimeField(true);
|
$field = $this->getDeleteTimeField(true);
|
||||||
$query->whereNull($field);
|
$query->useSoftDelete($field);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user