内核更新

This commit is contained in:
2017-02-14 09:41:34 +08:00
parent 689376a5d9
commit b355535009
43 changed files with 330 additions and 100 deletions

View File

@@ -9,7 +9,7 @@
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
define('THINK_VERSION', '5.0.5'); define('THINK_VERSION', '5.0.6');
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');

View File

@@ -206,7 +206,7 @@ return [
// 是否自动开启 SESSION // 是否自动开启 SESSION
'auto_start' => true, 'auto_start' => true,
'httponly' => true, 'httponly' => true,
'secure' => true, 'secure' => false,
], ],
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------

View File

@@ -64,4 +64,5 @@ return [
'invalid request' => '非法请求', 'invalid request' => '非法请求',
'bind attr has exists' => '模型的属性已经存在', 'bind attr has exists' => '模型的属性已经存在',
'relation data not exists' => '关联数据不存在', 'relation data not exists' => '关联数据不存在',
'relation not support' => '关联不支持',
]; ];

View File

@@ -87,7 +87,7 @@ class Config
return isset(self::$config[$range][strtolower($name)]); return isset(self::$config[$range][strtolower($name)]);
} else { } else {
// 二维数组设置和获取支持 // 二维数组设置和获取支持
$name = explode('.', $name); $name = explode('.', $name, 2);
return isset(self::$config[$range][strtolower($name[0])][$name[1]]); return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
} }
} }
@@ -111,7 +111,7 @@ class Config
return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null; return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;
} else { } else {
// 二维数组设置和获取支持 // 二维数组设置和获取支持
$name = explode('.', $name); $name = explode('.', $name, 2);
$name[0] = strtolower($name[0]); $name[0] = strtolower($name[0]);
return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null; return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null;
} }
@@ -135,7 +135,7 @@ class Config
self::$config[$range][strtolower($name)] = $value; self::$config[$range][strtolower($name)] = $value;
} else { } else {
// 二维数组设置和获取支持 // 二维数组设置和获取支持
$name = explode('.', $name); $name = explode('.', $name, 2);
self::$config[$range][strtolower($name[0])][$name[1]] = $value; self::$config[$range][strtolower($name[0])][$name[1]] = $value;
} }
return; return;

View File

@@ -40,7 +40,7 @@ class Controller
protected $beforeActionList = []; protected $beforeActionList = [];
/** /**
* 架构函数 * 构造方法
* @param Request $request Request对象 * @param Request $request Request对象
* @access public * @access public
*/ */

View File

