内核更新
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
// | Author: liu21st <liu21st@gmail.com>
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
define('THINK_VERSION', '5.0.4beta');
|
define('THINK_VERSION', '5.0.5beta');
|
||||||
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');
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ return [
|
|||||||
// 数据库连接DSN配置
|
// 数据库连接DSN配置
|
||||||
'dsn' => '',
|
'dsn' => '',
|
||||||
// 服务器地址
|
// 服务器地址
|
||||||
'hostname' => 'localhost',
|
'hostname' => '127.0.0.1',
|
||||||
// 数据库名
|
// 数据库名
|
||||||
'database' => '',
|
'database' => '',
|
||||||
// 数据库用户名
|
// 数据库用户名
|
||||||
@@ -262,8 +262,18 @@ return [
|
|||||||
'slave_no' => '',
|
'slave_no' => '',
|
||||||
// 是否严格检查字段是否存在
|
// 是否严格检查字段是否存在
|
||||||
'fields_strict' => true,
|
'fields_strict' => true,
|
||||||
|
// 数据集返回类型
|
||||||
|
'resultset_type' => 'array',
|
||||||
// 自动写入时间戳字段
|
// 自动写入时间戳字段
|
||||||
'auto_timestamp' => false,
|
'auto_timestamp' => false,
|
||||||
|
// 时间字段取出后的默认时间格式
|
||||||
|
'datetime_format' => 'Y-m-d H:i:s',
|
||||||
|
// 是否需要进行SQL性能分析
|
||||||
|
'sql_explain' => false,
|
||||||
|
// Builder类
|
||||||
|
'builder' => '',
|
||||||
|
// Query类
|
||||||
|
'query' => '\\think\\db\\Query',
|
||||||
],
|
],
|
||||||
|
|
||||||
//分页配置
|
//分页配置
|
||||||
|
|||||||
@@ -62,4 +62,5 @@ return [
|
|||||||
'sae mc write error' => 'SAE mc 写入错误',
|
'sae mc write error' => 'SAE mc 写入错误',
|
||||||
'route name not exists' => '路由标识不存在(或参数不够)',
|
'route name not exists' => '路由标识不存在(或参数不够)',
|
||||||
'invalid request' => '非法请求',
|
'invalid request' => '非法请求',
|
||||||
|
'bind attr has exists' => '模型的属性已经存在',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -11,19 +11,9 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Config;
|
|
||||||
use think\Env;
|
|
||||||
use think\Exception;
|
|
||||||
use think\exception\HttpException;
|
use think\exception\HttpException;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
use think\exception\RouteNotFoundException;
|
use think\exception\RouteNotFoundException;
|
||||||
use think\Hook;
|
|
||||||
use think\Lang;
|
|
||||||
use think\Loader;
|
|
||||||
use think\Log;
|
|
||||||
use think\Request;
|
|
||||||
use think\Response;
|
|
||||||
use think\Route;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App 应用管理
|
* App 应用管理
|
||||||
@@ -141,13 +131,13 @@ class App
|
|||||||
break;
|
break;
|
||||||
case 'controller':
|
case 'controller':
|
||||||
// 执行控制器操作
|
// 执行控制器操作
|
||||||
$vars = Request::instance()->param();
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
$data = Loader::action($dispatch['controller'], array_merge($vars, $dispatch['var']));
|
$data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);
|
||||||
break;
|
break;
|
||||||
case 'method':
|
case 'method':
|
||||||
// 执行回调方法
|
// 执行回调方法
|
||||||
$vars = Request::instance()->param();
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
$data = self::invokeMethod($dispatch['method'], array_merge($vars, $dispatch['var']));
|
$data = self::invokeMethod($dispatch['method'], $vars);
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function':
|
||||||
// 执行闭包
|
// 执行闭包
|
||||||
@@ -304,8 +294,6 @@ class App
|
|||||||
throw new \InvalidArgumentException('method param miss:' . $name);
|
throw new \InvalidArgumentException('method param miss:' . $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 全局过滤
|
|
||||||
array_walk_recursive($args, [Request::instance(), 'filterExp']);
|
|
||||||
}
|
}
|
||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
use think\cache\Driver;
|
||||||
|
|
||||||
class Cache
|
class Cache
|
||||||
{
|
{
|
||||||
@@ -31,7 +31,7 @@ class Cache
|
|||||||
* @access public
|
* @access public
|
||||||
* @param array $options 配置数组
|
* @param array $options 配置数组
|
||||||
* @param bool|string $name 缓存连接标识 true 强制重新连接
|
* @param bool|string $name 缓存连接标识 true 强制重新连接
|
||||||
* @return \think\cache\Driver
|
* @return Driver
|
||||||
*/
|
*/
|
||||||
public static function connect(array $options = [], $name = false)
|
public static function connect(array $options = [], $name = false)
|
||||||
{
|
{
|
||||||
@@ -79,7 +79,7 @@ class Cache
|
|||||||
* 切换缓存类型 需要配置 cache.type 为 complex
|
* 切换缓存类型 需要配置 cache.type 为 complex
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name 缓存标识
|
* @param string $name 缓存标识
|
||||||
* @return \think\cache\Driver
|
* @return Driver
|
||||||
*/
|
*/
|
||||||
public static function store($name)
|
public static function store($name)
|
||||||
{
|
{
|
||||||
@@ -220,7 +220,7 @@ class Cache
|
|||||||
* @param string $name 标签名
|
* @param string $name 标签名
|
||||||
* @param string|array $keys 缓存标识
|
* @param string|array $keys 缓存标识
|
||||||
* @param bool $overlay 是否覆盖
|
* @param bool $overlay 是否覆盖
|
||||||
* @return \think\cache\Driver
|
* @return Driver
|
||||||
*/
|
*/
|
||||||
public static function tag($name, $keys = null, $overlay = false)
|
public static function tag($name, $keys = null, $overlay = false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace think;
|
|||||||
|
|
||||||
\think\Loader::import('controller/Jump', TRAIT_PATH, EXT);
|
\think\Loader::import('controller/Jump', TRAIT_PATH, EXT);
|
||||||
|
|
||||||
use think\Exception;
|
|
||||||
use think\exception\ValidateException;
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
class Controller
|
class Controller
|
||||||
|
|||||||
@@ -99,6 +99,22 @@ class Cookie
|
|||||||
$_COOKIE[$name] = $value;
|
$_COOKIE[$name] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 永久保存Cookie数据
|
||||||
|
* @param string $name cookie名称
|
||||||
|
* @param mixed $value cookie值
|
||||||
|
* @param mixed $option 可选参数 可能会是 null|integer|string
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function forever($name, $value = '', $option = null)
|
||||||
|
{
|
||||||
|
if (is_null($option) || is_numeric($option)) {
|
||||||
|
$option = [];
|
||||||
|
}
|
||||||
|
$option['expire'] = 315360000;
|
||||||
|
self::set($name, $value, $option);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断Cookie数据
|
* 判断Cookie数据
|
||||||
* @param string $name cookie名称
|
* @param string $name cookie名称
|
||||||
@@ -133,7 +149,7 @@ class Cookie
|
|||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
use think\db\Connection;
|
||||||
use think\Collection;
|
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\paginator\Collection as PaginatorCollection;
|
use think\paginator\Collection as PaginatorCollection;
|
||||||
|
|
||||||
@@ -62,7 +61,7 @@ class Db
|
|||||||
* @access public
|
* @access public
|
||||||
* @param mixed $config 连接配置
|
* @param mixed $config 连接配置
|
||||||
* @param bool|string $name 连接标识 true 强制重新连接
|
* @param bool|string $name 连接标识 true 强制重新连接
|
||||||
* @return \think\db\Connection
|
* @return Connection
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function connect($config = [], $name = false)
|
public static function connect($config = [], $name = false)
|
||||||
|
|||||||
@@ -11,11 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Config;
|
|
||||||
use think\exception\ClassNotFoundException;
|
use think\exception\ClassNotFoundException;
|
||||||
use think\Log;
|
|
||||||
use think\Request;
|
|
||||||
use think\Response;
|
|
||||||
use think\response\Redirect;
|
use think\response\Redirect;
|
||||||
|
|
||||||
class Debug
|
class Debug
|
||||||
@@ -179,7 +175,7 @@ class Debug
|
|||||||
}
|
}
|
||||||
if ($echo) {
|
if ($echo) {
|
||||||
echo($output);
|
echo($output);
|
||||||
return null;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@@ -12,10 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
|
||||||
use think\Debug;
|
|
||||||
use think\Log;
|
|
||||||
|
|
||||||
class Hook
|
class Hook
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -69,7 +64,8 @@ class Hook
|
|||||||
*/
|
*/
|
||||||
public static function get($tag = '')
|
public static function get($tag = '')
|
||||||
{
|
{
|
||||||
if (empty($tag)) {//获取全部的插件信息
|
if (empty($tag)) {
|
||||||
|
//获取全部的插件信息
|
||||||
return self::$tags;
|
return self::$tags;
|
||||||
} else {
|
} else {
|
||||||
return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
|
return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
|
||||||
@@ -90,7 +86,8 @@ class Hook
|
|||||||
$tags = static::get($tag);
|
$tags = static::get($tag);
|
||||||
foreach ($tags as $key => $name) {
|
foreach ($tags as $key => $name) {
|
||||||
$results[$key] = self::exec($name, $tag, $params, $extra);
|
$results[$key] = self::exec($name, $tag, $params, $extra);
|
||||||
if (false === $results[$key]) {// 如果返回false 则中断行为执行
|
if (false === $results[$key]) {
|
||||||
|
// 如果返回false 则中断行为执行
|
||||||
break;
|
break;
|
||||||
} elseif (!is_null($results[$key]) && $once) {
|
} elseif (!is_null($results[$key]) && $once) {
|
||||||
break;
|
break;
|
||||||
@@ -110,15 +107,24 @@ class Hook
|
|||||||
public static function exec($class, $tag = '', &$params = null, $extra = null)
|
public static function exec($class, $tag = '', &$params = null, $extra = null)
|
||||||
{
|
{
|
||||||
App::$debug && Debug::remark('behavior_start', 'time');
|
App::$debug && Debug::remark('behavior_start', 'time');
|
||||||
if (is_callable($class)) {
|
$method = Loader::parseName($tag, 1, false);
|
||||||
|
if ($class instanceof \Closure) {
|
||||||
$result = call_user_func_array($class, [ & $params, $extra]);
|
$result = call_user_func_array($class, [ & $params, $extra]);
|
||||||
$class = 'Closure';
|
$class = 'Closure';
|
||||||
|
} elseif (is_array($class)) {
|
||||||
|
list($class, $method) = $class;
|
||||||
|
|
||||||
|
$result = (new $class())->$method($params, $extra);
|
||||||
|
$class = $class . '->' . $method;
|
||||||
} elseif (is_object($class)) {
|
} elseif (is_object($class)) {
|
||||||
$result = call_user_func_array([$class, $tag], [ & $params, $extra]);
|
$result = $class->$method($params, $extra);
|
||||||
$class = get_class($class);
|
$class = get_class($class);
|
||||||
|
} elseif (strpos($class, '::')) {
|
||||||
|
$result = call_user_func_array($class, [ & $params, $extra]);
|
||||||
} else {
|
} else {
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params, $extra) : $obj->run($params, $extra);
|
$method = ($tag && is_callable([$obj, $method])) ? $method : 'run';
|
||||||
|
$result = $obj->$method($params, $extra);
|
||||||
}
|
}
|
||||||
if (App::$debug) {
|
if (App::$debug) {
|
||||||
Debug::remark('behavior_end', 'time');
|
Debug::remark('behavior_end', 'time');
|
||||||
|
|||||||
@@ -11,10 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
|
||||||
use think\Cookie;
|
|
||||||
use think\Log;
|
|
||||||
|
|
||||||
class Lang
|
class Lang
|
||||||
{
|
{
|
||||||
// 语言数据
|
// 语言数据
|
||||||
|
|||||||
@@ -369,12 +369,16 @@ class Loader
|
|||||||
if (isset(self::$instance[$guid])) {
|
if (isset(self::$instance[$guid])) {
|
||||||
return self::$instance[$guid];
|
return self::$instance[$guid];
|
||||||
}
|
}
|
||||||
|
if (strpos($name, '\\')) {
|
||||||
|
$class = $name;
|
||||||
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name, 2);
|
list($module, $name) = explode('/', $name, 2);
|
||||||
} else {
|
} else {
|
||||||
$module = Request::instance()->module();
|
$module = Request::instance()->module();
|
||||||
}
|
}
|
||||||
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
||||||
|
}
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$model = new $class();
|
$model = new $class();
|
||||||
} else {
|
} else {
|
||||||
@@ -400,12 +404,16 @@ 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, '\\')) {
|
||||||
|
$class = $name;
|
||||||
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name);
|
list($module, $name) = explode('/', $name);
|
||||||
} else {
|
} else {
|
||||||
$module = Request::instance()->module();
|
$module = Request::instance()->module();
|
||||||
}
|
}
|
||||||
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
||||||
|
}
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
return App::invokeClass($class);
|
return App::invokeClass($class);
|
||||||
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
|
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
|
||||||
@@ -432,12 +440,16 @@ class Loader
|
|||||||
if (isset(self::$instance[$guid])) {
|
if (isset(self::$instance[$guid])) {
|
||||||
return self::$instance[$guid];
|
return self::$instance[$guid];
|
||||||
}
|
}
|
||||||
|
if (strpos($name, '\\')) {
|
||||||
|
$class = $name;
|
||||||
|
} else {
|
||||||
if (strpos($name, '/')) {
|
if (strpos($name, '/')) {
|
||||||
list($module, $name) = explode('/', $name);
|
list($module, $name) = explode('/', $name);
|
||||||
} else {
|
} else {
|
||||||
$module = Request::instance()->module();
|
$module = Request::instance()->module();
|
||||||
}
|
}
|
||||||
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
||||||
|
}
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$validate = new $class;
|
$validate = new $class;
|
||||||
} else {
|
} else {
|
||||||
@@ -494,14 +506,16 @@ class Loader
|
|||||||
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
||||||
* @param string $name 字符串
|
* @param string $name 字符串
|
||||||
* @param integer $type 转换类型
|
* @param integer $type 转换类型
|
||||||
|
* @param bool $ucfirst 首字母是否大写(驼峰规则)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function parseName($name, $type = 0)
|
public static function parseName($name, $type = 0, $ucfirst = true)
|
||||||
{
|
{
|
||||||
if ($type) {
|
if ($type) {
|
||||||
return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
$name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
||||||
return strtoupper($match[1]);
|
return strtoupper($match[1]);
|
||||||
}, $name));
|
}, $name);
|
||||||
|
return $ucfirst ? ucfirst($name) : lcfirst($name);
|
||||||
} else {
|
} else {
|
||||||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,8 @@
|
|||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use think\Cache;
|
|
||||||
use think\Collection;
|
|
||||||
use think\Config;
|
|
||||||
use think\Db;
|
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\Exception;
|
|
||||||
use think\Exception\ValidateException;
|
use think\Exception\ValidateException;
|
||||||
use think\Loader;
|
|
||||||
use think\model\Relation;
|
use think\model\Relation;
|
||||||
use think\model\relation\BelongsTo;
|
use think\model\relation\BelongsTo;
|
||||||
use think\model\relation\BelongsToMany;
|
use think\model\relation\BelongsToMany;
|
||||||
@@ -96,7 +90,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
// 更新时间字段
|
// 更新时间字段
|
||||||
protected $updateTime = 'update_time';
|
protected $updateTime = 'update_time';
|
||||||
// 时间字段取出后的默认时间格式
|
// 时间字段取出后的默认时间格式
|
||||||
protected $dateFormat = 'Y-m-d H:i:s';
|
protected $dateFormat;
|
||||||
// 字段类型或者格式转换
|
// 字段类型或者格式转换
|
||||||
protected $type = [];
|
protected $type = [];
|
||||||
// 是否为更新数据
|
// 是否为更新数据
|
||||||
@@ -151,7 +145,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
|
|
||||||
if (is_null($this->autoWriteTimestamp)) {
|
if (is_null($this->autoWriteTimestamp)) {
|
||||||
// 自动写入时间戳
|
// 自动写入时间戳
|
||||||
$this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp');
|
$this->autoWriteTimestamp = $this->db(false)->getConfig('auto_timestamp');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($this->dateFormat)) {
|
||||||
|
// 设置时间戳格式
|
||||||
|
$this->dateFormat = $this->db(false)->getConfig('datetime_format');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行初始化操作
|
// 执行初始化操作
|
||||||
@@ -169,13 +168,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$model = $this->class;
|
$model = $this->class;
|
||||||
if (!isset(self::$links[$model])) {
|
if (!isset(self::$links[$model])) {
|
||||||
// 合并数据库配置
|
// 合并数据库配置
|
||||||
|
if (!empty($this->connection)) {
|
||||||
if (is_array($this->connection)) {
|
if (is_array($this->connection)) {
|
||||||
$connection = array_merge(Config::get('database'), $this->connection);
|
$connection = array_merge(Config::get('database'), $this->connection);
|
||||||
} else {
|
} else {
|
||||||
$connection = $this->connection;
|
$connection = $this->connection;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$connection = [];
|
||||||
|
}
|
||||||
// 设置当前模型 确保查询返回模型对象
|
// 设置当前模型 确保查询返回模型对象
|
||||||
$query = Db::connect($connection)->model($model, $this->query);
|
$query = Db::connect($connection)->getQuery($model, $this->query);
|
||||||
|
|
||||||
// 设置当前数据表和模型名
|
// 设置当前数据表和模型名
|
||||||
if (!empty($this->table)) {
|
if (!empty($this->table)) {
|
||||||
@@ -319,21 +322,40 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
case 'datetime':
|
case 'datetime':
|
||||||
case 'date':
|
case 'date':
|
||||||
$format = !empty($param) ? $param : $this->dateFormat;
|
$format = !empty($param) ? $param : $this->dateFormat;
|
||||||
$value = date($format, $_SERVER['REQUEST_TIME']);
|
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $format);
|
||||||
break;
|
break;
|
||||||
case 'timestamp':
|
case 'timestamp':
|
||||||
case 'int':
|
case 'integer':
|
||||||
|
default:
|
||||||
$value = $_SERVER['REQUEST_TIME'];
|
$value = $_SERVER['REQUEST_TIME'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
||||||
$value = date($this->dateFormat, $_SERVER['REQUEST_TIME']);
|
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $this->dateFormat);
|
||||||
} else {
|
} else {
|
||||||
$value = $_SERVER['REQUEST_TIME'];
|
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $this->dateFormat, true);
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间日期字段格式化处理
|
||||||
|
* @access public
|
||||||
|
* @param mixed $time 时间日期表达式
|
||||||
|
* @param mixed $format 日期格式
|
||||||
|
* @param bool $timestamp 是否进行时间戳转换
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function formatDateTime($time, $format, $timestamp = false)
|
||||||
|
{
|
||||||
|
if (false !== strpos($format, '\\')) {
|
||||||
|
$time = new $format($time);
|
||||||
|
} elseif (!$timestamp) {
|
||||||
|
$time = date($format, $time);
|
||||||
|
}
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据写入 类型转换
|
* 数据写入 类型转换
|
||||||
* @access public
|
* @access public
|
||||||
@@ -369,7 +391,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
break;
|
break;
|
||||||
case 'datetime':
|
case 'datetime':
|
||||||
$format = !empty($param) ? $param : $this->dateFormat;
|
$format = !empty($param) ? $param : $this->dateFormat;
|
||||||
$value = date($format, is_numeric($value) ? $value : strtotime($value));
|
$value = is_numeric($value) ? $value : strtotime($value);
|
||||||
|
$value = $this->formatDateTime($value, $format);
|
||||||
break;
|
break;
|
||||||
case 'object':
|
case 'object':
|
||||||
if (is_object($value)) {
|
if (is_object($value)) {
|
||||||
@@ -385,6 +408,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
case 'serialize':
|
case 'serialize':
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -414,7 +438,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
// 类型转换
|
// 类型转换
|
||||||
$value = $this->readTransform($value, $this->type[$name]);
|
$value = $this->readTransform($value, $this->type[$name]);
|
||||||
} elseif ($notFound) {
|
} elseif ($notFound) {
|
||||||
$method = Loader::parseName($name, 1);
|
$method = Loader::parseName($name, 1, false);
|
||||||
if (method_exists($this, $method) && $this->$method() instanceof Relation) {
|
if (method_exists($this, $method) && $this->$method() instanceof Relation) {
|
||||||
// 不存在该字段 获取关联数据
|
// 不存在该字段 获取关联数据
|
||||||
$value = $this->$method()->getRelation();
|
$value = $this->$method()->getRelation();
|
||||||
@@ -458,13 +482,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
case 'timestamp':
|
case 'timestamp':
|
||||||
if (!is_null($value)) {
|
if (!is_null($value)) {
|
||||||
$format = !empty($param) ? $param : $this->dateFormat;
|
$format = !empty($param) ? $param : $this->dateFormat;
|
||||||
$value = date($format, $value);
|
$value = $this->formatDateTime($value, $format);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'datetime':
|
case 'datetime':
|
||||||
if (!is_null($value)) {
|
if (!is_null($value)) {
|
||||||
$format = !empty($param) ? $param : $this->dateFormat;
|
$format = !empty($param) ? $param : $this->dateFormat;
|
||||||
$value = date($format, strtotime($value));
|
$value = $this->formatDateTime(strtotime($value), $format);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'json':
|
case 'json':
|
||||||
@@ -479,6 +503,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
case 'serialize':
|
case 'serialize':
|
||||||
$value = unserialize($value);
|
$value = unserialize($value);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if (false !== strpos($type, '\\')) {
|
||||||
|
// 对象类型
|
||||||
|
$value = new $type($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -496,6 +525,32 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置附加关联对象的属性
|
||||||
|
* @access public
|
||||||
|
* @param string $relation 关联方法
|
||||||
|
* @param string|array $append 追加属性名
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function appendRelationAttr($relation, $append)
|
||||||
|
{
|
||||||
|
if (is_string($append)) {
|
||||||
|
$append = explode(',', $append);
|
||||||
|
}
|
||||||
|
$model = $this->getAttr($relation);
|
||||||
|
if ($model instanceof Model) {
|
||||||
|
foreach ($append as $key => $attr) {
|
||||||
|
$key = is_numeric($key) ? $attr : $key;
|
||||||
|
if ($this->__isset($key)) {
|
||||||
|
throw new Exception('bind attr has exists:' . $key);
|
||||||
|
} else {
|
||||||
|
$this->setAttr($key, $model->$attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置需要隐藏的输出属性
|
* 设置需要隐藏的输出属性
|
||||||
* @access public
|
* @access public
|
||||||
@@ -603,10 +658,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
public function getPk($name = '')
|
public function getPk($name = '')
|
||||||
{
|
{
|
||||||
if (!empty($name)) {
|
if (!empty($name)) {
|
||||||
$table = $this->db()->getTable($name);
|
$table = $this->db(false)->getTable($name);
|
||||||
return $this->db()->getPk($table);
|
return $this->db(false)->getPk($table);
|
||||||
} elseif (empty($this->pk)) {
|
} elseif (empty($this->pk)) {
|
||||||
$this->pk = $this->db()->getPk();
|
$this->pk = $this->db(false)->getPk();
|
||||||
}
|
}
|
||||||
return $this->pk;
|
return $this->pk;
|
||||||
}
|
}
|
||||||
@@ -665,7 +720,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->autoCompleteData($this->auto);
|
$this->autoCompleteData($this->auto);
|
||||||
|
|
||||||
// 自动写入更新时间
|
// 自动写入更新时间
|
||||||
if ($this->autoWriteTimestamp && $this->updateTime) {
|
if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) {
|
||||||
$this->setAttr($this->updateTime, null);
|
$this->setAttr($this->updateTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,7 +777,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->autoCompleteData($this->insert);
|
$this->autoCompleteData($this->insert);
|
||||||
|
|
||||||
// 自动写入创建时间
|
// 自动写入创建时间
|
||||||
if ($this->autoWriteTimestamp && $this->createTime) {
|
if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) {
|
||||||
$this->setAttr($this->createTime, null);
|
$this->setAttr($this->createTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,7 +858,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
public function allowField($field)
|
public function allowField($field)
|
||||||
{
|
{
|
||||||
if (true === $field) {
|
if (true === $field) {
|
||||||
$field = $this->db()->getTableInfo('', 'fields');
|
$field = $this->db(false)->getTableInfo('', 'fields');
|
||||||
}
|
}
|
||||||
$this->field = $field;
|
$this->field = $field;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -1157,7 +1212,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
public static function useGlobalScope($use)
|
public static function useGlobalScope($use)
|
||||||
{
|
{
|
||||||
$model = new static();
|
$model = new static();
|
||||||
self::$db = $model->db($use);
|
static::$db = $model->db($use);
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1245,6 +1300,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
if (strpos($relation, '.')) {
|
if (strpos($relation, '.')) {
|
||||||
list($relation, $subRelation) = explode('.', $relation);
|
list($relation, $subRelation) = explode('.', $relation);
|
||||||
}
|
}
|
||||||
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
$this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $class);
|
$this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1271,10 +1327,34 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
if (strpos($relation, '.')) {
|
if (strpos($relation, '.')) {
|
||||||
list($relation, $subRelation) = explode('.', $relation);
|
list($relation, $subRelation) = explode('.', $relation);
|
||||||
}
|
}
|
||||||
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
$this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure, $class);
|
$this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure, $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param string|array $relation 关联名
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function relationCount(&$result, $relation)
|
||||||
|
{
|
||||||
|
$relations = is_string($relation) ? explode(',', $relation) : $relation;
|
||||||
|
|
||||||
|
foreach ($relations as $key => $relation) {
|
||||||
|
$closure = false;
|
||||||
|
if ($relation instanceof \Closure) {
|
||||||
|
$closure = $relation;
|
||||||
|
$relation = $key;
|
||||||
|
}
|
||||||
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
|
$count = $this->$relation()->relationCount($result, $closure);
|
||||||
|
$result->setAttr(Loader::parseName($relation) . '_count', $count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAS ONE 关联定义
|
* HAS ONE 关联定义
|
||||||
* @access public
|
* @access public
|
||||||
@@ -1369,7 +1449,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
// 记录当前关联信息
|
// 记录当前关联信息
|
||||||
$model = $this->parseModel($model);
|
$model = $this->parseModel($model);
|
||||||
$name = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
$name = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
||||||
$table = $table ?: $this->db()->getTable(Loader::parseName($this->name) . '_' . $name);
|
$table = $table ?: $this->db(false)->getTable(Loader::parseName($this->name) . '_' . $name);
|
||||||
$foreignKey = $foreignKey ?: $name . '_id';
|
$foreignKey = $foreignKey ?: $name . '_id';
|
||||||
$localKey = $localKey ?: Loader::parseName($this->name) . '_id';
|
$localKey = $localKey ?: Loader::parseName($this->name) . '_id';
|
||||||
return new BelongsToMany($this, $model, $table, $foreignKey, $localKey, $alias);
|
return new BelongsToMany($this, $model, $table, $foreignKey, $localKey, $alias);
|
||||||
@@ -1426,7 +1506,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
|
|
||||||
public function __call($method, $args)
|
public function __call($method, $args)
|
||||||
{
|
{
|
||||||
|
if (isset(static::$db)) {
|
||||||
|
$query = static::$db;
|
||||||
|
static::$db = null;
|
||||||
|
} else {
|
||||||
$query = $this->db();
|
$query = $this->db();
|
||||||
|
}
|
||||||
|
|
||||||
if (method_exists($this, 'scope' . $method)) {
|
if (method_exists($this, 'scope' . $method)) {
|
||||||
// 动态调用命名范围
|
// 动态调用命名范围
|
||||||
$method = 'scope' . $method;
|
$method = 'scope' . $method;
|
||||||
@@ -1442,6 +1528,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
{
|
{
|
||||||
if (isset(static::$db)) {
|
if (isset(static::$db)) {
|
||||||
$query = static::$db;
|
$query = static::$db;
|
||||||
|
static::$db = null;
|
||||||
} else {
|
} else {
|
||||||
$query = (new static())->db();
|
$query = (new static())->db();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\paginator\Collection as PaginatorCollection;
|
use think\paginator\Collection as PaginatorCollection;
|
||||||
use think\Request;
|
|
||||||
|
|
||||||
abstract class Paginator
|
abstract class Paginator
|
||||||
{
|
{
|
||||||
@@ -42,14 +41,14 @@ abstract class Paginator
|
|||||||
'var_page' => 'page',
|
'var_page' => 'page',
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'query' => [],
|
'query' => [],
|
||||||
'fragment' => ''
|
'fragment' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])
|
protected function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])
|
||||||
{
|
{
|
||||||
$this->options = array_merge($this->options, $options);
|
$this->options = array_merge($this->options, $options);
|
||||||
|
|
||||||
$this->options['path'] = $this->options['path'] != '/' ? rtrim($this->options['path'], '/') : $this->options['path'];
|
$this->options['path'] = '/' != $this->options['path'] ? rtrim($this->options['path'], '/') : $this->options['path'];
|
||||||
|
|
||||||
$this->simple = $simple;
|
$this->simple = $simple;
|
||||||
$this->listRows = $listRows;
|
$this->listRows = $listRows;
|
||||||
@@ -182,7 +181,7 @@ abstract class Paginator
|
|||||||
*/
|
*/
|
||||||
public function hasPages()
|
public function hasPages()
|
||||||
{
|
{
|
||||||
return !($this->currentPage == 1 && !$this->hasMore);
|
return !(1 == $this->currentPage && !$this->hasMore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,7 +238,6 @@ abstract class Paginator
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造锚点字符串
|
* 构造锚点字符串
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ namespace think;
|
|||||||
use think\process\exception\Failed as ProcessFailedException;
|
use think\process\exception\Failed as ProcessFailedException;
|
||||||
use think\process\exception\Timeout as ProcessTimeoutException;
|
use think\process\exception\Timeout as ProcessTimeoutException;
|
||||||
use think\process\pipes\Pipes;
|
use think\process\pipes\Pipes;
|
||||||
use think\process\Utils;
|
|
||||||
use think\process\pipes\Unix as UnixPipes;
|
use think\process\pipes\Unix as UnixPipes;
|
||||||
use think\process\pipes\Windows as WindowsPipes;
|
use think\process\pipes\Windows as WindowsPipes;
|
||||||
|
use think\process\Utils;
|
||||||
|
|
||||||
class Process
|
class Process
|
||||||
{
|
{
|
||||||
@@ -147,7 +147,7 @@ class Process
|
|||||||
$this->enhanceSigchildCompatibility = '\\' !== DS && $this->isSigchildEnabled();
|
$this->enhanceSigchildCompatibility = '\\' !== DS && $this->isSigchildEnabled();
|
||||||
$this->options = array_replace([
|
$this->options = array_replace([
|
||||||
'suppress_errors' => true,
|
'suppress_errors' => true,
|
||||||
'binary_pipes' => true
|
'binary_pipes' => true,
|
||||||
], $options);
|
], $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,7 +490,7 @@ class Process
|
|||||||
public function getExitCodeText()
|
public function getExitCodeText()
|
||||||
{
|
{
|
||||||
if (null === $exitcode = $this->getExitCode()) {
|
if (null === $exitcode = $this->getExitCode()) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
|
return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
|
||||||
@@ -586,7 +586,7 @@ class Process
|
|||||||
*/
|
*/
|
||||||
public function isStarted()
|
public function isStarted()
|
||||||
{
|
{
|
||||||
return $this->status != self::STATUS_READY;
|
return self::STATUS_READY != $this->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -597,7 +597,7 @@ class Process
|
|||||||
{
|
{
|
||||||
$this->updateStatus(false);
|
$this->updateStatus(false);
|
||||||
|
|
||||||
return $this->status == self::STATUS_TERMINATED;
|
return self::STATUS_TERMINATED == $this->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -922,7 +922,7 @@ class Process
|
|||||||
*/
|
*/
|
||||||
public function checkTimeout()
|
public function checkTimeout()
|
||||||
{
|
{
|
||||||
if ($this->status !== self::STATUS_STARTED) {
|
if (self::STATUS_STARTED !== $this->status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,7 +1083,7 @@ class Process
|
|||||||
if (3 == $type) {
|
if (3 == $type) {
|
||||||
$this->fallbackExitcode = (int) $data;
|
$this->fallbackExitcode = (int) $data;
|
||||||
} else {
|
} else {
|
||||||
$callback($type === self::STDOUT ? self::OUT : self::ERR, $data);
|
$callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Config;
|
|
||||||
use think\Exception;
|
|
||||||
use think\File;
|
|
||||||
use think\Session;
|
|
||||||
|
|
||||||
class Request
|
class Request
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +20,7 @@ class Request
|
|||||||
|
|
||||||
protected $method;
|
protected $method;
|
||||||
/**
|
/**
|
||||||
* @var string 域名
|
* @var string 域名(含协议和端口)
|
||||||
*/
|
*/
|
||||||
protected $domain;
|
protected $domain;
|
||||||
|
|
||||||
@@ -227,6 +222,7 @@ class Request
|
|||||||
$info['path'] = '/';
|
$info['path'] = '/';
|
||||||
}
|
}
|
||||||
$options = [];
|
$options = [];
|
||||||
|
$options[strtolower($method)] = $params;
|
||||||
$queryString = '';
|
$queryString = '';
|
||||||
if (isset($info['query'])) {
|
if (isset($info['query'])) {
|
||||||
parse_str(html_entity_decode($info['query']), $query);
|
parse_str(html_entity_decode($info['query']), $query);
|
||||||
@@ -240,6 +236,11 @@ class Request
|
|||||||
} elseif (!empty($params)) {
|
} elseif (!empty($params)) {
|
||||||
$queryString = http_build_query($params, '', '&');
|
$queryString = http_build_query($params, '', '&');
|
||||||
}
|
}
|
||||||
|
if ($queryString) {
|
||||||
|
parse_str($queryString, $get);
|
||||||
|
$options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;
|
||||||
|
}
|
||||||
|
|
||||||
$server['REQUEST_URI'] = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
|
$server['REQUEST_URI'] = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
|
||||||
$server['QUERY_STRING'] = $queryString;
|
$server['QUERY_STRING'] = $queryString;
|
||||||
$options['cookie'] = $cookie;
|
$options['cookie'] = $cookie;
|
||||||
@@ -257,7 +258,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前包含协议的域名
|
* 设置或获取当前包含协议的域名
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $domain 域名
|
* @param string $domain 域名
|
||||||
* @return string
|
* @return string
|
||||||
@@ -274,7 +275,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前完整URL 包括QUERY_STRING
|
* 设置或获取当前完整URL 包括QUERY_STRING
|
||||||
* @access public
|
* @access public
|
||||||
* @param string|true $url URL地址 true 带域名获取
|
* @param string|true $url URL地址 true 带域名获取
|
||||||
* @return string
|
* @return string
|
||||||
@@ -301,7 +302,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前URL 不含QUERY_STRING
|
* 设置或获取当前URL 不含QUERY_STRING
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $url URL地址
|
* @param string $url URL地址
|
||||||
* @return string
|
* @return string
|
||||||
@@ -319,7 +320,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前执行的文件 SCRIPT_NAME
|
* 设置或获取当前执行的文件 SCRIPT_NAME
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $file 当前执行的文件
|
* @param string $file 当前执行的文件
|
||||||
* @return string
|
* @return string
|
||||||
@@ -351,7 +352,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取URL访问根地址
|
* 设置或获取URL访问根地址
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $url URL地址
|
* @param string $url URL地址
|
||||||
* @return string
|
* @return string
|
||||||
@@ -455,7 +456,7 @@ class Request
|
|||||||
*/
|
*/
|
||||||
public function type()
|
public function type()
|
||||||
{
|
{
|
||||||
$accept = isset($this->server['HTTP_ACCEPT']) ? $this->server['HTTP_ACCEPT'] : $_SERVER['HTTP_ACCEPT'];
|
$accept = $this->server('HTTP_ACCEPT');
|
||||||
if (empty($accept)) {
|
if (empty($accept)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -602,7 +603,7 @@ class Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置获取获取当前请求的参数
|
* 获取获取当前请求的参数
|
||||||
* @access public
|
* @access public
|
||||||
* @param string|array $name 变量名
|
* @param string|array $name 变量名
|
||||||
* @param mixed $default 默认值
|
* @param mixed $default 默认值
|
||||||
@@ -688,7 +689,7 @@ class Request
|
|||||||
if (empty($this->post)) {
|
if (empty($this->post)) {
|
||||||
$content = $this->input;
|
$content = $this->input;
|
||||||
if (empty($_POST) && strpos($content, '":')) {
|
if (empty($_POST) && strpos($content, '":')) {
|
||||||
$this->post = json_decode($content, true);
|
$this->post = (array) json_decode($content, true);
|
||||||
} else {
|
} else {
|
||||||
$this->post = $_POST;
|
$this->post = $_POST;
|
||||||
}
|
}
|
||||||
@@ -713,7 +714,7 @@ class Request
|
|||||||
if (is_null($this->put)) {
|
if (is_null($this->put)) {
|
||||||
$content = $this->input;
|
$content = $this->input;
|
||||||
if (strpos($content, '":')) {
|
if (strpos($content, '":')) {
|
||||||
$this->put = json_decode($content, true);
|
$this->put = (array) json_decode($content, true);
|
||||||
} else {
|
} else {
|
||||||
parse_str($content, $this->put);
|
parse_str($content, $this->put);
|
||||||
}
|
}
|
||||||
@@ -885,7 +886,7 @@ class Request
|
|||||||
return $array[$name];
|
return $array[$name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Cache;
|
|
||||||
use think\Config;
|
|
||||||
use think\Debug;
|
|
||||||
use think\Env;
|
|
||||||
use think\Request;
|
|
||||||
use think\response\Json as JsonResponse;
|
use think\response\Json as JsonResponse;
|
||||||
use think\response\Jsonp as JsonpResponse;
|
use think\response\Jsonp as JsonpResponse;
|
||||||
use think\response\Redirect as RedirectResponse;
|
use think\response\Redirect as RedirectResponse;
|
||||||
|
|||||||
@@ -11,14 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
|
||||||
use think\Config;
|
|
||||||
use think\exception\HttpException;
|
use think\exception\HttpException;
|
||||||
use think\Hook;
|
|
||||||
use think\Loader;
|
|
||||||
use think\Log;
|
|
||||||
use think\Request;
|
|
||||||
use think\Response;
|
|
||||||
|
|
||||||
class Route
|
class Route
|
||||||
{
|
{
|
||||||
@@ -296,11 +289,13 @@ class Route
|
|||||||
} elseif ('$' == substr($rule, -1, 1)) {
|
} elseif ('$' == substr($rule, -1, 1)) {
|
||||||
// 是否完整匹配
|
// 是否完整匹配
|
||||||
$option['complete_match'] = true;
|
$option['complete_match'] = true;
|
||||||
$rule = substr($rule, 0, -1);
|
|
||||||
}
|
}
|
||||||
} elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) {
|
} elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) {
|
||||||
// 是否完整匹配
|
// 是否完整匹配
|
||||||
$option['complete_match'] = true;
|
$option['complete_match'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('$' == substr($rule, -1, 1)) {
|
||||||
$rule = substr($rule, 0, -1);
|
$rule = substr($rule, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,13 +657,13 @@ class Route
|
|||||||
* rest方法定义和修改
|
* rest方法定义和修改
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name 方法名称
|
* @param string $name 方法名称
|
||||||
* @param array $resource 资源
|
* @param array|bool $resource 资源
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function rest($name, $resource = [])
|
public static function rest($name, $resource = [])
|
||||||
{
|
{
|
||||||
if (is_array($name)) {
|
if (is_array($name)) {
|
||||||
self::$rest = array_merge(self::$rest, $name);
|
self::$rest = $resource ? $name : array_merge(self::$rest, $name);
|
||||||
} else {
|
} else {
|
||||||
self::$rest[$name] = $resource;
|
self::$rest[$name] = $resource;
|
||||||
}
|
}
|
||||||
@@ -1493,6 +1488,10 @@ class Route
|
|||||||
$route = substr($route, 1);
|
$route = substr($route, 1);
|
||||||
list($route, $var) = self::parseUrlPath($route);
|
list($route, $var) = self::parseUrlPath($route);
|
||||||
$result = ['type' => 'controller', 'controller' => implode('/', $route), 'var' => $var];
|
$result = ['type' => 'controller', 'controller' => implode('/', $route), 'var' => $var];
|
||||||
|
$request->action(array_pop($route));
|
||||||
|
$request->controller($route ? array_pop($route) : Config::get('default_controller'));
|
||||||
|
$request->module($route ? array_pop($route) : Config::get('default_module'));
|
||||||
|
App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : '');
|
||||||
} else {
|
} else {
|
||||||
// 路由到模块/控制器/操作
|
// 路由到模块/控制器/操作
|
||||||
$result = self::parseModule($route);
|
$result = self::parseModule($route);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\App;
|
|
||||||
use think\exception\ClassNotFoundException;
|
use think\exception\ClassNotFoundException;
|
||||||
|
|
||||||
class Session
|
class Session
|
||||||
@@ -193,7 +192,7 @@ class Session
|
|||||||
self::delete($name, $prefix);
|
self::delete($name, $prefix);
|
||||||
return $result;
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\exception\TemplateNotFoundException;
|
use think\exception\TemplateNotFoundException;
|
||||||
use think\Request;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ThinkPHP分离出来的模板引擎
|
* ThinkPHP分离出来的模板引擎
|
||||||
@@ -130,7 +129,7 @@ class Template
|
|||||||
} elseif (isset($this->config[$config])) {
|
} elseif (isset($this->config[$config])) {
|
||||||
return $this->config[$config];
|
return $this->config[$config];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +668,7 @@ class Template
|
|||||||
$content = str_replace($matches[0], '', $content);
|
$content = str_replace($matches[0], '', $content);
|
||||||
return explode(',', $matches['name']);
|
return explode(',', $matches['name']);
|
||||||
}
|
}
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1067,6 +1066,8 @@ class Template
|
|||||||
}
|
}
|
||||||
if (0 !== strpos($template, '/')) {
|
if (0 !== strpos($template, '/')) {
|
||||||
$template = str_replace(['/', ':'], $this->config['view_depr'], $template);
|
$template = str_replace(['/', ':'], $this->config['view_depr'], $template);
|
||||||
|
} else {
|
||||||
|
$template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1));
|
||||||
}
|
}
|
||||||
if ($this->config['view_base']) {
|
if ($this->config['view_base']) {
|
||||||
$module = isset($module) ? $module : Request::instance()->module();
|
$module = isset($module) ? $module : Request::instance()->module();
|
||||||
|
|||||||
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Config;
|
|
||||||
use think\Loader;
|
|
||||||
use think\Request;
|
|
||||||
use think\Route;
|
|
||||||
|
|
||||||
class Url
|
class Url
|
||||||
{
|
{
|
||||||
// 生成URL地址的root
|
// 生成URL地址的root
|
||||||
@@ -90,6 +85,7 @@ class Url
|
|||||||
} else {
|
} else {
|
||||||
// 检查别名路由
|
// 检查别名路由
|
||||||
$alias = Route::rules('alias');
|
$alias = Route::rules('alias');
|
||||||
|
$matchAlias = false;
|
||||||
if ($alias) {
|
if ($alias) {
|
||||||
// 别名路由解析
|
// 别名路由解析
|
||||||
foreach ($alias as $key => $val) {
|
foreach ($alias as $key => $val) {
|
||||||
@@ -98,10 +94,12 @@ class Url
|
|||||||
}
|
}
|
||||||
if (0 === strpos($url, $val)) {
|
if (0 === strpos($url, $val)) {
|
||||||
$url = $key . substr($url, strlen($val));
|
$url = $key . substr($url, strlen($val));
|
||||||
|
$matchAlias = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (!$matchAlias) {
|
||||||
// 路由标识不存在 直接解析
|
// 路由标识不存在 直接解析
|
||||||
$url = self::parseUrl($url, $domain);
|
$url = self::parseUrl($url, $domain);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\File;
|
use think\exception\ClassNotFoundException;
|
||||||
use think\Lang;
|
|
||||||
use think\Request;
|
|
||||||
use think\Session;
|
|
||||||
|
|
||||||
class Validate
|
class Validate
|
||||||
{
|
{
|
||||||
@@ -72,8 +69,8 @@ class Validate
|
|||||||
'expire' => '不在有效期内 :rule',
|
'expire' => '不在有效期内 :rule',
|
||||||
'allowIp' => '不允许的IP访问',
|
'allowIp' => '不允许的IP访问',
|
||||||
'denyIp' => '禁止的IP访问',
|
'denyIp' => '禁止的IP访问',
|
||||||
'confirm' => ':attribute和字段 :rule 不一致',
|
'confirm' => ':attribute和确认字段:2不一致',
|
||||||
'different' => ':attribute和字段 :rule 不能相同',
|
'different' => ':attribute和比较字段:2不能相同',
|
||||||
'egt' => ':attribute必须大于等于 :rule',
|
'egt' => ':attribute必须大于等于 :rule',
|
||||||
'gt' => ':attribute必须大于 :rule',
|
'gt' => ':attribute必须大于 :rule',
|
||||||
'elt' => ':attribute必须小于等于 :rule',
|
'elt' => ':attribute必须小于等于 :rule',
|
||||||
@@ -317,7 +314,12 @@ class Validate
|
|||||||
$value = $this->getDataValue($data, $key);
|
$value = $this->getDataValue($data, $key);
|
||||||
|
|
||||||
// 字段验证
|
// 字段验证
|
||||||
|
if ($rule instanceof \Closure) {
|
||||||
|
// 匿名函数验证 支持传入当前字段和所有字段两个数据
|
||||||
|
$result = call_user_func_array($rule, [$value, $data]);
|
||||||
|
} else {
|
||||||
$result = $this->checkItem($key, $value, $rule, $data, $title, $msg);
|
$result = $this->checkItem($key, $value, $rule, $data, $title, $msg);
|
||||||
|
}
|
||||||
|
|
||||||
if (true !== $result) {
|
if (true !== $result) {
|
||||||
// 没有返回true 则表示验证失败
|
// 没有返回true 则表示验证失败
|
||||||
@@ -350,10 +352,6 @@ class Validate
|
|||||||
*/
|
*/
|
||||||
protected function checkItem($field, $value, $rules, $data, $title = '', $msg = [])
|
protected function checkItem($field, $value, $rules, $data, $title = '', $msg = [])
|
||||||
{
|
{
|
||||||
if ($rules instanceof \Closure) {
|
|
||||||
// 匿名函数验证 支持传入当前字段和所有字段两个数据
|
|
||||||
$result = call_user_func_array($rules, [$value, $data]);
|
|
||||||
} else {
|
|
||||||
// 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]
|
// 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]
|
||||||
if (is_string($rules)) {
|
if (is_string($rules)) {
|
||||||
$rules = explode('|', $rules);
|
$rules = explode('|', $rules);
|
||||||
@@ -362,6 +360,7 @@ class Validate
|
|||||||
foreach ($rules as $key => $rule) {
|
foreach ($rules as $key => $rule) {
|
||||||
if ($rule instanceof \Closure) {
|
if ($rule instanceof \Closure) {
|
||||||
$result = call_user_func_array($rule, [$value, $data]);
|
$result = call_user_func_array($rule, [$value, $data]);
|
||||||
|
$info = is_numeric($key) ? '' : $key;
|
||||||
} else {
|
} else {
|
||||||
// 判断验证类型
|
// 判断验证类型
|
||||||
if (is_numeric($key)) {
|
if (is_numeric($key)) {
|
||||||
@@ -389,7 +388,7 @@ class Validate
|
|||||||
// 验证类型
|
// 验证类型
|
||||||
$callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
|
$callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
|
||||||
// 验证数据
|
// 验证数据
|
||||||
$result = call_user_func_array($callback, [$value, $rule, $data, $field]);
|
$result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]);
|
||||||
} else {
|
} else {
|
||||||
$result = true;
|
$result = true;
|
||||||
}
|
}
|
||||||
@@ -415,8 +414,7 @@ class Validate
|
|||||||
}
|
}
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
}
|
return $result;
|
||||||
return true !== $result ? $result : true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -811,7 +809,16 @@ class Validate
|
|||||||
if (is_string($rule)) {
|
if (is_string($rule)) {
|
||||||
$rule = explode(',', $rule);
|
$rule = explode(',', $rule);
|
||||||
}
|
}
|
||||||
|
if (false !== strpos($rule[0], '\\')) {
|
||||||
|
// 指定模型类
|
||||||
|
$db = new $rule[0];
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
$db = Loader::model($rule[0]);
|
||||||
|
} catch (ClassNotFoundException $e) {
|
||||||
$db = Db::name($rule[0]);
|
$db = Db::name($rule[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
$key = isset($rule[1]) ? $rule[1] : $field;
|
$key = isset($rule[1]) ? $rule[1] : $field;
|
||||||
|
|
||||||
if (strpos($key, '^')) {
|
if (strpos($key, '^')) {
|
||||||
@@ -1201,6 +1208,8 @@ class Validate
|
|||||||
{
|
{
|
||||||
if (isset($this->message[$attribute . '.' . $type])) {
|
if (isset($this->message[$attribute . '.' . $type])) {
|
||||||
$msg = $this->message[$attribute . '.' . $type];
|
$msg = $this->message[$attribute . '.' . $type];
|
||||||
|
} elseif (isset($this->message[$attribute][$type])) {
|
||||||
|
$msg = $this->message[$attribute][$type];
|
||||||
} elseif (isset($this->message[$attribute])) {
|
} elseif (isset($this->message[$attribute])) {
|
||||||
$msg = $this->message[$attribute];
|
$msg = $this->message[$attribute];
|
||||||
} elseif (isset(self::$typeMsg[$type])) {
|
} elseif (isset(self::$typeMsg[$type])) {
|
||||||
@@ -1213,7 +1222,7 @@ class Validate
|
|||||||
$msg = Lang::get(substr($msg, 2, -1));
|
$msg = Lang::get(substr($msg, 2, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($msg) && false !== strpos($msg, ':')) {
|
if (is_string($msg) && is_string($rule) && false !== strpos($msg, ':')) {
|
||||||
// 变量替换
|
// 变量替换
|
||||||
if (strpos($rule, ',')) {
|
if (strpos($rule, ',')) {
|
||||||
$array = array_pad(explode(',', $rule), 3, '');
|
$array = array_pad(explode(',', $rule), 3, '');
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use think\Loader;
|
|
||||||
use think\Request;
|
|
||||||
|
|
||||||
class View
|
class View
|
||||||
{
|
{
|
||||||
// 视图实例
|
// 视图实例
|
||||||
|
|||||||
2
core/library/think/cache/Driver.php
vendored
2
core/library/think/cache/Driver.php
vendored
@@ -105,7 +105,7 @@ abstract class Driver
|
|||||||
$this->rm($name);
|
$this->rm($name);
|
||||||
return $result;
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
core/library/think/cache/driver/Memcache.php
vendored
1
core/library/think/cache/driver/Memcache.php
vendored
@@ -12,7 +12,6 @@
|
|||||||
namespace think\cache\driver;
|
namespace think\cache\driver;
|
||||||
|
|
||||||
use think\cache\Driver;
|
use think\cache\Driver;
|
||||||
use think\Exception;
|
|
||||||
|
|
||||||
class Memcache extends Driver
|
class Memcache extends Driver
|
||||||
{
|
{
|
||||||
|
|||||||
1
core/library/think/cache/driver/Sqlite.php
vendored
1
core/library/think/cache/driver/Sqlite.php
vendored
@@ -12,7 +12,6 @@
|
|||||||
namespace think\cache\driver;
|
namespace think\cache\driver;
|
||||||
|
|
||||||
use think\cache\Driver;
|
use think\cache\Driver;
|
||||||
use think\Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sqlite缓存驱动
|
* Sqlite缓存驱动
|
||||||
|
|||||||
3
core/library/think/cache/driver/Wincache.php
vendored
3
core/library/think/cache/driver/Wincache.php
vendored
@@ -12,7 +12,6 @@
|
|||||||
namespace think\cache\driver;
|
namespace think\cache\driver;
|
||||||
|
|
||||||
use think\cache\Driver;
|
use think\cache\Driver;
|
||||||
use think\Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wincache缓存驱动
|
* Wincache缓存驱动
|
||||||
@@ -28,7 +27,7 @@ class Wincache extends Driver
|
|||||||
/**
|
/**
|
||||||
* 架构函数
|
* 架构函数
|
||||||
* @param array $options 缓存参数
|
* @param array $options 缓存参数
|
||||||
* @throws Exception
|
* @throws \BadFunctionCallException
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function __construct($options = [])
|
public function __construct($options = [])
|
||||||
|
|||||||
1
core/library/think/cache/driver/Xcache.php
vendored
1
core/library/think/cache/driver/Xcache.php
vendored
@@ -12,7 +12,6 @@
|
|||||||
namespace think\cache\driver;
|
namespace think\cache\driver;
|
||||||
|
|
||||||
use think\cache\Driver;
|
use think\cache\Driver;
|
||||||
use think\Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Xcache缓存驱动
|
* Xcache缓存驱动
|
||||||
|
|||||||
@@ -12,9 +12,6 @@
|
|||||||
namespace think\db;
|
namespace think\db;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use think\Db;
|
|
||||||
use think\db\Connection;
|
|
||||||
use think\db\Query;
|
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
|
|
||||||
abstract class Builder
|
abstract class Builder
|
||||||
@@ -118,6 +115,9 @@ abstract class Builder
|
|||||||
$this->query->bind($key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
$this->query->bind($key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||||
$result[$item] = ':' . $key;
|
$result[$item] = ':' . $key;
|
||||||
}
|
}
|
||||||
|
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||||
|
// 对象数据写入
|
||||||
|
$result[$item] = $val->__toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@@ -317,6 +317,11 @@ abstract class Builder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$bindName = $bindName ?: 'where_' . str_replace('.', '_', $field);
|
$bindName = $bindName ?: 'where_' . str_replace('.', '_', $field);
|
||||||
|
if (preg_match('/\W/', $bindName)) {
|
||||||
|
// 处理带非单词字符的字段名
|
||||||
|
$bindName = md5($bindName);
|
||||||
|
}
|
||||||
|
|
||||||
$bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
|
$bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
|
||||||
if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
|
if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
|
||||||
if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) {
|
if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) {
|
||||||
@@ -702,8 +707,13 @@ abstract class Builder
|
|||||||
throw new Exception('fields not exists:[' . $key . ']');
|
throw new Exception('fields not exists:[' . $key . ']');
|
||||||
}
|
}
|
||||||
unset($data[$key]);
|
unset($data[$key]);
|
||||||
|
} elseif (is_null($val)) {
|
||||||
|
$data[$key] = 'NULL';
|
||||||
} elseif (is_scalar($val)) {
|
} elseif (is_scalar($val)) {
|
||||||
$data[$key] = $this->parseValue($val, $key);
|
$data[$key] = $this->parseValue($val, $key);
|
||||||
|
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||||
|
// 对象数据写入
|
||||||
|
$data[$key] = $val->__toString();
|
||||||
} else {
|
} else {
|
||||||
// 过滤掉非标量数据
|
// 过滤掉非标量数据
|
||||||
unset($data[$key]);
|
unset($data[$key]);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ use PDOStatement;
|
|||||||
use think\Collection;
|
use think\Collection;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\db\exception\BindParamException;
|
use think\db\exception\BindParamException;
|
||||||
use think\db\Query;
|
|
||||||
use think\Debug;
|
use think\Debug;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
use think\exception\PDOException;
|
use think\exception\PDOException;
|
||||||
@@ -100,6 +99,8 @@ abstract class Connection
|
|||||||
'resultset_type' => 'array',
|
'resultset_type' => 'array',
|
||||||
// 自动写入时间戳字段
|
// 自动写入时间戳字段
|
||||||
'auto_timestamp' => false,
|
'auto_timestamp' => false,
|
||||||
|
// 时间字段取出后的默认时间格式
|
||||||
|
'datetime_format' => 'Y-m-d H:i:s',
|
||||||
// 是否需要进行SQL性能分析
|
// 是否需要进行SQL性能分析
|
||||||
'sql_explain' => false,
|
'sql_explain' => false,
|
||||||
// Builder类
|
// Builder类
|
||||||
@@ -136,11 +137,11 @@ abstract class Connection
|
|||||||
* @param string $queryClass 查询对象类名
|
* @param string $queryClass 查询对象类名
|
||||||
* @return Query
|
* @return Query
|
||||||
*/
|
*/
|
||||||
public function model($model, $queryClass = '')
|
public function getQuery($model = 'db', $queryClass = '')
|
||||||
{
|
{
|
||||||
if (!isset($this->query[$model])) {
|
if (!isset($this->query[$model])) {
|
||||||
$class = $queryClass ?: $this->config['query'];
|
$class = $queryClass ?: $this->config['query'];
|
||||||
$this->query[$model] = new $class($this, $model);
|
$this->query[$model] = new $class($this, 'db' == $model ? '' : $model);
|
||||||
}
|
}
|
||||||
return $this->query[$model];
|
return $this->query[$model];
|
||||||
}
|
}
|
||||||
@@ -154,11 +155,7 @@ abstract class Connection
|
|||||||
*/
|
*/
|
||||||
public function __call($method, $args)
|
public function __call($method, $args)
|
||||||
{
|
{
|
||||||
if (!isset($this->query['database'])) {
|
return call_user_func_array([$this->getQuery(), $method], $args);
|
||||||
$class = $this->config['query'];
|
|
||||||
$this->query['database'] = new $class($this);
|
|
||||||
}
|
|
||||||
return call_user_func_array([$this->query['database'], $method], $args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ use think\Cache;
|
|||||||
use think\Collection;
|
use think\Collection;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\db\Builder;
|
|
||||||
use think\db\Connection;
|
|
||||||
use think\db\exception\BindParamException;
|
use think\db\exception\BindParamException;
|
||||||
use think\db\exception\DataNotFoundException;
|
use think\db\exception\DataNotFoundException;
|
||||||
use think\db\exception\ModelNotFoundException;
|
use think\db\exception\ModelNotFoundException;
|
||||||
@@ -27,8 +25,7 @@ use think\exception\PDOException;
|
|||||||
use think\Loader;
|
use think\Loader;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\Relation;
|
use think\model\Relation;
|
||||||
use think\model\relation\BelongsTo;
|
use think\model\relation\OneToOne;
|
||||||
use think\model\relation\HasOne;
|
|
||||||
use think\Paginator;
|
use think\Paginator;
|
||||||
|
|
||||||
class Query
|
class Query
|
||||||
@@ -1182,7 +1179,14 @@ class Query
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->options['order'] = $field;
|
if (!isset($this->options['order'])) {
|
||||||
|
$this->options['order'] = [];
|
||||||
|
}
|
||||||
|
if (is_array($field)) {
|
||||||
|
$this->options['order'] = array_merge($this->options['order'], $field);
|
||||||
|
} else {
|
||||||
|
$this->options['order'][] = $field;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1552,7 +1556,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
protected function getFieldBindType($type)
|
protected function getFieldBindType($type)
|
||||||
{
|
{
|
||||||
if (preg_match('/(int|double|float|decimal|real|numeric|serial)/is', $type)) {
|
if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {
|
||||||
$bind = PDO::PARAM_INT;
|
$bind = PDO::PARAM_INT;
|
||||||
} elseif (preg_match('/bool/is', $type)) {
|
} elseif (preg_match('/bool/is', $type)) {
|
||||||
$bind = PDO::PARAM_BOOL;
|
$bind = PDO::PARAM_BOOL;
|
||||||
@@ -1653,8 +1657,9 @@ class Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var Relation $model */
|
/** @var Relation $model */
|
||||||
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
$model = $class->$relation();
|
$model = $class->$relation();
|
||||||
if ($model instanceof HasOne || $model instanceof BelongsTo) {
|
if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
|
||||||
$model->eagerly($this, $relation, $subRelation, $closure, $first);
|
$model->eagerly($this, $relation, $subRelation, $closure, $first);
|
||||||
$first = false;
|
$first = false;
|
||||||
} elseif ($closure) {
|
} elseif ($closure) {
|
||||||
@@ -1666,6 +1671,36 @@ class Query
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param string|array $relation 关联方法名
|
||||||
|
* @param bool $subQuery 是否使用子查询
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withCount($relation, $subQuery = true)
|
||||||
|
{
|
||||||
|
if (!$subQuery) {
|
||||||
|
$this->options['with_count'] = $relation;
|
||||||
|
} else {
|
||||||
|
$relations = is_string($relation) ? explode(',', $relation) : $relation;
|
||||||
|
if (!isset($this->options['field'])) {
|
||||||
|
$this->field('*');
|
||||||
|
}
|
||||||
|
foreach ($relations as $key => $relation) {
|
||||||
|
$closure = false;
|
||||||
|
if ($relation instanceof \Closure) {
|
||||||
|
$closure = $relation;
|
||||||
|
$relation = $key;
|
||||||
|
}
|
||||||
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
|
$count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')';
|
||||||
|
$this->field([$count => Loader::parseName($relation) . '_count']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关联预加载中 获取关联指定字段值
|
* 关联预加载中 获取关联指定字段值
|
||||||
* example:
|
* example:
|
||||||
@@ -1997,6 +2032,10 @@ class Query
|
|||||||
if (!empty($options['relation'])) {
|
if (!empty($options['relation'])) {
|
||||||
$result->relationQuery($options['relation']);
|
$result->relationQuery($options['relation']);
|
||||||
}
|
}
|
||||||
|
// 关联统计
|
||||||
|
if (!empty($options['with_count'])) {
|
||||||
|
$result->relationCount($result, $options['with_count']);
|
||||||
|
}
|
||||||
$resultSet[$key] = $result;
|
$resultSet[$key] = $result;
|
||||||
}
|
}
|
||||||
if (!empty($options['with'])) {
|
if (!empty($options['with'])) {
|
||||||
@@ -2095,10 +2134,14 @@ class Query
|
|||||||
if (!empty($options['relation'])) {
|
if (!empty($options['relation'])) {
|
||||||
$data->relationQuery($options['relation']);
|
$data->relationQuery($options['relation']);
|
||||||
}
|
}
|
||||||
|
// 预载入查询
|
||||||
if (!empty($options['with'])) {
|
if (!empty($options['with'])) {
|
||||||
// 预载入
|
|
||||||
$data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : '');
|
$data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : '');
|
||||||
}
|
}
|
||||||
|
// 关联统计
|
||||||
|
if (!empty($options['with_count'])) {
|
||||||
|
$data->relationCount($data, $options['with_count']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif (!empty($options['fail'])) {
|
} elseif (!empty($options['fail'])) {
|
||||||
$this->throwNotFound($options);
|
$this->throwNotFound($options);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class DataNotFoundException extends DbException
|
|||||||
* @param string $table
|
* @param string $table
|
||||||
* @param array $config
|
* @param array $config
|
||||||
*/
|
*/
|
||||||
public function __construct($message, $table = '', Array $config = [])
|
public function __construct($message, $table = '', array $config = [])
|
||||||
{
|
{
|
||||||
$this->message = $message;
|
$this->message = $message;
|
||||||
$this->table = $table;
|
$this->table = $table;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class ModelNotFoundException extends DbException
|
|||||||
* @param string $message
|
* @param string $message
|
||||||
* @param string $model
|
* @param string $model
|
||||||
*/
|
*/
|
||||||
public function __construct($message, $model = '', Array $config = [])
|
public function __construct($message, $model = '', array $config = [])
|
||||||
{
|
{
|
||||||
$this->message = $message;
|
$this->message = $message;
|
||||||
$this->model = $model;
|
$this->model = $model;
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
namespace think\exception;
|
namespace think\exception;
|
||||||
|
|
||||||
use think\exception\DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PDO异常处理类
|
* PDO异常处理类
|
||||||
* 重新封装了系统的\PDOException类
|
* 重新封装了系统的\PDOException类
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
namespace think\exception;
|
namespace think\exception;
|
||||||
|
|
||||||
use think\exception\HttpException;
|
|
||||||
|
|
||||||
class RouteNotFoundException extends HttpException
|
class RouteNotFoundException extends HttpException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class File
|
|||||||
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
|
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$runtime = number_format(microtime(true) - THINK_START_TIME, 10);
|
$runtime = round(microtime(true) - THINK_START_TIME, 10);
|
||||||
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
||||||
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
||||||
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace think\log\driver;
|
namespace think\log\driver;
|
||||||
|
|
||||||
|
use think\App;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* github: https://github.com/luofei614/SocketLog
|
* github: https://github.com/luofei614/SocketLog
|
||||||
* @author luofei614<weibo.com/luofei614>
|
* @author luofei614<weibo.com/luofei614>
|
||||||
@@ -65,7 +67,7 @@ class Socket
|
|||||||
}
|
}
|
||||||
$trace = [];
|
$trace = [];
|
||||||
if (App::$debug) {
|
if (App::$debug) {
|
||||||
$runtime = number_format(microtime(true) - THINK_START_TIME, 10);
|
$runtime = round(microtime(true) - THINK_START_TIME, 10);
|
||||||
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
$reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
|
||||||
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
$time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
|
||||||
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
$memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);
|
||||||
@@ -207,19 +209,19 @@ class Socket
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($_SERVER[$key])) {
|
if (!isset($_SERVER[$key])) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
if (empty($args)) {
|
if (empty($args)) {
|
||||||
if (!preg_match('/SocketLog\((.*?)\)/', $_SERVER[$key], $match)) {
|
if (!preg_match('/SocketLog\((.*?)\)/', $_SERVER[$key], $match)) {
|
||||||
$args = ['tabid' => null];
|
$args = ['tabid' => null];
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
parse_str($match[1], $args);
|
parse_str($match[1], $args);
|
||||||
}
|
}
|
||||||
if (isset($args[$name])) {
|
if (isset($args[$name])) {
|
||||||
return $args[$name];
|
return $args[$name];
|
||||||
}
|
}
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
namespace think\model;
|
namespace think\model;
|
||||||
|
|
||||||
use think\Db;
|
use think\Db;
|
||||||
|
use think\db\Query;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
class Merge extends Model
|
class Merge extends Model
|
||||||
@@ -168,12 +169,13 @@ class Merge extends Model
|
|||||||
$this->autoCompleteData($this->auto);
|
$this->autoCompleteData($this->auto);
|
||||||
|
|
||||||
// 自动写入更新时间
|
// 自动写入更新时间
|
||||||
if ($this->autoWriteTimestamp && $this->updateTime) {
|
if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) {
|
||||||
$this->setAttr($this->updateTime, null);
|
$this->setAttr($this->updateTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
$db->startTrans();
|
$db->startTrans();
|
||||||
|
$pk = $this->getPk();
|
||||||
try {
|
try {
|
||||||
if ($this->isUpdate) {
|
if ($this->isUpdate) {
|
||||||
// 自动写入
|
// 自动写入
|
||||||
@@ -187,19 +189,15 @@ class Merge extends Model
|
|||||||
$where = $this->updateWhere;
|
$where = $this->updateWhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($where)) {
|
|
||||||
$pk = $this->getPk();
|
|
||||||
|
|
||||||
if (isset($this->mapFields[$pk])) {
|
|
||||||
$pk = $this->mapFields[$pk];
|
|
||||||
}
|
|
||||||
if (isset($where[$pk])) {
|
|
||||||
unset($where[$pk]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理模型数据
|
// 处理模型数据
|
||||||
$data = $this->parseData($this->name, $this->data);
|
$data = $this->parseData($this->name, $this->data);
|
||||||
|
if (is_string($pk) && isset($data[$pk])) {
|
||||||
|
if (!isset($where[$pk])) {
|
||||||
|
unset($where);
|
||||||
|
$where[$pk] = $data[$pk];
|
||||||
|
}
|
||||||
|
unset($data[$pk]);
|
||||||
|
}
|
||||||
// 写入主表数据
|
// 写入主表数据
|
||||||
$result = $db->strict(false)->where($where)->update($data);
|
$result = $db->strict(false)->where($where)->update($data);
|
||||||
|
|
||||||
@@ -209,7 +207,7 @@ class Merge extends Model
|
|||||||
$table = is_int($key) ? $db->getTable($model) : $model;
|
$table = is_int($key) ? $db->getTable($model) : $model;
|
||||||
// 处理关联模型数据
|
// 处理关联模型数据
|
||||||
$data = $this->parseData($name, $this->data);
|
$data = $this->parseData($name, $this->data);
|
||||||
$query = clone $db;
|
$query = new Query;
|
||||||
if ($query->table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data)) {
|
if ($query->table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data)) {
|
||||||
$result = 1;
|
$result = 1;
|
||||||
}
|
}
|
||||||
@@ -223,7 +221,7 @@ class Merge extends Model
|
|||||||
$this->autoCompleteData($this->insert);
|
$this->autoCompleteData($this->insert);
|
||||||
|
|
||||||
// 自动写入创建时间
|
// 自动写入创建时间
|
||||||
if ($this->autoWriteTimestamp && $this->createTime) {
|
if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) {
|
||||||
$this->setAttr($this->createTime, null);
|
$this->setAttr($this->createTime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +236,6 @@ class Merge extends Model
|
|||||||
if ($result) {
|
if ($result) {
|
||||||
$insertId = $db->getLastInsID($sequence);
|
$insertId = $db->getLastInsID($sequence);
|
||||||
// 写入外键数据
|
// 写入外键数据
|
||||||
$pk = $this->getPk();
|
|
||||||
if ($insertId) {
|
if ($insertId) {
|
||||||
if (is_string($pk)) {
|
if (is_string($pk)) {
|
||||||
$this->data[$pk] = $insertId;
|
$this->data[$pk] = $insertId;
|
||||||
@@ -259,7 +256,7 @@ class Merge extends Model
|
|||||||
$table = is_int($key) ? $db->getTable($model) : $model;
|
$table = is_int($key) ? $db->getTable($model) : $model;
|
||||||
// 处理关联模型数据
|
// 处理关联模型数据
|
||||||
$data = $this->parseData($name, $source, true);
|
$data = $this->parseData($name, $source, true);
|
||||||
$query = clone $db;
|
$query = new Query;
|
||||||
$query->table($table)->strict(false)->insert($data);
|
$query->table($table)->strict(false)->insert($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +297,7 @@ class Merge extends Model
|
|||||||
// 删除关联数据
|
// 删除关联数据
|
||||||
foreach ($this->relationModel as $key => $model) {
|
foreach ($this->relationModel as $key => $model) {
|
||||||
$table = is_int($key) ? $db->getTable($model) : $model;
|
$table = is_int($key) ? $db->getTable($model) : $model;
|
||||||
$query = clone $db;
|
$query = new Query;
|
||||||
$query->table($table)->where($this->fk, $pk)->delete();
|
$query->table($table)->where($this->fk, $pk)->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
namespace think\model\relation;
|
namespace think\model\relation;
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\relation\OneToOne;
|
|
||||||
|
|
||||||
class BelongsTo extends OneToOne
|
class BelongsTo extends OneToOne
|
||||||
{
|
{
|
||||||
@@ -22,7 +21,7 @@ class BelongsTo extends OneToOne
|
|||||||
* @param Model $parent 上级模型对象
|
* @param Model $parent 上级模型对象
|
||||||
* @param string $model 模型名
|
* @param string $model 模型名
|
||||||
* @param string $foreignKey 关联外键
|
* @param string $foreignKey 关联外键
|
||||||
* @param string $otherKey 关联主键
|
* @param string $localKey 关联主键
|
||||||
* @param array $alias 别名定义
|
* @param array $alias 别名定义
|
||||||
* @param string $joinType JOIN类型
|
* @param string $joinType JOIN类型
|
||||||
*/
|
*/
|
||||||
@@ -48,4 +47,80 @@ class BelongsTo extends OneToOne
|
|||||||
return $this->query->where($localKey, $this->parent->$foreignKey)->find();
|
return $this->query->where($localKey, $this->parent->$foreignKey)->find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预载入关联查询(数据集)
|
||||||
|
* @access public
|
||||||
|
* @param array $resultSet 数据集
|
||||||
|
* @param string $relation 当前关联名
|
||||||
|
* @param string $subRelation 子关联名
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure, $class)
|
||||||
|
{
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$foreignKey = $this->foreignKey;
|
||||||
|
|
||||||
|
$range = [];
|
||||||
|
foreach ($resultSet as $result) {
|
||||||
|
// 获取关联外键列表
|
||||||
|
if (isset($result->$foreignKey)) {
|
||||||
|
$range[] = $result->$foreignKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($range)) {
|
||||||
|
$this->where[$localKey] = ['in', $range];
|
||||||
|
$data = $this->eagerlyWhere($this, [
|
||||||
|
$localKey => [
|
||||||
|
'in',
|
||||||
|
$range,
|
||||||
|
],
|
||||||
|
], $localKey, $relation, $subRelation, $closure);
|
||||||
|
|
||||||
|
// 关联数据封装
|
||||||
|
foreach ($resultSet as $result) {
|
||||||
|
if (!isset($data[$result->$foreignKey])) {
|
||||||
|
$data[$result->$foreignKey] = [];
|
||||||
|
}
|
||||||
|
$relationModel = $this->resultSetBuild($data[$result->$foreignKey], $class);
|
||||||
|
if (!empty($this->bindAttr)) {
|
||||||
|
// 绑定关联属性
|
||||||
|
$this->bindAttr($relationModel, $result, $this->bindAttr);
|
||||||
|
}
|
||||||
|
// 设置关联属性
|
||||||
|
$result->setAttr($relation, $relationModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预载入关联查询(数据)
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param string $relation 当前关联名
|
||||||
|
* @param string $subRelation 子关联名
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function eagerlyOne(&$result, $relation, $subRelation, $closure, $class)
|
||||||
|
{
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$foreignKey = $this->foreignKey;
|
||||||
|
$data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure);
|
||||||
|
// 关联数据封装
|
||||||
|
if (!isset($data[$result->$foreignKey])) {
|
||||||
|
$data[$result->$foreignKey] = [];
|
||||||
|
}
|
||||||
|
$relationModel = $this->resultSetBuild($data[$result->$foreignKey], $class);
|
||||||
|
if (!empty($this->bindAttr)) {
|
||||||
|
// 绑定关联属性
|
||||||
|
$this->bindAttr($relationModel, $result, $this->bindAttr);
|
||||||
|
}
|
||||||
|
// 设置关联属性
|
||||||
|
$result->setAttr($relation, $relationModel);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace think\model\relation;
|
|||||||
|
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
|
use think\Exception;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\Pivot;
|
use think\model\Pivot;
|
||||||
use think\model\Relation;
|
use think\model\Relation;
|
||||||
@@ -128,14 +129,11 @@ class BelongsToMany extends Relation
|
|||||||
*/
|
*/
|
||||||
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
$localKey = $this->localKey;
|
|
||||||
$foreignKey = $this->foreignKey;
|
|
||||||
|
|
||||||
$pk = $result->getPk();
|
$pk = $result->getPk();
|
||||||
if (isset($result->$pk)) {
|
if (isset($result->$pk)) {
|
||||||
$pk = $result->$pk;
|
$pk = $result->$pk;
|
||||||
// 查询管理数据
|
// 查询管理数据
|
||||||
$data = $this->eagerlyManyToMany(['pivot.' . $localKey => $pk], $relation, $subRelation);
|
$data = $this->eagerlyManyToMany(['pivot.' . $this->localKey => $pk], $relation, $subRelation);
|
||||||
|
|
||||||
// 关联数据封装
|
// 关联数据封装
|
||||||
if (!isset($data[$pk])) {
|
if (!isset($data[$pk])) {
|
||||||
@@ -145,6 +143,35 @@ class BelongsToMany extends Relation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{
|
||||||
|
$pk = $result->getPk();
|
||||||
|
$count = 0;
|
||||||
|
if (isset($result->$pk)) {
|
||||||
|
$pk = $result->$pk;
|
||||||
|
$count = $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count();
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取关联统计子查询
|
||||||
|
* @access public
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRelationCountQuery($closure)
|
||||||
|
{
|
||||||
|
return $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => ['exp', '=' . $this->parent->getTable() . '.' . $this->parent->getPk()]])->fetchSql()->count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多对多 关联模型预查询
|
* 多对多 关联模型预查询
|
||||||
* @access public
|
* @access public
|
||||||
@@ -155,10 +182,8 @@ class BelongsToMany extends Relation
|
|||||||
*/
|
*/
|
||||||
protected function eagerlyManyToMany($where, $relation, $subRelation = '')
|
protected function eagerlyManyToMany($where, $relation, $subRelation = '')
|
||||||
{
|
{
|
||||||
$foreignKey = $this->foreignKey;
|
|
||||||
$localKey = $this->localKey;
|
|
||||||
// 预载入关联查询 支持嵌套预载入
|
// 预载入关联查询 支持嵌套预载入
|
||||||
$list = $this->belongsToManyQuery($this->middle, $foreignKey, $localKey, $where)->with($subRelation)->select();
|
$list = $this->belongsToManyQuery($this->middle, $this->foreignKey, $this->localKey, $where)->with($subRelation)->select();
|
||||||
|
|
||||||
// 组装模型数据
|
// 组装模型数据
|
||||||
$data = [];
|
$data = [];
|
||||||
@@ -174,7 +199,7 @@ class BelongsToMany extends Relation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$set->pivot = new Pivot($pivot, $this->middle);
|
$set->pivot = new Pivot($pivot, $this->middle);
|
||||||
$data[$pivot[$localKey]][] = $set;
|
$data[$pivot[$this->localKey]][] = $set;
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
@@ -217,13 +242,19 @@ class BelongsToMany extends Relation
|
|||||||
* @access public
|
* @access public
|
||||||
* @param array $dataSet 数据集
|
* @param array $dataSet 数据集
|
||||||
* @param array $pivot 中间表额外数据
|
* @param array $pivot 中间表额外数据
|
||||||
|
* @param bool $samePivot 额外数据是否相同
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function saveAll(array $dataSet, array $pivot = [])
|
public function saveAll(array $dataSet, array $pivot = [], $samePivot = false)
|
||||||
{
|
{
|
||||||
$result = false;
|
$result = false;
|
||||||
foreach ($dataSet as $key => $data) {
|
foreach ($dataSet as $key => $data) {
|
||||||
$result = $this->attach($data, !empty($pivot) ? $pivot[$key] : []);
|
if (!$samePivot) {
|
||||||
|
$pivotData = isset($pivot[$key]) ? $pivot[$key] : [];
|
||||||
|
} else {
|
||||||
|
$pivotData = $pivot;
|
||||||
|
}
|
||||||
|
$result = $this->attach($data, $pivotData);
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -238,10 +269,14 @@ class BelongsToMany extends Relation
|
|||||||
public function attach($data, $pivot = [])
|
public function attach($data, $pivot = [])
|
||||||
{
|
{
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
|
if (key($data) === 0) {
|
||||||
|
$id = $data;
|
||||||
|
} else {
|
||||||
// 保存关联表数据
|
// 保存关联表数据
|
||||||
$model = new $this->model;
|
$model = new $this->model;
|
||||||
$model->save($data);
|
$model->save($data);
|
||||||
$id = $model->getLastInsID();
|
$id = $model->getLastInsID();
|
||||||
|
}
|
||||||
} elseif (is_numeric($data) || is_string($data)) {
|
} elseif (is_numeric($data) || is_string($data)) {
|
||||||
// 根据关联表主键直接写入中间表
|
// 根据关联表主键直接写入中间表
|
||||||
$id = $data;
|
$id = $data;
|
||||||
@@ -255,8 +290,12 @@ class BelongsToMany extends Relation
|
|||||||
// 保存中间表数据
|
// 保存中间表数据
|
||||||
$pk = $this->parent->getPk();
|
$pk = $this->parent->getPk();
|
||||||
$pivot[$this->localKey] = $this->parent->$pk;
|
$pivot[$this->localKey] = $this->parent->$pk;
|
||||||
|
$ids = (array) $id;
|
||||||
|
foreach ($ids as $id) {
|
||||||
$pivot[$this->foreignKey] = $id;
|
$pivot[$this->foreignKey] = $id;
|
||||||
return $this->query->table($this->middle)->insert($pivot);
|
$result = $this->query->table($this->middle)->insert($pivot, true);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
throw new Exception('miss relation data');
|
throw new Exception('miss relation data');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ class HasMany extends Relation
|
|||||||
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)
|
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
$localKey = $this->localKey;
|
$localKey = $this->localKey;
|
||||||
$foreignKey = $this->foreignKey;
|
|
||||||
|
|
||||||
$range = [];
|
$range = [];
|
||||||
foreach ($resultSet as $result) {
|
foreach ($resultSet as $result) {
|
||||||
// 获取关联外键列表
|
// 获取关联外键列表
|
||||||
@@ -70,9 +68,9 @@ class HasMany extends Relation
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($range)) {
|
if (!empty($range)) {
|
||||||
$this->where[$foreignKey] = ['in', $range];
|
$this->where[$this->foreignKey] = ['in', $range];
|
||||||
$data = $this->eagerlyOneToMany($this, [
|
$data = $this->eagerlyOneToMany($this, [
|
||||||
$foreignKey => [
|
$this->foreignKey => [
|
||||||
'in',
|
'in',
|
||||||
$range,
|
$range,
|
||||||
],
|
],
|
||||||
@@ -101,10 +99,9 @@ class HasMany extends Relation
|
|||||||
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
$localKey = $this->localKey;
|
$localKey = $this->localKey;
|
||||||
$foreignKey = $this->foreignKey;
|
|
||||||
|
|
||||||
if (isset($result->$localKey)) {
|
if (isset($result->$localKey)) {
|
||||||
$data = $this->eagerlyOneToMany($this, [$foreignKey => $result->$localKey], $relation, $subRelation, $closure);
|
$data = $this->eagerlyOneToMany($this, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure);
|
||||||
// 关联数据封装
|
// 关联数据封装
|
||||||
if (!isset($data[$result->$localKey])) {
|
if (!isset($data[$result->$localKey])) {
|
||||||
$data[$result->$localKey] = [];
|
$data[$result->$localKey] = [];
|
||||||
@@ -113,6 +110,41 @@ class HasMany extends Relation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$count = 0;
|
||||||
|
if (isset($result->$localKey)) {
|
||||||
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $this->query]);
|
||||||
|
}
|
||||||
|
$count = $this->query->where([$this->foreignKey => $result->$localKey])->count();
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建关联统计子查询
|
||||||
|
* @access public
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRelationCountQuery($closure)
|
||||||
|
{
|
||||||
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $this->query]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->query->where([$this->foreignKey => ['exp', '=' . $this->parent->getTable() . '.' . $this->parent->getPk()]])->fetchSql()->count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一对多 关联模型预查询
|
* 一对多 关联模型预查询
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class HasManyThrough extends Relation
|
|||||||
{
|
{
|
||||||
// 中间关联表外键
|
// 中间关联表外键
|
||||||
protected $throughKey;
|
protected $throughKey;
|
||||||
|
// 中间表模型
|
||||||
|
protected $through;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 架构函数
|
* 架构函数
|
||||||
@@ -37,7 +39,7 @@ class HasManyThrough extends Relation
|
|||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
$this->model = $model;
|
$this->model = $model;
|
||||||
$this->middle = $through;
|
$this->through = $through;
|
||||||
$this->foreignKey = $foreignKey;
|
$this->foreignKey = $foreignKey;
|
||||||
$this->throughKey = $throughKey;
|
$this->throughKey = $throughKey;
|
||||||
$this->localKey = $localKey;
|
$this->localKey = $localKey;
|
||||||
@@ -65,8 +67,7 @@ class HasManyThrough extends Relation
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)
|
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询 返回模型对象
|
* 预载入关联查询 返回模型对象
|
||||||
@@ -79,8 +80,17 @@ class HasManyThrough extends Relation
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行基础查询(进执行一次)
|
* 执行基础查询(进执行一次)
|
||||||
@@ -90,7 +100,7 @@ class HasManyThrough extends Relation
|
|||||||
protected function baseQuery()
|
protected function baseQuery()
|
||||||
{
|
{
|
||||||
if (empty($this->baseQuery)) {
|
if (empty($this->baseQuery)) {
|
||||||
$through = $this->middle;
|
$through = $this->through;
|
||||||
$model = $this->model;
|
$model = $this->model;
|
||||||
$alias = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
$alias = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
||||||
$throughTable = $through::getTable();
|
$throughTable = $through::getTable();
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
namespace think\model\relation;
|
namespace think\model\relation;
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\relation\OneToOne;
|
|
||||||
|
|
||||||
class HasOne extends OneToOne
|
class HasOne extends OneToOne
|
||||||
{
|
{
|
||||||
@@ -73,4 +72,80 @@ class HasOne extends OneToOne
|
|||||||
->join($table . ' b', 'a.' . $this->localKey . '=b.' . $this->foreignKey, $this->joinType)
|
->join($table . ' b', 'a.' . $this->localKey . '=b.' . $this->foreignKey, $this->joinType)
|
||||||
->where($where);
|
->where($where);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预载入关联查询(数据集)
|
||||||
|
* @access public
|
||||||
|
* @param array $resultSet 数据集
|
||||||
|
* @param string $relation 当前关联名
|
||||||
|
* @param string $subRelation 子关联名
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure, $class)
|
||||||
|
{
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$foreignKey = $this->foreignKey;
|
||||||
|
|
||||||
|
$range = [];
|
||||||
|
foreach ($resultSet as $result) {
|
||||||
|
// 获取关联外键列表
|
||||||
|
if (isset($result->$localKey)) {
|
||||||
|
$range[] = $result->$localKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($range)) {
|
||||||
|
$this->where[$foreignKey] = ['in', $range];
|
||||||
|
$data = $this->eagerlyWhere($this, [
|
||||||
|
$foreignKey => [
|
||||||
|
'in',
|
||||||
|
$range,
|
||||||
|
],
|
||||||
|
], $foreignKey, $relation, $subRelation, $closure);
|
||||||
|
|
||||||
|
// 关联数据封装
|
||||||
|
foreach ($resultSet as $result) {
|
||||||
|
if (!isset($data[$result->$localKey])) {
|
||||||
|
$data[$result->$localKey] = [];
|
||||||
|
}
|
||||||
|
$relationModel = $this->resultSetBuild($data[$result->$localKey], $class);
|
||||||
|
if (!empty($this->bindAttr)) {
|
||||||
|
// 绑定关联属性
|
||||||
|
$this->bindAttr($relationModel, $result, $this->bindAttr);
|
||||||
|
}
|
||||||
|
// 设置关联属性
|
||||||
|
$result->setAttr($relation, $relationModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预载入关联查询(数据)
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param string $relation 当前关联名
|
||||||
|
* @param string $subRelation 子关联名
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function eagerlyOne(&$result, $relation, $subRelation, $closure, $class)
|
||||||
|
{
|
||||||
|
$localKey = $this->localKey;
|
||||||
|
$foreignKey = $this->foreignKey;
|
||||||
|
$data = $this->eagerlyWhere($this, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure);
|
||||||
|
// 关联数据封装
|
||||||
|
if (!isset($data[$result->$localKey])) {
|
||||||
|
$data[$result->$localKey] = [];
|
||||||
|
}
|
||||||
|
$relationModel = $this->resultSetBuild($data[$result->$localKey], $class);
|
||||||
|
if (!empty($this->bindAttr)) {
|
||||||
|
// 绑定关联属性
|
||||||
|
$this->bindAttr($relationModel, $result, $this->bindAttr);
|
||||||
|
}
|
||||||
|
$result->setAttr($relation, $relationModel);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,16 +106,48 @@ class MorphMany extends Relation
|
|||||||
*/
|
*/
|
||||||
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
$morphType = $this->morphType;
|
|
||||||
$morphKey = $this->morphKey;
|
|
||||||
$type = $this->type;
|
|
||||||
$pk = $result->getPk();
|
$pk = $result->getPk();
|
||||||
if (isset($result->$pk)) {
|
if (isset($result->$pk)) {
|
||||||
$data = $this->eagerlyMorphToMany([$morphKey => $result->$pk, $morphType => $type], $relation, $subRelation, $closure);
|
$data = $this->eagerlyMorphToMany([$this->morphKey => $result->$pk, $this->morphType => $this->type], $relation, $subRelation, $closure);
|
||||||
$result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class));
|
$result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{
|
||||||
|
$pk = $result->getPk();
|
||||||
|
$count = 0;
|
||||||
|
if (isset($result->$pk)) {
|
||||||
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $this->query]);
|
||||||
|
}
|
||||||
|
$count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count();
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取关联统计子查询
|
||||||
|
* @access public
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRelationCountQuery($closure)
|
||||||
|
{
|
||||||
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $this->query]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->query->where([$this->morphKey => ['exp', '=' . $this->parent->getTable() . '.' . $this->parent->getPk()], $this->morphType => $this->type])->fetchSql()->count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多态一对多 关联模型预查询
|
* 多态一对多 关联模型预查询
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -136,6 +136,16 @@ class MorphTo extends Relation
|
|||||||
$this->eagerlyMorphToOne($model, $relation, $result, $subRelation);
|
$this->eagerlyMorphToOne($model, $relation, $result, $subRelation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多态MorphTo 关联模型预查询
|
* 多态MorphTo 关联模型预查询
|
||||||
* @access public
|
* @access public
|
||||||
|
|||||||
@@ -12,15 +12,20 @@
|
|||||||
namespace think\model\relation;
|
namespace think\model\relation;
|
||||||
|
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
|
use think\Exception;
|
||||||
use think\Loader;
|
use think\Loader;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\Relation;
|
use think\model\Relation;
|
||||||
use think\model\relation\BelongsTo;
|
|
||||||
|
|
||||||
abstract class OneToOne extends Relation
|
abstract class OneToOne extends Relation
|
||||||
{
|
{
|
||||||
|
// 预载入方式
|
||||||
|
protected $eagerlyType = 0;
|
||||||
|
// 要绑定的属性
|
||||||
|
protected $bindAttr = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询
|
* 预载入关联查询(JOIN方式)
|
||||||
* @access public
|
* @access public
|
||||||
* @param Query $query 查询对象
|
* @param Query $query 查询对象
|
||||||
* @param string $relation 关联名
|
* @param string $relation 关联名
|
||||||
@@ -76,7 +81,7 @@ abstract class OneToOne extends Relation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询
|
* 预载入关联查询(数据集)
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $resultSet 数据集
|
* @param array $resultSet 数据集
|
||||||
* @param string $relation 当前关联名
|
* @param string $relation 当前关联名
|
||||||
@@ -85,16 +90,21 @@ abstract class OneToOne extends Relation
|
|||||||
* @param string $class 数据集对象名 为空表示数组
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function eagerlyResultSet(&$resultSet, $relation)
|
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
foreach ($resultSet as $result) {
|
if (1 == $this->eagerlyType) {
|
||||||
|
// IN查询
|
||||||
|
$this->eagerlySet($resultSet, $relation, $subRelation, $closure, $class);
|
||||||
|
} else {
|
||||||
// 模型关联组装
|
// 模型关联组装
|
||||||
|
foreach ($resultSet as $result) {
|
||||||
$this->match($this->model, $relation, $result);
|
$this->match($this->model, $relation, $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预载入关联查询 返回模型对象
|
* 预载入关联查询(数据)
|
||||||
* @access public
|
* @access public
|
||||||
* @param Model $result 数据对象
|
* @param Model $result 数据对象
|
||||||
* @param string $relation 当前关联名
|
* @param string $relation 当前关联名
|
||||||
@@ -103,11 +113,80 @@ abstract class OneToOne extends Relation
|
|||||||
* @param string $class 数据集对象名 为空表示数组
|
* @param string $class 数据集对象名 为空表示数组
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function eagerlyResult(&$result, $relation)
|
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)
|
||||||
{
|
{
|
||||||
|
if (1 == $this->eagerlyType) {
|
||||||
|
// IN查询
|
||||||
|
$this->eagerlyOne($result, $relation, $subRelation, $closure, $class);
|
||||||
|
} else {
|
||||||
// 模型关联组装
|
// 模型关联组装
|
||||||
$this->match($this->model, $relation, $result);
|
$this->match($this->model, $relation, $result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存(新增)当前关联数据对象
|
||||||
|
* @access public
|
||||||
|
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function save($data)
|
||||||
|
{
|
||||||
|
if ($data instanceof Model) {
|
||||||
|
$data = $data->getData();
|
||||||
|
}
|
||||||
|
// 保存关联表数据
|
||||||
|
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
||||||
|
$model = new $this->model;
|
||||||
|
return $model->save($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置预载入方式
|
||||||
|
* @access public
|
||||||
|
* @param integer $type 预载入方式 0 JOIN查询 1 IN查询
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public function setEagerlyType($type)
|
||||||
|
{
|
||||||
|
$this->eagerlyType = $type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取预载入方式
|
||||||
|
* @access public
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getEagerlyType()
|
||||||
|
{
|
||||||
|
return $this->eagerlyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定关联表的属性到父模型属性
|
||||||
|
* @access public
|
||||||
|
* @param mixed $attr 要绑定的属性列表
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public function bind($attr)
|
||||||
|
{
|
||||||
|
if (is_string($attr)) {
|
||||||
|
$attr = explode(',', $attr);
|
||||||
|
}
|
||||||
|
$this->bindAttr = $attr;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联统计
|
||||||
|
* @access public
|
||||||
|
* @param Model $result 数据对象
|
||||||
|
* @param \Closure $closure 闭包
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function relationCount($result, $closure)
|
||||||
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一对一 关联模型预查询拼装
|
* 一对一 关联模型预查询拼装
|
||||||
@@ -129,25 +208,60 @@ abstract class OneToOne extends Relation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isset($list[$relation])) {
|
||||||
$result->setAttr($relation, !isset($list[$relation]) ? null : (new $model($list[$relation]))->isUpdate(true));
|
$relationModel = new $model($list[$relation]);
|
||||||
|
if (!empty($this->bindAttr)) {
|
||||||
|
$this->bindAttr($relationModel, $result, $this->bindAttr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result->setAttr($relation, !isset($relationModel) ? null : $relationModel->isUpdate(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存(新增)当前关联数据对象
|
* 绑定关联属性到父模型
|
||||||
* @access public
|
* @access protected
|
||||||
* @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键
|
* @param Model $model 关联模型对象
|
||||||
* @return integer
|
* @param Model $result 父模型对象
|
||||||
|
* @param array $bindAttr 绑定属性
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function save($data)
|
protected function bindAttr($model, &$result, $bindAttr)
|
||||||
{
|
{
|
||||||
if ($data instanceof Model) {
|
foreach ($bindAttr as $key => $attr) {
|
||||||
$data = $data->getData();
|
$key = is_numeric($key) ? $attr : $key;
|
||||||
|
if (isset($result->$key)) {
|
||||||
|
throw new Exception('bind attr has exists:' . $key);
|
||||||
|
} else {
|
||||||
|
$result->setAttr($key, $model->$attr);
|
||||||
}
|
}
|
||||||
// 保存关联表数据
|
}
|
||||||
$data[$this->foreignKey] = $this->parent->{$this->localKey};
|
}
|
||||||
$model = new $this->model;
|
|
||||||
return $model->save($data);
|
/**
|
||||||
|
* 一对一 关联模型预查询(IN方式)
|
||||||
|
* @access public
|
||||||
|
* @param object $model 关联模型对象
|
||||||
|
* @param array $where 关联预查询条件
|
||||||
|
* @param string $key 关联键名
|
||||||
|
* @param string $relation 关联名
|
||||||
|
* @param string $subRelation 子关联
|
||||||
|
* @param bool $closure
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false)
|
||||||
|
{
|
||||||
|
// 预载入关联查询 支持嵌套预载入
|
||||||
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $model]);
|
||||||
|
}
|
||||||
|
$list = $model->where($where)->with($subRelation)->select();
|
||||||
|
|
||||||
|
// 组装模型数据
|
||||||
|
$data = [];
|
||||||
|
foreach ($list as $set) {
|
||||||
|
$data[$set->$key][] = $set;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ class Bootstrap extends Paginator
|
|||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染分页html
|
* 渲染分页html
|
||||||
* @return mixed
|
* @return mixed
|
||||||
@@ -127,7 +126,6 @@ class Bootstrap extends Paginator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成一个可点击的按钮
|
* 生成一个可点击的按钮
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ use think\Process;
|
|||||||
|
|
||||||
class Builder
|
class Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
private $arguments;
|
private $arguments;
|
||||||
private $cwd;
|
private $cwd;
|
||||||
private $env = null;
|
private $env = null;
|
||||||
|
|||||||
42
core/library/think/process/exception/Failed.php
Normal file
42
core/library/think/process/exception/Failed.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: yunwuxin <448901948@qq.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace think\process\exception;
|
||||||
|
|
||||||
|
use think\Process;
|
||||||
|
|
||||||
|
class Failed extends \RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
private $process;
|
||||||
|
|
||||||
|
public function __construct(Process $process)
|
||||||
|
{
|
||||||
|
if ($process->isSuccessful()) {
|
||||||
|
throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText());
|
||||||
|
|
||||||
|
if (!$process->isOutputDisabled()) {
|
||||||
|
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($error);
|
||||||
|
|
||||||
|
$this->process = $process;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProcess()
|
||||||
|
{
|
||||||
|
return $this->process;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,6 @@ abstract class Pipes
|
|||||||
*/
|
*/
|
||||||
abstract public function areOpen();
|
abstract public function areOpen();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class Unix extends Pipes
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ('' !== $data) {
|
if ('' !== $data) {
|
||||||
if ($type === 'input') {
|
if ('input' === $type) {
|
||||||
$this->inputBuffer .= $data;
|
$this->inputBuffer .= $data;
|
||||||
} else {
|
} else {
|
||||||
$read[$type] = $data;
|
$read[$type] = $data;
|
||||||
@@ -147,7 +147,7 @@ class Unix extends Pipes
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (false === $data || (true === $close && feof($pipe) && '' === $data)) {
|
if (false === $data || (true === $close && feof($pipe) && '' === $data)) {
|
||||||
if ($type === 'input') {
|
if ('input' === $type) {
|
||||||
$this->input = null;
|
$this->input = null;
|
||||||
} else {
|
} else {
|
||||||
fclose($this->pipes[$type]);
|
fclose($this->pipes[$type]);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class Memcache extends SessionHandler
|
|||||||
*/
|
*/
|
||||||
public function read($sessID)
|
public function read($sessID)
|
||||||
{
|
{
|
||||||
return $this->handler->get($this->config['session_name'] . $sessID);
|
return (string) $this->handler->get($this->config['session_name'] . $sessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class Memcached extends SessionHandler
|
|||||||
*/
|
*/
|
||||||
public function read($sessID)
|
public function read($sessID)
|
||||||
{
|
{
|
||||||
return $this->handler->get($this->config['session_name'] . $sessID);
|
return (string) $this->handler->get($this->config['session_name'] . $sessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ class Redis extends SessionHandler
|
|||||||
* 读取Session
|
* 读取Session
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $sessID
|
* @param string $sessID
|
||||||
* @return bool|string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function read($sessID)
|
public function read($sessID)
|
||||||
{
|
{
|
||||||
return $this->handler->get($this->config['session_name'] . $sessID);
|
return (string) $this->handler->get($this->config['session_name'] . $sessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ class Cx extends Taglib
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* U函数的tag标签
|
* url函数的tag标签
|
||||||
* 格式:{url link="模块/控制器/方法" vars="参数" suffix="true或者false 是否带有后缀" domain="true或者false 是否携带域名" /}
|
* 格式:{url link="模块/控制器/方法" vars="参数" suffix="true或者false 是否带有后缀" domain="true或者false 是否携带域名" /}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
|
|||||||
@@ -128,8 +128,6 @@ class Php
|
|||||||
$depr = $this->config['view_depr'];
|
$depr = $this->config['view_depr'];
|
||||||
if (0 !== strpos($template, '/')) {
|
if (0 !== strpos($template, '/')) {
|
||||||
$template = str_replace(['/', ':'], $depr, $template);
|
$template = str_replace(['/', ':'], $depr, $template);
|
||||||
}
|
|
||||||
|
|
||||||
$controller = Loader::parseName($request->controller());
|
$controller = Loader::parseName($request->controller());
|
||||||
if ($controller) {
|
if ($controller) {
|
||||||
if ('' == $template) {
|
if ('' == $template) {
|
||||||
@@ -139,6 +137,9 @@ class Php
|
|||||||
$template = str_replace('.', DS, $controller) . $depr . $template;
|
$template = str_replace('.', DS, $controller) . $depr . $template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$template = str_replace(['/', ':'], $depr, substr($template, 1));
|
||||||
|
}
|
||||||
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,11 +120,10 @@ class Think
|
|||||||
$path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];
|
$path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$controller = Loader::parseName($request->controller());
|
|
||||||
$depr = $this->config['view_depr'];
|
$depr = $this->config['view_depr'];
|
||||||
if (0 !== strpos($template, '/')) {
|
if (0 !== strpos($template, '/')) {
|
||||||
$template = str_replace(['/', ':'], $depr, $template);
|
$template = str_replace(['/', ':'], $depr, $template);
|
||||||
}
|
$controller = Loader::parseName($request->controller());
|
||||||
if ($controller) {
|
if ($controller) {
|
||||||
if ('' == $template) {
|
if ('' == $template) {
|
||||||
// 如果模板文件名为空 按照默认规则定位
|
// 如果模板文件名为空 按照默认规则定位
|
||||||
@@ -133,6 +132,9 @@ class Think
|
|||||||
$template = str_replace('.', DS, $controller) . $depr . $template;
|
$template = str_replace('.', DS, $controller) . $depr . $template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$template = str_replace(['/', ':'], $depr, substr($template, 1));
|
||||||
|
}
|
||||||
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace traits\model;
|
namespace traits\model;
|
||||||
|
|
||||||
|
use think\db\Query;
|
||||||
|
|
||||||
trait SoftDelete
|
trait SoftDelete
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -22,7 +24,7 @@ trait SoftDelete
|
|||||||
/**
|
/**
|
||||||
* 查询软删除数据
|
* 查询软删除数据
|
||||||
* @access public
|
* @access public
|
||||||
* @return \think\db\Query
|
* @return Query
|
||||||
*/
|
*/
|
||||||
public static function withTrashed()
|
public static function withTrashed()
|
||||||
{
|
{
|
||||||
@@ -34,7 +36,7 @@ trait SoftDelete
|
|||||||
/**
|
/**
|
||||||
* 只查询软删除数据
|
* 只查询软删除数据
|
||||||
* @access public
|
* @access public
|
||||||
* @return \think\db\Query
|
* @return Query
|
||||||
*/
|
*/
|
||||||
public static function onlyTrashed()
|
public static function onlyTrashed()
|
||||||
{
|
{
|
||||||
@@ -77,8 +79,8 @@ trait SoftDelete
|
|||||||
*/
|
*/
|
||||||
public static function destroy($data, $force = false)
|
public static function destroy($data, $force = false)
|
||||||
{
|
{
|
||||||
$model = new static();
|
// 包含软删除数据
|
||||||
$query = $model->db();
|
$query = self::withTrashed();
|
||||||
if (is_array($data) && key($data) !== 0) {
|
if (is_array($data) && key($data) !== 0) {
|
||||||
$query->where($data);
|
$query->where($data);
|
||||||
$data = null;
|
$data = null;
|
||||||
@@ -109,15 +111,19 @@ trait SoftDelete
|
|||||||
public function restore($where = [])
|
public function restore($where = [])
|
||||||
{
|
{
|
||||||
$name = $this->getDeleteTimeField();
|
$name = $this->getDeleteTimeField();
|
||||||
|
if (empty($where)) {
|
||||||
|
$pk = $this->getPk();
|
||||||
|
$where[$pk] = $this->getData($pk);
|
||||||
|
$where[$name] = ['not null', ''];
|
||||||
|
}
|
||||||
// 恢复删除
|
// 恢复删除
|
||||||
return $this->isUpdate()->save([$name => null], $where);
|
return $this->db(false)->removeWhereField($this->getDeleteTimeField(true))->where($where)->update([$name => null]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询默认不包含软删除数据
|
* 查询默认不包含软删除数据
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param \think\db\Query $query 查询对象
|
* @param Query $query 查询对象
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function base($query)
|
protected function base($query)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace traits\think;
|
namespace traits\think;
|
||||||
|
|
||||||
use \think\Exception;
|
use think\Exception;
|
||||||
|
|
||||||
trait Instance
|
trait Instance
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user