diff --git a/composer.lock b/composer.lock index f8b434f8f..5557c32ab 100644 --- a/composer.lock +++ b/composer.lock @@ -17,7 +17,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/ivanlanin/pclzip/19dd1de9d3f5fc4d7d70175b4c344dee329f45fd.zip", + "url": "https://files.phpcomposer.com/files/ivanlanin/pclzip/19dd1de9d3f5fc4d7d70175b4c344dee329f45fd.zip", "reference": "19dd1de9d3f5fc4d7d70175b4c344dee329f45fd", "shasum": "" }, @@ -54,7 +54,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/qiniu/php-sdk/b91653485e36b4797d7a302cc86c49695e47a642.zip", + "url": "https://files.phpcomposer.com/files/qiniu/php-sdk/b91653485e36b4797d7a302cc86c49695e47a642.zip", "reference": "b91653485e36b4797d7a302cc86c49695e47a642", "shasum": "" }, @@ -97,16 +97,16 @@ }, { "name": "topthink/framework", - "version": "v5.0.6", + "version": "v5.0.7", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "a3a37e6cfad132d5b02ffff8f23a4abc565f7928" + "reference": "bcf64f19f4fadbff6c8503891689ff7e6f2fe9a3" }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/framework/a3a37e6cfad132d5b02ffff8f23a4abc565f7928.zip", - "reference": "a3a37e6cfad132d5b02ffff8f23a4abc565f7928", + "url": "https://files.phpcomposer.com/files/top-think/framework/bcf64f19f4fadbff6c8503891689ff7e6f2fe9a3.zip", + "reference": "bcf64f19f4fadbff6c8503891689ff7e6f2fe9a3", "shasum": "" }, "require": { @@ -144,7 +144,7 @@ "orm", "thinkphp" ], - "time": "2017-02-07 09:39:59" + "time": "2017-02-25 02:51:57" }, { "name": "topthink/think-captcha", @@ -156,7 +156,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/think-captcha/0c55455df26a1626a60d0dc35d2d89002b741d44.zip", + "url": "https://files.phpcomposer.com/files/top-think/think-captcha/0c55455df26a1626a60d0dc35d2d89002b741d44.zip", "reference": "0c55455df26a1626a60d0dc35d2d89002b741d44", "shasum": "" }, @@ -192,7 +192,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/think-helper/ed64408cdc4cdbd390365ba0906d208b987af520.zip", + "url": "https://files.phpcomposer.com/files/top-think/think-helper/ed64408cdc4cdbd390365ba0906d208b987af520.zip", "reference": "ed64408cdc4cdbd390365ba0906d208b987af520", "shasum": "" }, @@ -228,7 +228,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/think-installer/4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d.zip", + "url": "https://files.phpcomposer.com/files/top-think/think-installer/4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d.zip", "reference": "4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d", "shasum": "" }, @@ -261,16 +261,16 @@ }, { "name": "topthink/think-mongo", - "version": "v1.5", + "version": "v1.6", "source": { "type": "git", "url": "https://github.com/top-think/think-mongo.git", - "reference": "2dd7ecae965cd3a6e5cc99f3db7c63353dae4cf3" + "reference": "1c6d29f58bd7caa8da088c167b4e65ddac621588" }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/think-mongo/2dd7ecae965cd3a6e5cc99f3db7c63353dae4cf3.zip", - "reference": "2dd7ecae965cd3a6e5cc99f3db7c63353dae4cf3", + "url": "https://files.phpcomposer.com/files/top-think/think-mongo/1c6d29f58bd7caa8da088c167b4e65ddac621588.zip", + "reference": "1c6d29f58bd7caa8da088c167b4e65ddac621588", "shasum": "" }, "type": "library", @@ -291,20 +291,20 @@ } ], "description": "mongodb driver for thinkphp5", - "time": "2017-02-06 06:05:55" + "time": "2017-02-13 07:17:51" }, { "name": "topthink/think-queue", - "version": "v1.1.2", + "version": "v1.1.3", "source": { "type": "git", "url": "https://github.com/top-think/think-queue.git", - "reference": "503c5b809585ca60cba9485a233aa8be4b22c990" + "reference": "07480c36381344bef9db9c9bbe3de28005a839d3" }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/top-think/think-queue/503c5b809585ca60cba9485a233aa8be4b22c990.zip", - "reference": "503c5b809585ca60cba9485a233aa8be4b22c990", + "url": "https://files.phpcomposer.com/files/top-think/think-queue/07480c36381344bef9db9c9bbe3de28005a839d3.zip", + "reference": "07480c36381344bef9db9c9bbe3de28005a839d3", "shasum": "" }, "require": { @@ -336,7 +336,7 @@ } ], "description": "The ThinkPHP5 Queue Package", - "time": "2016-12-01 04:29:39" + "time": "2017-02-28 08:07:37" }, { "name": "zoujingli/wechat-php-sdk", @@ -348,7 +348,7 @@ }, "dist": { "type": "zip", - "url": "https://packagist.phpcomposer.com/files/zoujingli/wechat-php-sdk/12759d48867aab14e6b66be81a5b5afe223a0476.zip", + "url": "https://files.phpcomposer.com/files/zoujingli/wechat-php-sdk/12759d48867aab14e6b66be81a5b5afe223a0476.zip", "reference": "12759d48867aab14e6b66be81a5b5afe223a0476", "shasum": "" }, diff --git a/thinkphp/README.md b/thinkphp/README.md index ae2090288..4b0eb838f 100644 --- a/thinkphp/README.md +++ b/thinkphp/README.md @@ -32,7 +32,7 @@ ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PH > ThinkPHP5的运行环境要求PHP5.4以上。 -详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) +详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart) ## 目录结构 diff --git a/thinkphp/base.php b/thinkphp/base.php index 63fc16c36..9520a92f3 100644 --- a/thinkphp/base.php +++ b/thinkphp/base.php @@ -9,7 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- -define('THINK_VERSION', '5.0.6'); +define('THINK_VERSION', '5.0.7'); define('THINK_START_TIME', microtime(true)); define('THINK_START_MEM', memory_get_usage()); define('EXT', '.php'); diff --git a/thinkphp/console.php b/thinkphp/console.php index fa7778011..578e4a7c4 100644 --- a/thinkphp/console.php +++ b/thinkphp/console.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006-2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/convention.php b/thinkphp/convention.php index b6f23e28f..887b076d5 100644 --- a/thinkphp/convention.php +++ b/thinkphp/convention.php @@ -206,7 +206,7 @@ return [ // 是否自动开启 SESSION 'auto_start' => true, 'httponly' => true, - 'secure' => true, + 'secure' => false, ], // +---------------------------------------------------------------------- diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php index b837bc410..c6c5a50f5 100644 --- a/thinkphp/lang/zh-cn.php +++ b/thinkphp/lang/zh-cn.php @@ -64,4 +64,5 @@ return [ 'invalid request' => '非法请求', 'bind attr has exists' => '模型的属性已经存在', 'relation data not exists' => '关联数据不存在', + 'relation not support' => '关联不支持', ]; diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php index fc6c50ac8..2b8084349 100644 --- a/thinkphp/library/think/Config.php +++ b/thinkphp/library/think/Config.php @@ -87,7 +87,7 @@ class Config return isset(self::$config[$range][strtolower($name)]); } else { // 二维数组设置和获取支持 - $name = explode('.', $name); + $name = explode('.', $name, 2); 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; } else { // 二维数组设置和获取支持 - $name = explode('.', $name); + $name = explode('.', $name, 2); $name[0] = strtolower($name[0]); 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; } else { // 二维数组设置和获取支持 - $name = explode('.', $name); + $name = explode('.', $name, 2); self::$config[$range][strtolower($name[0])][$name[1]] = $value; } return; diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php index 69db0a1d1..7aba39cd1 100644 --- a/thinkphp/library/think/Controller.php +++ b/thinkphp/library/think/Controller.php @@ -40,7 +40,7 @@ class Controller protected $beforeActionList = []; /** - * 架构函数 + * 构造方法 * @param Request $request Request对象 * @access public */ diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php index 70de31753..a0727fef5 100644 --- a/thinkphp/library/think/Loader.php +++ b/thinkphp/library/think/Loader.php @@ -369,8 +369,9 @@ class Loader if (isset(self::$instance[$guid])) { return self::$instance[$guid]; } - if (strpos($name, '\\')) { - $class = $name; + if (false !== strpos($name, '\\')) { + $class = $name; + $module = Request::instance()->module(); } else { if (strpos($name, '/')) { list($module, $name) = explode('/', $name, 2); @@ -404,8 +405,9 @@ class Loader */ public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '') { - if (strpos($name, '\\')) { - $class = $name; + if (false !== strpos($name, '\\')) { + $class = $name; + $module = Request::instance()->module(); } else { if (strpos($name, '/')) { list($module, $name) = explode('/', $name); @@ -440,8 +442,9 @@ class Loader if (isset(self::$instance[$guid])) { return self::$instance[$guid]; } - if (strpos($name, '\\')) { - $class = $name; + if (false !== strpos($name, '\\')) { + $class = $name; + $module = Request::instance()->module(); } else { if (strpos($name, '/')) { list($module, $name) = explode('/', $name); diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index 4a73bf39c..8aa468c14 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -14,7 +14,7 @@ namespace think; use InvalidArgumentException; use think\db\Query; use think\Exception\ValidateException; -use think\model\Collection; +use think\model\Collection as ModelCollection; use think\model\Relation; use think\model\relation\BelongsTo; use think\model\relation\BelongsToMany; @@ -109,7 +109,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected static $initialized = []; /** - * 架构函数 + * 构造方法 * @access public * @param array|object $data 数据 */ @@ -290,9 +290,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } // 标记字段更改 - if (isset($this->data[$name]) && is_scalar($this->data[$name]) && is_scalar($value) && 0 !== strcmp($this->data[$name], $value)) { + if (!isset($this->data[$name])) { $this->change[] = $name; - } elseif (!isset($this->data[$name]) || $value != $this->data[$name]) { + } elseif (is_scalar($value) && is_scalar($this->data[$name]) && 0 !== strcmp($this->data[$name], $value)) { + $this->change[] = $name; + } elseif (!is_object($value) && $value != $this->data[$name]) { $this->change[] = $name; } // 设置数据对象属性 @@ -508,7 +510,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $value = json_decode($value, true); break; case 'array': - $value = is_null($value) ? [] : json_decode($value, true); + $value = empty($value) ? [] : json_decode($value, true); break; case 'object': $value = empty($value) ? new \stdClass() : json_decode($value); @@ -624,7 +626,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 转换子模型对象 * @access protected - * @param Model|Collection $model + * @param Model|ModelCollection $model * @param $visible * @param $hidden * @param $key @@ -663,7 +665,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } 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); } elseif (is_array($val) && reset($val) instanceof Model) { @@ -712,14 +714,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 转换当前模型数据集为数据集对象 * @access public - * @param array|Collection $collection 数据集 - * @return Collection + * @param array|\think\Collection $collection 数据集 + * @return \think\Collection */ public function toCollection($collection) { if ($this->resultSetType) { if ('collection' == $this->resultSetType) { - $collection = new Collection($collection); + $collection = new ModelCollection($collection); } elseif (false !== strpos($this->resultSetType, '\\')) { $class = $this->resultSetType; $collection = new $class($collection); @@ -1081,7 +1083,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 删除条件 $pk = $this->getPk(); - if (isset($this->data[$pk])) { + if (is_string($pk) && isset($this->data[$pk])) { $where = [$pk => $this->data[$pk]]; } elseif (!empty($this->updateWhere)) { $where = $this->updateWhere; @@ -1426,16 +1428,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function has($relation, $operator = '>=', $count = 1, $id = '*') { - $model = new static(); - $relation = $model->$relation(); - if ($relation instanceof HasMany) { - if (is_array($operator) || $operator instanceof \Closure) { - return $relation->hasWhere($operator); - } - return $relation->has($operator, $count, $id); - } else { - return $relation; + $relation = (new static())->$relation(); + if (is_array($operator) || $operator instanceof \Closure) { + return $relation->hasWhere($operator); } + return $relation->has($operator, $count, $id); } /** @@ -1447,13 +1444,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function hasWhere($relation, $where = []) { - $model = new static(); - $relation = $model->$relation(); - if ($relation instanceof HasMany) { - return $relation->hasWhere($where); - } else { - return $relation; - } + return (new static())->$relation()->hasWhere($where); } /** @@ -1493,7 +1484,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $closure = $relation; $relation = $key; } - if (strpos($relation, '.')) { + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { list($relation, $subRelation) = explode('.', $relation, 2); } $method = Loader::parseName($relation, 1, false); @@ -1519,7 +1513,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $closure = $relation; $relation = $key; } - if (strpos($relation, '.')) { + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { list($relation, $subRelation) = explode('.', $relation, 2); } $relation = Loader::parseName($relation, 1, false); @@ -1545,7 +1542,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $closure = $relation; $relation = $key; } - if (strpos($relation, '.')) { + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { list($relation, $subRelation) = explode('.', $relation, 2); } $relation = Loader::parseName($relation, 1, false); @@ -1569,10 +1569,16 @@ abstract class Model implements \JsonSerializable, \ArrayAccess if ($relation instanceof \Closure) { $closure = $relation; $relation = $key; + } elseif (is_string($key)) { + $name = $relation; + $relation = $key; } $relation = Loader::parseName($relation, 1, false); $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); } } diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php index 0c1bea8a7..d3547f8ba 100644 --- a/thinkphp/library/think/Paginator.php +++ b/thinkphp/library/think/Paginator.php @@ -341,7 +341,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J { try { $total = $this->total(); - } catch (Exception $e) { + } catch (\DomainException $e) { $total = null; } @@ -349,7 +349,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J 'total' => $total, 'per_page' => $this->listRows(), 'current_page' => $this->currentPage(), - 'data' => $this->items->toArray() + 'data' => $this->items->toArray(), ]; } diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index d39153fd1..d4f96a75d 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -120,7 +120,7 @@ class Request protected $isCheckCache; /** - * 架构函数 + * 构造函数 * @access protected * @param array $options 参数 */ @@ -633,7 +633,7 @@ class Request if (true === $name) { // 获取包含文件上传信息的数组 $file = $this->file(); - $data = array_merge($this->param, $file); + $data = is_array($file) ? array_merge($this->param, $file) : $this->param; return $this->input($data, '', $default, $filter); } return $this->input($this->param, $name, $default, $filter); @@ -688,7 +688,7 @@ class Request { if (empty($this->post)) { $content = $this->input; - if (empty($_POST) && 'application/json' == $this->contentType()) { + if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) { $this->post = (array) json_decode($content, true); } else { $this->post = $_POST; @@ -713,7 +713,7 @@ class Request { if (is_null($this->put)) { $content = $this->input; - if ('application/json' == $this->contentType()) { + if (false !== strpos($this->contentType(), 'application/json')) { $this->put = (array) json_decode($content, true); } else { parse_str($content, $this->put); @@ -1357,7 +1357,11 @@ class Request { $contentType = $this->server('CONTENT_TYPE'); if ($contentType) { - list($type) = explode(';', $contentType); + if (strpos($contentType, ';')) { + list($type) = explode(';', $contentType); + } else { + $type = $contentType; + } return trim($type); } return ''; @@ -1523,13 +1527,13 @@ class Request } } // 自动缓存功能 - $key = '__URL__'; + $key = md5($this->host()) . '__URL__'; } elseif (strpos($key, '|')) { list($key, $fun) = explode('|', $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, ':')) { diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php index 656198f03..d03457827 100644 --- a/thinkphp/library/think/Response.php +++ b/thinkphp/library/think/Response.php @@ -40,7 +40,7 @@ class Response protected $content = null; /** - * 架构函数 + * 构造函数 * @access public * @param mixed $data 输出数据 * @param int $code diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index 1629d6364..506d74ba4 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -232,6 +232,7 @@ class Route public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = []) { $group = self::getGroup('name'); + if (!is_null($group)) { // 路由分组 $option = array_merge(self::getGroup('option'), $option); @@ -304,8 +305,12 @@ class Route } $vars = self::parseVar($rule); if (isset($name)) { - $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule; - self::name($name, [$key, $vars, self::$domain]); + $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule; + $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 ('*' != $type) { @@ -447,7 +452,8 @@ class Route $vars = self::parseVar($key); $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]; } @@ -827,7 +833,7 @@ class Route // 分隔符替换 确保路由定义使用统一的分隔符 $url = str_replace($depr, '|', $url); - if (strpos($url, '|') && isset(self::$rules['alias'][strstr($url, '|', true)])) { + if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) { // 检测路由别名 $result = self::checkRouteAlias($request, $url, $depr); if (false !== $result) { @@ -1126,8 +1132,8 @@ class Route || (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['ext']) && false === stripos('|' . $option['ext'] . '|', $request->ext() ? '|' . $request->ext() . '|' : '')) // 伪静态后缀检测 - || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_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() . '|')) || (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检测 @@ -1164,7 +1170,7 @@ class Route $len1 = substr_count($url, '|'); $len2 = substr_count($rule, '/'); // 多余参数是否合并 - $merge = !empty($option['merge_extra_vars']) ? true : false; + $merge = !empty($option['merge_extra_vars']); if ($merge && $len1 > $len2) { $url = str_replace('|', $depr, $url); $url = implode('|', explode($depr, $url, $len2 + 1)); @@ -1275,9 +1281,6 @@ class Route } elseif (strpos($url, '/')) { // [模块/控制器/操作] $path = explode('/', $url); - } elseif (false !== strpos($url, '=')) { - // 参数1=值1&参数2=值2... - parse_str($url, $var); } else { $path = [$url]; } diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php index 66ba9e187..7e20407c3 100644 --- a/thinkphp/library/think/Template.php +++ b/thinkphp/library/think/Template.php @@ -57,7 +57,7 @@ class Template protected $storage; /** - * 架构函数 + * 构造函数 * @access public */ public function __construct(array $config = []) diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php index d7dfd9731..de3cd9124 100644 --- a/thinkphp/library/think/Url.php +++ b/thinkphp/library/think/Url.php @@ -80,6 +80,9 @@ class Url if (!empty($match[1])) { $domain = $match[1]; } + if (!is_null($match[2])) { + $suffix = $match[2]; + } } elseif (!empty($rule) && isset($name)) { throw new \InvalidArgumentException('route name not exists:' . $name); } else { @@ -288,18 +291,18 @@ class Url public static function getRuleUrl($rule, &$vars = []) { foreach ($rule as $item) { - list($url, $pattern, $domain) = $item; + list($url, $pattern, $domain, $suffix) = $item; if (empty($pattern)) { - return [$url, $domain]; + return [$url, $domain, $suffix]; } foreach ($pattern as $key => $val) { if (isset($vars[$key])) { $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url); unset($vars[$key]); - $result = [$url, $domain]; + $result = [$url, $domain, $suffix]; } elseif (2 == $val) { $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); - $result = [$url, $domain]; + $result = [$url, $domain, $suffix]; } else { break; } diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php index 2f728a601..718ed7a1c 100644 --- a/thinkphp/library/think/Validate.php +++ b/thinkphp/library/think/Validate.php @@ -102,7 +102,7 @@ class Validate protected $batch = false; /** - * 架构函数 + * 构造函数 * @access public * @param array $rules 验证规则 * @param array $message 验证提示信息 diff --git a/thinkphp/library/think/View.php b/thinkphp/library/think/View.php index 020e5789e..96ae56c92 100644 --- a/thinkphp/library/think/View.php +++ b/thinkphp/library/think/View.php @@ -25,7 +25,7 @@ class View protected $replace = []; /** - * 架构函数 + * 构造函数 * @access public * @param array $engine 模板引擎参数 * @param array $replace 字符串替换参数 diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php index dba02c3e2..5aadb2b19 100644 --- a/thinkphp/library/think/cache/driver/File.php +++ b/thinkphp/library/think/cache/driver/File.php @@ -28,7 +28,7 @@ class File extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options */ public function __construct($options = []) @@ -225,6 +225,7 @@ class File extends Driver foreach ($files as $path) { if (is_dir($path)) { array_map('unlink', glob($path . '/*.php')); + rmdir($path); } else { unlink($path); } diff --git a/thinkphp/library/think/cache/driver/Lite.php b/thinkphp/library/think/cache/driver/Lite.php index 57727651b..eeb96a194 100644 --- a/thinkphp/library/think/cache/driver/Lite.php +++ b/thinkphp/library/think/cache/driver/Lite.php @@ -26,7 +26,7 @@ class Lite extends Driver ]; /** - * 架构函数 + * 构造函数 * @access public * * @param array $options diff --git a/thinkphp/library/think/cache/driver/Memcache.php b/thinkphp/library/think/cache/driver/Memcache.php index d41939d82..1fbd3b08e 100644 --- a/thinkphp/library/think/cache/driver/Memcache.php +++ b/thinkphp/library/think/cache/driver/Memcache.php @@ -25,7 +25,7 @@ class Memcache extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @access public * @throws \BadFunctionCallException diff --git a/thinkphp/library/think/cache/driver/Memcached.php b/thinkphp/library/think/cache/driver/Memcached.php index 35fafd07e..fa312e8e0 100644 --- a/thinkphp/library/think/cache/driver/Memcached.php +++ b/thinkphp/library/think/cache/driver/Memcached.php @@ -27,7 +27,7 @@ class Memcached extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @access public */ diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php index 360f515a1..4f6187856 100644 --- a/thinkphp/library/think/cache/driver/Redis.php +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -34,7 +34,7 @@ class Redis extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @access public */ diff --git a/thinkphp/library/think/cache/driver/Sqlite.php b/thinkphp/library/think/cache/driver/Sqlite.php index 76c592d80..305fd9e88 100644 --- a/thinkphp/library/think/cache/driver/Sqlite.php +++ b/thinkphp/library/think/cache/driver/Sqlite.php @@ -28,7 +28,7 @@ class Sqlite extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @throws \BadFunctionCallException * @access public diff --git a/thinkphp/library/think/cache/driver/Wincache.php b/thinkphp/library/think/cache/driver/Wincache.php index 5be8d0df2..3076fc140 100644 --- a/thinkphp/library/think/cache/driver/Wincache.php +++ b/thinkphp/library/think/cache/driver/Wincache.php @@ -25,7 +25,7 @@ class Wincache extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @throws \BadFunctionCallException * @access public diff --git a/thinkphp/library/think/cache/driver/Xcache.php b/thinkphp/library/think/cache/driver/Xcache.php index 317a4ee30..2a0e07ad9 100644 --- a/thinkphp/library/think/cache/driver/Xcache.php +++ b/thinkphp/library/think/cache/driver/Xcache.php @@ -25,7 +25,7 @@ class Xcache extends Driver ]; /** - * 架构函数 + * 构造函数 * @param array $options 缓存参数 * @access public * @throws \BadFunctionCallException diff --git a/thinkphp/library/think/controller/Rest.php b/thinkphp/library/think/controller/Rest.php index c297f4eb1..8c5911dff 100644 --- a/thinkphp/library/think/controller/Rest.php +++ b/thinkphp/library/think/controller/Rest.php @@ -32,7 +32,7 @@ abstract class Rest ]; /** - * 架构函数 取得模板对象实例 + * 构造函数 取得模板对象实例 * @access public */ public function __construct() diff --git a/thinkphp/library/think/controller/Yar.php b/thinkphp/library/think/controller/Yar.php index fcf5ced1b..af4e9a1a8 100644 --- a/thinkphp/library/think/controller/Yar.php +++ b/thinkphp/library/think/controller/Yar.php @@ -18,7 +18,7 @@ abstract class Yar { /** - * 架构函数 + * 构造函数 * @access public */ public function __construct() diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 9034076e0..5097016df 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -32,7 +32,7 @@ abstract class Builder protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; /** - * 架构函数 + * 构造函数 * @access public * @param Connection $connection 数据库连接对象实例 * @param Query $query 数据库查询对象实例 @@ -379,7 +379,7 @@ abstract class Builder } else { $zone = implode(',', $this->parseValue($value, $field)); } - $whereStr .= $key . ' ' . $exp . ' (' . $zone . ')'; + $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')'; } } elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) { // BETWEEN 查询 diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index 0887093da..bc67b1d8c 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -125,7 +125,7 @@ abstract class Connection protected $bind = []; /** - * 架构函数 读取数据库配置信息 + * 构造函数 读取数据库配置信息 * @access public * @param array $config 数据库配置数组 */ @@ -365,8 +365,8 @@ abstract class Connection $this->bind = $bind; } - //释放前次的查询结果 - if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { + // 释放前次的查询结果 + if (!empty($this->PDOStatement)) { $this->free(); } diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 3d080dccd..1032944f6 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -54,7 +54,7 @@ class Query private static $event = []; /** - * 架构函数 + * 构造函数 * @access public * @param Connection $connection 数据库对象实例 * @param string $model 模型名 @@ -869,7 +869,7 @@ class Query public function view($join, $field = true, $on = null, $type = 'INNER') { $this->options['view'] = true; - if (is_array($join) && is_null($field)) { + if (is_array($join) && key($join) !== 0) { foreach ($join as $key => $val) { $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); } @@ -893,7 +893,7 @@ class Query } else { $name = $alias . '.' . $key; } - $fields[] = $name . ' AS ' . $val; + $fields[$name] = $val; $this->options['map'][$val] = $name; } } @@ -1895,7 +1895,7 @@ class Query $relation = Loader::parseName($relation, 1, false); $model = $class->$relation(); if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) { - $model->eagerly($this, $relation, $subRelation, $closure, $first); + $model->removeOption()->eagerly($this, $relation, $subRelation, $closure, $first); $first = false; } elseif ($closure) { $with[$key] = $closure; @@ -2065,8 +2065,10 @@ class Query $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); $lastInsId = $this->getLastInsID($sequence); if ($lastInsId) { - $pk = $this->getPk($options); - $data[$pk] = $lastInsId; + $pk = $this->getPk($options); + if (is_string($pk)) { + $data[$pk] = $lastInsId; + } } $options['data'] = $data; $this->trigger('after_insert', $options); @@ -2202,11 +2204,13 @@ class Query if (isset($key) && Cache::get($key)) { // 删除缓存 Cache::rm($key); + } elseif (!empty($options['cache']['tag'])) { + Cache::clear($options['cache']['tag']); } // 执行操作 $result = '' == $sql ? 0 : $this->execute($sql, $bind); if ($result) { - if (isset($where[$pk])) { + if (is_string($pk) && isset($where[$pk])) { $data[$pk] = $where[$pk]; } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { list($a, $val) = explode('|', $key); @@ -2298,7 +2302,7 @@ class Query } } - if (isset($cache)) { + if (isset($cache) && $resultSet) { // 缓存数据集 $this->cacheData($key, $resultSet, $cache); } @@ -2375,6 +2379,8 @@ class Query } if (isset($data)) { return 'think:' . $options['table'] . '|' . $data; + } else { + return md5(serialize($options)); } } @@ -2412,8 +2418,10 @@ class Query $cache = $options['cache']; if (true === $cache['key'] && !is_null($data) && !is_array($data)) { $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } elseif (is_string($cache['key'])) { + $key = $cache['key']; } elseif (!isset($key)) { - $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $key = md5(serialize($options)); } $result = Cache::get($key); } @@ -2451,7 +2459,7 @@ class Query $result = isset($resultSet[0]) ? $resultSet[0] : null; } - if (isset($cache)) { + if (isset($cache) && $result) { // 缓存数据 $this->cacheData($key, $result, $cache); } @@ -2644,6 +2652,8 @@ class Query if (isset($key) && Cache::get($key)) { // 删除缓存 Cache::rm($key); + } elseif (!empty($options['cache']['tag'])) { + Cache::clear($options['cache']['tag']); } // 执行操作 $result = $this->execute($sql, $bind); diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index de38fac5f..4aac4424d 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -36,6 +36,9 @@ class Mysql extends Builder $key = 'json_extract(' . $field . ', \'$.' . $name . '\')'; } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } if (isset($options['alias'][$table])) { $table = $options['alias'][$table]; } diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php index 8b853a2f1..5be0468a3 100644 --- a/thinkphp/library/think/db/builder/Pgsql.php +++ b/thinkphp/library/think/db/builder/Pgsql.php @@ -55,6 +55,9 @@ class Pgsql extends Builder $key = $field . '->>\'' . $name . '\''; } elseif (strpos($key, '.')) { list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } if (isset($options['alias'][$table])) { $table = $options['alias'][$table]; } diff --git a/thinkphp/library/think/db/builder/Sqlite.php b/thinkphp/library/think/db/builder/Sqlite.php index 02d1bf2e0..55d3abc41 100644 --- a/thinkphp/library/think/db/builder/Sqlite.php +++ b/thinkphp/library/think/db/builder/Sqlite.php @@ -60,6 +60,9 @@ class Sqlite extends Builder $key = trim($key); if (strpos($key, '.')) { list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } if (isset($options['alias'][$table])) { $table = $options['alias'][$table]; } diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php index d2f418f38..2e13d3fb4 100644 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -73,6 +73,9 @@ class Sqlsrv extends Builder $key = trim($key); if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) { list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } if (isset($options['alias'][$table])) { $table = $options['alias'][$table]; } diff --git a/thinkphp/library/think/log/driver/Socket.php b/thinkphp/library/think/log/driver/Socket.php index 08fd8ace9..d30bba304 100644 --- a/thinkphp/library/think/log/driver/Socket.php +++ b/thinkphp/library/think/log/driver/Socket.php @@ -43,7 +43,7 @@ class Socket protected $allowForceClientIds = []; //配置强制推送且被授权的client_id /** - * 架构函数 + * 构造函数 * @param array $config 缓存参数 * @access public */ diff --git a/thinkphp/library/think/model/Merge.php b/thinkphp/library/think/model/Merge.php index 47d54923d..01f403f8b 100644 --- a/thinkphp/library/think/model/Merge.php +++ b/thinkphp/library/think/model/Merge.php @@ -22,7 +22,7 @@ class Merge extends Model protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) /** - * 架构函数 + * 构造函数 * @access public * @param array|object $data 数据 */ diff --git a/thinkphp/library/think/model/Pivot.php b/thinkphp/library/think/model/Pivot.php index 7823370c4..9fd457193 100644 --- a/thinkphp/library/think/model/Pivot.php +++ b/thinkphp/library/think/model/Pivot.php @@ -17,7 +17,7 @@ class Pivot extends Model { /** - * 架构函数 + * 构造函数 * @access public * @param array|object $data 数据 * @param string $table 中间数据表名 diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php index d1c4b9bde..6996526d3 100644 --- a/thinkphp/library/think/model/relation/BelongsTo.php +++ b/thinkphp/library/think/model/relation/BelongsTo.php @@ -17,7 +17,7 @@ use think\Model; class BelongsTo extends OneToOne { /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 @@ -51,6 +51,45 @@ class BelongsTo extends OneToOne 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 @@ -85,10 +124,10 @@ class BelongsTo extends OneToOne // 关联数据封装 foreach ($resultSet as $result) { // 关联模型 - if (!isset($data[$result->$localKey])) { + if (!isset($data[$result->$foreignKey])) { $relationModel = null; } else { - $relationModel = $data[$result->$localKey]; + $relationModel = $data[$result->$foreignKey]; } if ($relationModel && !empty($this->bindAttr)) { @@ -116,10 +155,10 @@ class BelongsTo extends OneToOne $foreignKey = $this->foreignKey; $data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); // 关联模型 - if (!isset($data[$result->$localKey])) { + if (!isset($data[$result->$foreignKey])) { $relationModel = null; } else { - $relationModel = $data[$result->$localKey]; + $relationModel = $data[$result->$foreignKey]; } if ($relationModel && !empty($this->bindAttr)) { // 绑定关联属性 diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php index 128287e04..b7758e9fe 100644 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -24,7 +24,7 @@ class BelongsToMany extends Relation protected $middle; /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 @@ -76,6 +76,31 @@ class BelongsToMany extends Relation 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 diff --git a/thinkphp/library/think/model/relation/HasMany.php b/thinkphp/library/think/model/relation/HasMany.php index 9bcdceadc..364d793d0 100644 --- a/thinkphp/library/think/model/relation/HasMany.php +++ b/thinkphp/library/think/model/relation/HasMany.php @@ -20,7 +20,7 @@ use think\model\Relation; class HasMany extends Relation { /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 diff --git a/thinkphp/library/think/model/relation/HasManyThrough.php b/thinkphp/library/think/model/relation/HasManyThrough.php index e1518972f..dd6f6a55f 100644 --- a/thinkphp/library/think/model/relation/HasManyThrough.php +++ b/thinkphp/library/think/model/relation/HasManyThrough.php @@ -13,6 +13,7 @@ namespace think\model\relation; use think\Db; use think\db\Query; +use think\Exception; use think\Loader; use think\Model; use think\model\Relation; @@ -25,7 +26,7 @@ class HasManyThrough extends Relation protected $through; /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 @@ -54,11 +55,36 @@ class HasManyThrough extends Relation public function getRelation($subRelation = '', $closure = null) { if ($closure) { - call_user_func_array($closure, [& $this->query]); + call_user_func_array($closure, [ & $this->query]); } 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 diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php index 2c0cf3509..95a401bfa 100644 --- a/thinkphp/library/think/model/relation/HasOne.php +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -18,7 +18,7 @@ use think\Model; class HasOne extends OneToOne { /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 @@ -47,12 +47,28 @@ class HasOne extends OneToOne // 执行关联定义方法 $localKey = $this->localKey; 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(); } + /** + * 根据关联条件查询当前模型 + * @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 diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php index 3fc8179c4..58e441354 100644 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -13,6 +13,7 @@ namespace think\model\relation; use think\Db; use think\db\Query; +use think\Exception; use think\Loader; use think\Model; use think\model\Relation; @@ -26,7 +27,7 @@ class MorphMany extends Relation protected $type; /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $model 模型名 @@ -53,11 +54,36 @@ class MorphMany extends Relation public function getRelation($subRelation = '', $closure = null) { if ($closure) { - call_user_func_array($closure, [& $this->query]); + call_user_func_array($closure, [ & $this->query]); } 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 @@ -113,7 +139,7 @@ class MorphMany extends Relation if (isset($result->$pk)) { $data = $this->eagerlyMorphToMany([ $this->morphKey => $result->$pk, - $this->morphType => $this->type + $this->morphType => $this->type, ], $relation, $subRelation, $closure); $result->setAttr(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); } @@ -132,7 +158,7 @@ class MorphMany extends Relation $count = 0; if (isset($result->$pk)) { 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(); } @@ -148,15 +174,15 @@ class MorphMany extends Relation public function getRelationCountQuery($closure) { if ($closure) { - call_user_func_array($closure, [& $this->query]); + call_user_func_array($closure, [ & $this->query]); } return $this->query->where([ $this->morphKey => [ 'exp', - '=' . $this->parent->getTable() . '.' . $this->parent->getPk() + '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), ], - $this->morphType => $this->type + $this->morphType => $this->type, ])->fetchSql()->count(); } @@ -173,7 +199,7 @@ class MorphMany extends Relation { // 预载入关联查询 支持嵌套预载入 if ($closure) { - call_user_func_array($closure, [& $this]); + call_user_func_array($closure, [ & $this]); } $list = $this->query->where($where)->with($subRelation)->select(); $morphKey = $this->morphKey; diff --git a/thinkphp/library/think/model/relation/MorphTo.php b/thinkphp/library/think/model/relation/MorphTo.php index 5e1867f2b..5fafd47ae 100644 --- a/thinkphp/library/think/model/relation/MorphTo.php +++ b/thinkphp/library/think/model/relation/MorphTo.php @@ -25,7 +25,7 @@ class MorphTo extends Relation protected $alias; /** - * 架构函数 + * 构造函数 * @access public * @param Model $parent 上级模型对象 * @param string $morphType 多态字段名 @@ -57,6 +57,31 @@ class MorphTo extends Relation 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 @@ -89,6 +114,16 @@ class MorphTo extends Relation return $this; } + /** + * 移除关联查询参数 + * @access public + * @return $this + */ + public function removeOption() + { + return $this; + } + /** * 预载入关联查询 * @access public diff --git a/thinkphp/library/think/model/relation/OneToOne.php b/thinkphp/library/think/model/relation/OneToOne.php index 18b922256..525755896 100644 --- a/thinkphp/library/think/model/relation/OneToOne.php +++ b/thinkphp/library/think/model/relation/OneToOne.php @@ -67,6 +67,7 @@ abstract class OneToOne extends Relation $field = true; } $query->field($field, false, $table, $alias); + $field = null; } // 预载入封装 @@ -82,7 +83,7 @@ abstract class OneToOne extends Relation if ($closure) { // 执行闭包查询 - call_user_func_array($closure, [& $query]); + call_user_func_array($closure, [ & $query]); // 使用withField指定获取关联的字段,如 // $query->where(['id'=>1])->withField('id,name'); if ($query->getOptions('with_field')) { @@ -91,10 +92,8 @@ abstract class OneToOne extends Relation } } elseif (isset($this->option['field'])) { $field = $this->option['field']; - } else { - $field = true; } - $query->field($field, false, $joinTable, $joinAlias, $relation . '__'); + $query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__'); } /** @@ -195,7 +194,6 @@ abstract class OneToOne extends Relation */ public function getEagerlyType() { - $this->removeOption(); return $this->eagerlyType; } @@ -290,7 +288,7 @@ abstract class OneToOne extends Relation { // 预载入关联查询 支持嵌套预载入 if ($closure) { - call_user_func_array($closure, [& $model]); + call_user_func_array($closure, [ & $model]); if ($field = $model->getOptions('with_field')) { $model->field($field)->removeOption('with_field'); } diff --git a/thinkphp/library/think/template/TagLib.php b/thinkphp/library/think/template/TagLib.php index b33251916..2e0d232ff 100644 --- a/thinkphp/library/think/template/TagLib.php +++ b/thinkphp/library/think/template/TagLib.php @@ -68,7 +68,7 @@ class TagLib protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < ']; /** - * 架构函数 + * 构造函数 * @access public * @param \stdClass $template 模板引擎对象 */ diff --git a/thinkphp/library/traits/model/SoftDelete.php b/thinkphp/library/traits/model/SoftDelete.php index 720b6e888..2b97ff72a 100644 --- a/thinkphp/library/traits/model/SoftDelete.php +++ b/thinkphp/library/traits/model/SoftDelete.php @@ -142,7 +142,7 @@ trait SoftDelete { $field = isset($this->deleteTime) ? $this->deleteTime : 'delete_time'; if (!strpos($field, '.')) { - $field = $this->db(false)->getTable() . '.' . $field; + $field = '__TABLE__.' . $field; } if (!$read && strpos($field, '.')) { $array = explode('.', $field); diff --git a/thinkphp/tpl/think_exception.tpl b/thinkphp/tpl/think_exception.tpl index e80c57b25..2d898c304 100644 --- a/thinkphp/tpl/think_exception.tpl +++ b/thinkphp/tpl/think_exception.tpl @@ -79,15 +79,17 @@ - 系统发生错误 + <?php echo lang('System Error'); ?> +