@@ -14,7 +14,7 @@ namespace think;
use InvalidArgumentException; use InvalidArgumentException;
use think\db\Query; use think\db\Query;
use think\Exception\ValidateException; use think\Exception\ValidateException;
use think\model\Collection; use think\model\Collection as ModelCollection;
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;
@@ -109,7 +109,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
protected static $initialized = []; protected static $initialized = [];
/** /**
* 架构函数 * 构造方法
* @access public * @access public
* @param array|object $data 数据 * @param array|object $data 数据
*/ */
@@ -624,7 +624,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
/** /**
* 转换子模型对象 * 转换子模型对象
* @access protected * @access protected
* @param Model|Collection $model * @param Model|ModelCollection $model
* @param $visible * @param $visible
* @param $hidden * @param $hidden
* @param $key * @param $key
@@ -663,7 +663,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
} }
foreach ($data as $key => $val) { foreach ($data as $key => $val) {
if ($val instanceof Model || $val instanceof Collection) { if ($val instanceof Model || $val instanceof ModelCollection) {
// 关联模型对象 // 关联模型对象
$item[$key] = $this->subToArray($val, $visible, $hidden, $key); $item[$key] = $this->subToArray($val, $visible, $hidden, $key);
} elseif (is_array($val) && reset($val) instanceof Model) { } elseif (is_array($val) && reset($val) instanceof Model) {
@@ -712,14 +712,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
/** /**
* 转换当前模型数据集为数据集对象 * 转换当前模型数据集为数据集对象
* @access public * @access public
* @param array|Collection $collection 数据集 * @param array|\think\Collection $collection 数据集
* @return Collection * @return \think\Collection
*/ */
public function toCollection($collection) public function toCollection($collection)
{ {
if ($this->resultSetType) { if ($this->resultSetType) {
if ('collection' == $this->resultSetType) { if ('collection' == $this->resultSetType) {
$collection = new Collection($collection); $collection = new ModelCollection($collection);
} elseif (false !== strpos($this->resultSetType, '\\')) { } elseif (false !== strpos($this->resultSetType, '\\')) {
$class = $this->resultSetType; $class = $this->resultSetType;
$collection = new $class($collection); $collection = new $class($collection);
@@ -1081,7 +1081,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 删除条件 // 删除条件
$pk = $this->getPk(); $pk = $this->getPk();
if (isset($this->data[$pk])) { if (is_string($pk) && isset($this->data[$pk])) {
$where = [$pk => $this->data[$pk]]; $where = [$pk => $this->data[$pk]];
} elseif (!empty($this->updateWhere)) { } elseif (!empty($this->updateWhere)) {
$where = $this->updateWhere; $where = $this->updateWhere;
@@ -1422,15 +1422,15 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @param mixed $operator 比较操作符 * @param mixed $operator 比较操作符
* @param integer $count 个数 * @param integer $count 个数
* @param string $id 关联表的统计字段 * @param string $id 关联表的统计字段
* @return Model * @return Relation|Query
*/ */
public static function has($relation, $operator = '>=', $count = 1, $id = '*') public static function has($relation, $operator = '>=', $count = 1, $id = '*')
{ {
$model = new static(); $relation = (new static())->$relation();
if (is_array($operator) || $operator instanceof \Closure) { if (is_array($operator) || $operator instanceof \Closure) {
return $model->$relation()->hasWhere($operator); return $relation->hasWhere($operator);
} }
return $model->$relation()->has($operator, $count, $id); return $relation->has($operator, $count, $id);
} }
/** /**
@@ -1438,12 +1438,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @access public * @access public
* @param string $relation 关联方法名 * @param string $relation 关联方法名
* @param mixed $where 查询条件(数组或者闭包) * @param mixed $where 查询条件(数组或者闭包)
* @return Model * @return Relation|Query
*/ */
public static function hasWhere($relation, $where = []) public static function hasWhere($relation, $where = [])
{ {
$model = new static(); return (new static())->$relation()->hasWhere($where);
return $model->$relation()->hasWhere($where);
} }
/** /**
@@ -1483,7 +1482,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$closure = $relation; $closure = $relation;
$relation = $key; $relation = $key;
} }
if (strpos($relation, '.')) { if (is_array($relation)) {
$subRelation = $relation;
$relation = $key;
} elseif (strpos($relation, '.')) {
list($relation, $subRelation) = explode('.', $relation, 2); list($relation, $subRelation) = explode('.', $relation, 2);
} }
$method = Loader::parseName($relation, 1, false); $method = Loader::parseName($relation, 1, false);
@@ -1509,7 +1511,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$closure = $relation; $closure = $relation;
$relation = $key; $relation = $key;
} }
if (strpos($relation, '.')) { if (is_array($relation)) {
$subRelation = $relation;
$relation = $key;
} elseif (strpos($relation, '.')) {
list($relation, $subRelation) = explode('.', $relation, 2); list($relation, $subRelation) = explode('.', $relation, 2);
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
@@ -1535,7 +1540,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$closure = $relation; $closure = $relation;
$relation = $key; $relation = $key;
} }
if (strpos($relation, '.')) { if (is_array($relation)) {
$subRelation = $relation;
$relation = $key;
} elseif (strpos($relation, '.')) {
list($relation, $subRelation) = explode('.', $relation, 2); list($relation, $subRelation) = explode('.', $relation, 2);
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
@@ -1559,10 +1567,16 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if ($relation instanceof \Closure) { if ($relation instanceof \Closure) {
$closure = $relation; $closure = $relation;
$relation = $key; $relation = $key;
} elseif (is_string($key)) {
$name = $relation;
$relation = $key;
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
$count = $this->$relation()->relationCount($result, $closure); $count = $this->$relation()->relationCount($result, $closure);
$result->setAttr(Loader::parseName($relation) . '_count', $count); if (!isset($name)) {
$name = Loader::parseName($relation) . '_count';
}
$result->setAttr($name, $count);
} }
} }

View File

@@ -120,7 +120,7 @@ class Request
protected $isCheckCache; protected $isCheckCache;
/** /**
* 构函数 * 构函数
* @access protected * @access protected
* @param array $options 参数 * @param array $options 参数
*/ */
@@ -1523,13 +1523,13 @@ class Request
} }
} }
// 自动缓存功能 // 自动缓存功能
$key = '__URL__'; $key = md5($this->host()) . '__URL__';
} elseif (strpos($key, '|')) { } elseif (strpos($key, '|')) {
list($key, $fun) = explode('|', $key); list($key, $fun) = explode('|', $key);
} }
// 特殊规则替换 // 特殊规则替换
if (false !== strpos($key, '__')) { if (false !== strpos($key, '__')) {
$key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__'], [$this->module, $this->controller, $this->action, md5($this->url())], $key); $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url())], $key);
} }
if (false !== strpos($key, ':')) { if (false !== strpos($key, ':')) {

View File

@@ -40,7 +40,7 @@ class Response
protected $content = null; protected $content = null;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param mixed $data 输出数据 * @param mixed $data 输出数据
* @param int $code * @param int $code

View File

@@ -232,6 +232,7 @@ class Route
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = []) public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [])
{ {
$group = self::getGroup('name'); $group = self::getGroup('name');
if (!is_null($group)) { if (!is_null($group)) {
// 路由分组 // 路由分组
$option = array_merge(self::getGroup('option'), $option); $option = array_merge(self::getGroup('option'), $option);
@@ -304,8 +305,12 @@ class Route
} }
$vars = self::parseVar($rule); $vars = self::parseVar($rule);
if (isset($name)) { if (isset($name)) {
$key = $group ? $group . ($rule ? '/' . $rule : '') : $rule; $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
self::name($name, [$key, $vars, self::$domain]); $suffix = isset($option['ext']) ? $option['ext'] : null;
self::name($name, [$key, $vars, self::$domain, $suffix]);
}
if (isset($option['modular'])) {
$route = $option['modular'] . '/' . $route;
} }
if ($group) { if ($group) {
if ('*' != $type) { if ('*' != $type) {
@@ -447,7 +452,8 @@ class Route
$vars = self::parseVar($key); $vars = self::parseVar($key);
$item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns]; $item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns];
// 设置路由标识 // 设置路由标识
self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain]); $suffix = isset($options['ext']) ? $options['ext'] : null;
self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain, $suffix]);
} }
self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern]; self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
} }
@@ -1126,8 +1132,8 @@ class Route
|| (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测 || (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测
|| (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测 || (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测
|| (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测 || (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测
|| (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', $request->ext() ? '|' . $request->ext() . '|' : '')) // 伪静态后缀检测 || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) // 伪静态后缀检测
|| (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', $request->ext() ? '|' . $request->ext() . '|' : '')) || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|'))
|| (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测 || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测
|| (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测 || (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测
|| (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测 || (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测
@@ -1164,7 +1170,7 @@ class Route
$len1 = substr_count($url, '|'); $len1 = substr_count($url, '|');
$len2 = substr_count($rule, '/'); $len2 = substr_count($rule, '/');
// 多余参数是否合并 // 多余参数是否合并
$merge = !empty($option['merge_extra_vars']) ? true : false; $merge = !empty($option['merge_extra_vars']);
if ($merge && $len1 > $len2) { if ($merge && $len1 > $len2) {
$url = str_replace('|', $depr, $url); $url = str_replace('|', $depr, $url);
$url = implode('|', explode($depr, $url, $len2 + 1)); $url = implode('|', explode($depr, $url, $len2 + 1));

View File

@@ -57,7 +57,7 @@ class Template
protected $storage; protected $storage;
/** /**
* 构函数 * 构函数
* @access public * @access public
*/ */
public function __construct(array $config = []) public function __construct(array $config = [])

View File

@@ -80,6 +80,9 @@ class Url
if (!empty($match[1])) { if (!empty($match[1])) {
$domain = $match[1]; $domain = $match[1];
} }
if (!is_null($match[2])) {
$suffix = $match[2];
}
} elseif (!empty($rule) && isset($name)) { } elseif (!empty($rule) && isset($name)) {
throw new \InvalidArgumentException('route name not exists:' . $name); throw new \InvalidArgumentException('route name not exists:' . $name);
} else { } else {
@@ -288,18 +291,18 @@ class Url
public static function getRuleUrl($rule, &$vars = []) public static function getRuleUrl($rule, &$vars = [])
{ {
foreach ($rule as $item) { foreach ($rule as $item) {
list($url, $pattern, $domain) = $item; list($url, $pattern, $domain, $suffix) = $item;
if (empty($pattern)) { if (empty($pattern)) {
return [$url, $domain]; return [$url, $domain, $suffix];
} }
foreach ($pattern as $key => $val) { foreach ($pattern as $key => $val) {
if (isset($vars[$key])) { if (isset($vars[$key])) {
$url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url); $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url);
unset($vars[$key]); unset($vars[$key]);
$result = [$url, $domain]; $result = [$url, $domain, $suffix];
} elseif (2 == $val) { } elseif (2 == $val) {
$url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
$result = [$url, $domain]; $result = [$url, $domain, $suffix];
} else { } else {
break; break;
} }

View File

@@ -102,7 +102,7 @@ class Validate
protected $batch = false; protected $batch = false;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param array $rules 验证规则 * @param array $rules 验证规则
* @param array $message 验证提示信息 * @param array $message 验证提示信息

View File

@@ -25,7 +25,7 @@ class View
protected $replace = []; protected $replace = [];
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param array $engine 模板引擎参数 * @param array $engine 模板引擎参数
* @param array $replace 字符串替换参数 * @param array $replace 字符串替换参数

View File

@@ -28,7 +28,7 @@ class File extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options * @param array $options
*/ */
public function __construct($options = []) public function __construct($options = [])
@@ -225,6 +225,7 @@ class File extends Driver
foreach ($files as $path) { foreach ($files as $path) {
if (is_dir($path)) { if (is_dir($path)) {
array_map('unlink', glob($path . '/*.php')); array_map('unlink', glob($path . '/*.php'));
rmdir($path);
} else { } else {
unlink($path); unlink($path);
} }

View File

@@ -26,7 +26,7 @@ class Lite extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @access public * @access public
* *
* @param array $options * @param array $options

View File

@@ -25,7 +25,7 @@ class Memcache extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @access public * @access public
* @throws \BadFunctionCallException * @throws \BadFunctionCallException

View File

@@ -27,7 +27,7 @@ class Memcached extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @access public * @access public
*/ */

View File

@@ -34,7 +34,7 @@ class Redis extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @access public * @access public
*/ */

View File

@@ -28,7 +28,7 @@ class Sqlite extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @throws \BadFunctionCallException * @throws \BadFunctionCallException
* @access public * @access public

View File

@@ -25,7 +25,7 @@ class Wincache extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @throws \BadFunctionCallException * @throws \BadFunctionCallException
* @access public * @access public

View File

@@ -25,7 +25,7 @@ class Xcache extends Driver
]; ];
/** /**
* 构函数 * 构函数
* @param array $options 缓存参数 * @param array $options 缓存参数
* @access public * @access public
* @throws \BadFunctionCallException * @throws \BadFunctionCallException

View File

@@ -32,7 +32,7 @@ abstract class Rest
]; ];
/** /**
* 构函数 取得模板对象实例 * 构函数 取得模板对象实例
* @access public * @access public
*/ */
public function __construct() public function __construct()

View File

@@ -18,7 +18,7 @@ abstract class Yar
{ {
/** /**
* 构函数 * 构函数
* @access public * @access public
*/ */
public function __construct() public function __construct()

View File

@@ -32,7 +32,7 @@ abstract class Builder
protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Connection $connection 数据库连接对象实例 * @param Connection $connection 数据库连接对象实例
* @param Query $query 数据库查询对象实例 * @param Query $query 数据库查询对象实例

View File

@@ -125,7 +125,7 @@ abstract class Connection
protected $bind = []; protected $bind = [];
/** /**
* 构函数 读取数据库配置信息 * 构函数 读取数据库配置信息
* @access public * @access public
* @param array $config 数据库配置数组 * @param array $config 数据库配置数组
*/ */
@@ -365,8 +365,8 @@ abstract class Connection
$this->bind = $bind; $this->bind = $bind;
} }
//释放前次的查询结果 // 释放前次的查询结果
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { if (!empty($this->PDOStatement)) {
$this->free(); $this->free();
} }

View File

@@ -54,7 +54,7 @@ class Query
private static $event = []; private static $event = [];
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Connection $connection 数据库对象实例 * @param Connection $connection 数据库对象实例
* @param string $model 模型名 * @param string $model 模型名
@@ -869,7 +869,7 @@ class Query
public function view($join, $field = true, $on = null, $type = 'INNER') public function view($join, $field = true, $on = null, $type = 'INNER')
{ {
$this->options['view'] = true; $this->options['view'] = true;
if (is_array($join) && is_null($field)) { if (is_array($join) && key($join) !== 0) {
foreach ($join as $key => $val) { foreach ($join as $key => $val) {
$this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER');
} }
@@ -2065,8 +2065,10 @@ class Query
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
$lastInsId = $this->getLastInsID($sequence); $lastInsId = $this->getLastInsID($sequence);
if ($lastInsId) { if ($lastInsId) {
$pk = $this->getPk($options); $pk = $this->getPk($options);
$data[$pk] = $lastInsId; if (is_string($pk)) {
$data[$pk] = $lastInsId;
}
} }
$options['data'] = $data; $options['data'] = $data;
$this->trigger('after_insert', $options); $this->trigger('after_insert', $options);
@@ -2202,6 +2204,8 @@ class Query
if (isset($key) && Cache::get($key)) { if (isset($key) && Cache::get($key)) {
// 删除缓存 // 删除缓存
Cache::rm($key); Cache::rm($key);
} elseif (!empty($options['cache']['tag'])) {
Cache::clear($options['cache']['tag']);
} }
// 执行操作 // 执行操作
$result = '' == $sql ? 0 : $this->execute($sql, $bind); $result = '' == $sql ? 0 : $this->execute($sql, $bind);
@@ -2375,6 +2379,8 @@ class Query
} }
if (isset($data)) { if (isset($data)) {
return 'think:' . $options['table'] . '|' . $data; return 'think:' . $options['table'] . '|' . $data;
} else {
return md5(serialize($options));
} }
} }
@@ -2412,8 +2418,10 @@ class Query
$cache = $options['cache']; $cache = $options['cache'];
if (true === $cache['key'] && !is_null($data) && !is_array($data)) { if (true === $cache['key'] && !is_null($data) && !is_array($data)) {
$key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
} elseif (is_string($cache['key'])) {
$key = $cache['key'];
} elseif (!isset($key)) { } elseif (!isset($key)) {
$key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); $key = md5(serialize($options));
} }
$result = Cache::get($key); $result = Cache::get($key);
} }
@@ -2644,6 +2652,8 @@ class Query
if (isset($key) && Cache::get($key)) { if (isset($key) && Cache::get($key)) {
// 删除缓存 // 删除缓存
Cache::rm($key); Cache::rm($key);
} elseif (!empty($options['cache']['tag'])) {
Cache::clear($options['cache']['tag']);
} }
// 执行操作 // 执行操作
$result = $this->execute($sql, $bind); $result = $this->execute($sql, $bind);

View File

@@ -38,6 +38,8 @@ class Mysql extends Builder
list($table, $key) = explode('.', $key, 2); list($table, $key) = explode('.', $key, 2);
if (isset($options['alias'][$table])) { if (isset($options['alias'][$table])) {
$table = $options['alias'][$table]; $table = $options['alias'][$table];
} elseif ('__TABLE__' == $table) {
$table = $this->query->getTable();
} }
} }
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {

View File

@@ -57,6 +57,8 @@ class Pgsql extends Builder
list($table, $key) = explode('.', $key, 2); list($table, $key) = explode('.', $key, 2);
if (isset($options['alias'][$table])) { if (isset($options['alias'][$table])) {
$table = $options['alias'][$table]; $table = $options['alias'][$table];
} elseif ('__TABLE__' == $table) {
$table = $this->query->getTable();
} }
} }
if (isset($table)) { if (isset($table)) {

View File

@@ -62,6 +62,8 @@ class Sqlite extends Builder
list($table, $key) = explode('.', $key, 2); list($table, $key) = explode('.', $key, 2);
if (isset($options['alias'][$table])) { if (isset($options['alias'][$table])) {
$table = $options['alias'][$table]; $table = $options['alias'][$table];
} elseif ('__TABLE__' == $table) {
$table = $this->query->getTable();
} }
} }
if (isset($table)) { if (isset($table)) {

View File

@@ -75,6 +75,8 @@ class Sqlsrv extends Builder
list($table, $key) = explode('.', $key, 2); list($table, $key) = explode('.', $key, 2);
if (isset($options['alias'][$table])) { if (isset($options['alias'][$table])) {
$table = $options['alias'][$table]; $table = $options['alias'][$table];
} elseif ('__TABLE__' == $table) {
$table = $this->query->getTable();
} }
} }
if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {

View File

@@ -43,7 +43,7 @@ class Socket
protected $allowForceClientIds = []; //配置强制推送且被授权的client_id protected $allowForceClientIds = []; //配置强制推送且被授权的client_id
/** /**
* 构函数 * 构函数
* @param array $config 缓存参数 * @param array $config 缓存参数
* @access public * @access public
*/ */

View File

@@ -22,7 +22,7 @@ class Merge extends Model
protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' )
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param array|object $data 数据 * @param array|object $data 数据
*/ */

View File

@@ -17,7 +17,7 @@ class Pivot extends Model
{ {
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param array|object $data 数据 * @param array|object $data 数据
* @param string $table 中间数据表名 * @param string $table 中间数据表名

View File

@@ -17,7 +17,7 @@ use think\Model;
class BelongsTo extends OneToOne class BelongsTo extends OneToOne
{ {
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名
@@ -51,6 +51,45 @@ class BelongsTo extends OneToOne
return $this->query->where($this->localKey, $this->parent->$foreignKey)->relation($subRelation)->find(); return $this->query->where($this->localKey, $this->parent->$foreignKey)->relation($subRelation)->find();
} }
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @return Query
*/
public function has($operator = '>=', $count = 1, $id = '*')
{
return $this->parent;
}
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @return Query
*/
public function hasWhere($where = [])
{
$table = $this->query->getTable();
$model = basename(str_replace('\\', '/', get_class($this->parent)));
$relation = basename(str_replace('\\', '/', $this->model));
if (is_array($where)) {
foreach ($where as $key => $val) {
if (false === strpos($key, '.')) {
$where[$relation . '.' . $key] = $val;
unset($where[$key]);
}
}
}
return $this->parent->db()->alias($model)
->field($model . '.*')
->join($table . ' ' . $relation, $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType)
->where($where);
}
/** /**
* 预载入关联查询(数据集) * 预载入关联查询(数据集)
* @access public * @access public
@@ -85,10 +124,10 @@ class BelongsTo extends OneToOne
// 关联数据封装 // 关联数据封装
foreach ($resultSet as $result) { foreach ($resultSet as $result) {
// 关联模型 // 关联模型
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$foreignKey])) {
$relationModel = null; $relationModel = null;
} else { } else {
$relationModel = $data[$result->$localKey]; $relationModel = $data[$result->$foreignKey];
} }
if ($relationModel && !empty($this->bindAttr)) { if ($relationModel && !empty($this->bindAttr)) {
@@ -116,10 +155,10 @@ class BelongsTo extends OneToOne
$foreignKey = $this->foreignKey; $foreignKey = $this->foreignKey;
$data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); $data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure);
// 关联模型 // 关联模型
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$foreignKey])) {
$relationModel = null; $relationModel = null;
} else { } else {
$relationModel = $data[$result->$localKey]; $relationModel = $data[$result->$foreignKey];
} }
if ($relationModel && !empty($this->bindAttr)) { if ($relationModel && !empty($this->bindAttr)) {
// 绑定关联属性 // 绑定关联属性

View File

@@ -24,7 +24,7 @@ class BelongsToMany extends Relation
protected $middle; protected $middle;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名
@@ -76,6 +76,31 @@ class BelongsToMany extends Relation
return $result; return $result;
} }
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @return Query
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
return $this->parent;
}
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @return Query
*/
public function hasWhere($where = [])
{
throw new Exception('relation not support: hasWhere');
}
/** /**
* 预载入关联查询(数据集) * 预载入关联查询(数据集)
* @access public * @access public

View File

@@ -20,7 +20,7 @@ use think\model\Relation;
class HasMany extends Relation class HasMany extends Relation
{ {
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名

View File

@@ -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\Loader; use think\Loader;
use think\Model; use think\Model;
use think\model\Relation; use think\model\Relation;
@@ -25,7 +26,7 @@ class HasManyThrough extends Relation
protected $through; protected $through;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名
@@ -54,11 +55,36 @@ class HasManyThrough extends Relation
public function getRelation($subRelation = '', $closure = null) public function getRelation($subRelation = '', $closure = null)
{ {
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
return $this->relation($subRelation)->select(); return $this->relation($subRelation)->select();
} }
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @return Query
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
return $this->parent;
}
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @return Query
*/
public function hasWhere($where = [])
{
throw new Exception('relation not support: hasWhere');
}
/** /**
* 预载入关联查询 * 预载入关联查询
* @access public * @access public

View File

@@ -18,7 +18,7 @@ use think\Model;
class HasOne extends OneToOne class HasOne extends OneToOne
{ {
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名
@@ -47,12 +47,28 @@ class HasOne extends OneToOne
// 执行关联定义方法 // 执行关联定义方法
$localKey = $this->localKey; $localKey = $this->localKey;
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
// 判断关联类型执行查询 // 判断关联类型执行查询
return $this->query->where($this->foreignKey, $this->parent->$localKey)->relation($subRelation)->find(); return $this->query->where($this->foreignKey, $this->parent->$localKey)->relation($subRelation)->find();
} }
/**
* 根据关联条件查询当前模型
* @access public
* @return Query
*/
public function has()
{
$table = $this->query->getTable();
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
return $this->parent->db()->alias('a')
->whereExists(function ($query) use ($table, $localKey, $foreignKey) {
$query->table([$table => 'b'])->field('b.' . $foreignKey)->whereExp('a.' . $localKey, '=b.' . $foreignKey);
});
}
/** /**
* 根据关联条件查询当前模型 * 根据关联条件查询当前模型
* @access public * @access public

View File

@@ -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\Loader; use think\Loader;
use think\Model; use think\Model;
use think\model\Relation; use think\model\Relation;
@@ -26,7 +27,7 @@ class MorphMany extends Relation
protected $type; protected $type;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $model 模型名 * @param string $model 模型名
@@ -53,11 +54,36 @@ class MorphMany extends Relation
public function getRelation($subRelation = '', $closure = null) public function getRelation($subRelation = '', $closure = null)
{ {
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
return $this->relation($subRelation)->select(); return $this->relation($subRelation)->select();
} }
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @return Query
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
throw new Exception('relation not support: has');
}
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @return Query
*/
public function hasWhere($where = [])
{
throw new Exception('relation not support: hasWhere');
}
/** /**
* 预载入关联查询 * 预载入关联查询
* @access public * @access public
@@ -113,7 +139,7 @@ class MorphMany extends Relation
if (isset($result->$pk)) { if (isset($result->$pk)) {
$data = $this->eagerlyMorphToMany([ $data = $this->eagerlyMorphToMany([
$this->morphKey => $result->$pk, $this->morphKey => $result->$pk,
$this->morphType => $this->type $this->morphType => $this->type,
], $relation, $subRelation, $closure); ], $relation, $subRelation, $closure);
$result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); $result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk]));
} }
@@ -132,7 +158,7 @@ class MorphMany extends Relation
$count = 0; $count = 0;
if (isset($result->$pk)) { if (isset($result->$pk)) {
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
$count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count(); $count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count();
} }
@@ -148,15 +174,15 @@ class MorphMany extends Relation
public function getRelationCountQuery($closure) public function getRelationCountQuery($closure)
{ {
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this->query]); call_user_func_array($closure, [ & $this->query]);
} }
return $this->query->where([ return $this->query->where([
$this->morphKey => [ $this->morphKey => [
'exp', 'exp',
'=' . $this->parent->getTable() . '.' . $this->parent->getPk() '=' . $this->parent->getTable() . '.' . $this->parent->getPk(),
], ],
$this->morphType => $this->type $this->morphType => $this->type,
])->fetchSql()->count(); ])->fetchSql()->count();
} }
@@ -173,7 +199,7 @@ class MorphMany extends Relation
{ {
// 预载入关联查询 支持嵌套预载入 // 预载入关联查询 支持嵌套预载入
if ($closure) { if ($closure) {
call_user_func_array($closure, [& $this]); call_user_func_array($closure, [ & $this]);
} }
$list = $this->query->where($where)->with($subRelation)->select(); $list = $this->query->where($where)->with($subRelation)->select();
$morphKey = $this->morphKey; $morphKey = $this->morphKey;

View File

@@ -25,7 +25,7 @@ class MorphTo extends Relation
protected $alias; protected $alias;
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param Model $parent 上级模型对象 * @param Model $parent 上级模型对象
* @param string $morphType 多态字段名 * @param string $morphType 多态字段名
@@ -57,6 +57,31 @@ class MorphTo extends Relation
return (new $model)->relation($subRelation)->find($pk); return (new $model)->relation($subRelation)->find($pk);
} }
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @return Query
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
return $this->parent;
}
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @return Query
*/
public function hasWhere($where = [])
{
throw new Exception('relation not support: hasWhere');
}
/** /**
* 解析模型的完整命名空间 * 解析模型的完整命名空间
* @access public * @access public

View File

@@ -68,7 +68,7 @@ class TagLib
protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < ']; protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < '];
/** /**
* 构函数 * 构函数
* @access public * @access public
* @param \stdClass $template 模板引擎对象 * @param \stdClass $template 模板引擎对象
*/ */

View File

@@ -142,7 +142,7 @@ trait SoftDelete
{ {
$field = isset($this->deleteTime) ? $this->deleteTime : 'delete_time'; $field = isset($this->deleteTime) ? $this->deleteTime : 'delete_time';
if (!strpos($field, '.')) { if (!strpos($field, '.')) {
$field = $this->db(false)->getTable() . '.' . $field; $field = '__TABLE__.' . $field;
} }
if (!$read && strpos($field, '.')) { if (!$read && strpos($field, '.')) {
$array = explode('.', $field); $array = explode('.', $field);

View File

@@ -79,15 +79,17 @@
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>系统发生错误</title> <title><?php echo lang('System Error'); ?></title>
<meta name="robots" content="noindex,nofollow" /> <meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style> <style>
/* Base */ /* Base */
body { body {
color: #333; color: #333;
font: 16px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif; font: 14px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif;
margin: 0; margin: 0;
padding: 0 20px 20px; padding: 0 20px 20px;
word-break: break-word;
} }
h1{ h1{
margin: 10px 0 0; margin: 10px 0 0;
@@ -103,6 +105,11 @@
font-size: 18px; font-size: 18px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
h3.subheading {
color: #4288ce;
margin: 6px 0 0;
font-weight: 400;
}
h3{ h3{
margin: 12px; margin: 12px;
font-size: 16px; font-size: 16px;
@@ -143,7 +150,27 @@
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
/* Layout */
.col-md-3 {
width: 25%;
}
.col-md-9 {
width: 75%;
}
[class^="col-md-"] {
float: left;
}
.clearfix {
clear:both;
}
@media only screen
and (min-device-width : 375px)
and (max-device-width : 667px) {
.col-md-3,
.col-md-9 {
width: 100%;
}
}
/* Exception Info */ /* Exception Info */
.exception { .exception {
margin-top: 20px; margin-top: 20px;
@@ -378,16 +405,19 @@
<div class="exception-var"> <div class="exception-var">
<h2>Environment Variables</h2> <h2>Environment Variables</h2>
<?php foreach ((array) $tables as $label => $value) { ?> <?php foreach ((array) $tables as $label => $value) { ?>
<table> <div>
<?php if(empty($value)){ ?> <?php if(empty($value)){ ?>
<caption><?php echo $label; ?><small>empty</small></caption> <div class="clearfix">
<div class="col-md-3"><strong><?php echo $label; ?></strong></div>
<div class="col-md-9"><small>empty</small></div>
</div>
<?php } else { ?> <?php } else { ?>
<caption><?php echo $label; ?></caption> <h3 class="subheading"><?php echo $label; ?></h3>
<tbody> <div>
<?php foreach ((array) $value as $key => $val) { ?> <?php foreach ((array) $value as $key => $val) { ?>
<tr> <div class="clearfix">
<td><?php echo htmlentities($key); ?></td> <div class="col-md-3"><strong><?php echo htmlentities($key); ?></strong></div>
<td> <div class="col-md-9"><small>
<?php <?php
if(is_array($val) || is_object($val)){ if(is_array($val) || is_object($val)){
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT)); echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
@@ -399,12 +429,12 @@
echo 'Resource'; echo 'Resource';
} }
?> ?>
</td> </small></div>
</tr> </div>
<?php } ?> <?php } ?>
</tbody> </div>
<?php } ?> <?php } ?>
</table> </div>
<?php } ?> <?php } ?>
</div> </div>
<?php } ?> <?php } ?>