From 0e5d37e95c690abf15f503be79325f8e08068345 Mon Sep 17 00:00:00 2001 From: Anyon Date: Tue, 23 May 2017 17:15:01 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=8D=87=E7=BA=A7]ThinkPHP=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B05.0.9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- thinkphp/base.php | 2 +- thinkphp/helper.php | 2 +- thinkphp/library/think/Model.php | 79 ++++++++++----- thinkphp/library/think/Paginator.php | 18 ++++ thinkphp/library/think/Request.php | 30 +++--- thinkphp/library/think/Response.php | 17 ++-- thinkphp/library/think/Route.php | 2 +- thinkphp/library/think/Url.php | 2 +- thinkphp/library/think/db/Builder.php | 9 +- thinkphp/library/think/db/Connection.php | 95 ++++++++++++------- thinkphp/library/think/db/Query.php | 29 +++--- thinkphp/library/think/db/connector/Mysql.php | 17 +--- thinkphp/library/think/db/connector/Pgsql.php | 4 +- .../library/think/db/connector/Sqlite.php | 4 +- .../library/think/db/connector/Sqlsrv.php | 4 +- thinkphp/library/think/log/driver/File.php | 2 +- thinkphp/library/think/model/Collection.php | 14 +++ thinkphp/library/think/model/Relation.php | 26 +++++ .../think/model/relation/BelongsToMany.php | 4 +- thinkphp/tpl/think_exception.tpl | 2 +- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 14 +-- vendor/composer/autoload_static.php | 8 +- vendor/composer/installed.json | 12 +-- 24 files changed, 252 insertions(+), 146 deletions(-) diff --git a/thinkphp/base.php b/thinkphp/base.php index 43f154406..9744f01df 100644 --- a/thinkphp/base.php +++ b/thinkphp/base.php @@ -9,7 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- -define('THINK_VERSION', '5.0.8'); +define('THINK_VERSION', '5.0.9'); define('THINK_START_TIME', microtime(true)); define('THINK_START_MEM', memory_get_usage()); define('EXT', '.php'); diff --git a/thinkphp/helper.php b/thinkphp/helper.php index 677b47f53..a23b67942 100644 --- a/thinkphp/helper.php +++ b/thinkphp/helper.php @@ -192,7 +192,7 @@ if (!function_exists('db')) { * @param bool $force 是否强制重新连接 * @return \think\db\Query */ - function db($name = '', $config = [], $force = true) + function db($name = '', $config = [], $force = false) { return Db::connect($config, $force)->name($name); } diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index 8553fec61..55e7da8e4 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -176,7 +176,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 设置当前模型 确保查询返回模型对象 $queryClass = $this->query ?: $con->getConfig('query'); $query = new $queryClass($con, $this->class); - $con->setQuery($query, $this->class); // 设置当前数据表和模型名 if (!empty($this->table)) { @@ -659,14 +658,23 @@ abstract class Model implements \JsonSerializable, \ArrayAccess if (is_string($append)) { $append = explode(',', $append); } - $model = $this->getAttr($relation); + + $relation = Loader::parseName($relation, 1, false); + + // 获取关联数据 + if (isset($this->relation[$relation])) { + $model = $this->relation[$relation]; + } else { + $model = $this->getRelationData($this->$relation()); + } + if ($model instanceof Model) { foreach ($append as $key => $attr) { $key = is_numeric($key) ? $attr : $key; - if ($this->__isset($key)) { + if (isset($this->data[$key])) { throw new Exception('bind attr has exists:' . $key); } else { - $this->setAttr($key, $model->$attr); + $this->data[$key] = $model->$attr; } } } @@ -779,7 +787,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 关联模型数据集 $arr = []; foreach ($val as $k => $value) { - $arr[$k] = $this->subToArray($value, $visible, $hidden, $k); + $arr[$k] = $this->subToArray($value, $visible, $hidden, $key); } $item[$key] = $arr; } else { @@ -928,18 +936,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } } elseif (isset($this->relation[$name])) { $relation[$name] = $this->relation[$name]; - } - } - } - - // 检测字段 - if (!empty($this->field)) { - if (true === $this->field) { - $this->field = $this->getQuery()->getTableInfo('', 'fields'); - } - foreach ($this->data as $key => $val) { - if (!in_array($key, $this->field)) { - unset($this->data[$key]); + } elseif (isset($this->data[$name])) { + $relation[$name] = $this->data[$name]; + unset($this->data[$name]); } } } @@ -953,17 +952,20 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } $pk = $this->getPk(); if ($this->isUpdate) { + // 检测字段 + $this->checkAllowField($this->data, array_merge($this->auto, $this->update)); + // 自动更新 $this->autoCompleteData($this->update); + // 获取有更新的数据 + $data = $this->getChangedData(); + // 事件回调 if (false === $this->trigger('before_update', $this)) { return false; } - // 获取有更新的数据 - $data = $this->getChangedData(); - if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) { // 关联更新 if (isset($relation)) { @@ -995,7 +997,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } // 模型更新 - $result = $this->db()->where($where)->update($data); + $result = $this->getQuery()->where($where)->update($data); // 关联更新 if (isset($relation)) { @@ -1006,8 +1008,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $this->trigger('after_update', $this); } else { + // 检测字段 + $this->checkAllowField($this->data, array_merge($this->auto, $this->insert)); + // 自动写入 $this->autoCompleteData($this->insert); + // 自动写入创建时间和更新时间 if ($this->autoWriteTimestamp) { if ($this->createTime && !isset($this->data[$this->createTime])) { @@ -1022,11 +1028,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } - $result = $this->db()->insert($this->data); + $result = $this->getQuery()->insert($this->data); // 获取自动增长主键 if ($result && is_string($pk) && (!isset($this->data[$pk]) || '' == $this->data[$pk])) { - $insertId = $this->db()->getLastInsID($sequence); + $insertId = $this->getQuery()->getLastInsID($sequence); if ($insertId) { $this->data[$pk] = $insertId; } @@ -1055,6 +1061,24 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $result; } + protected function checkAllowField(&$data, $auto = []) + { + if (!empty($this->field)) { + if (true === $this->field) { + $this->field = $this->getQuery()->getTableInfo('', 'fields'); + $field = $this->field; + } else { + $field = array_merge($this->field, $auto); + } + + foreach ($data as $key => $val) { + if (!in_array($key, $field)) { + unset($data[$key]); + } + } + } + } + protected function autoRelationUpdate($relation) { foreach ($relation as $name => $val) { @@ -1078,6 +1102,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public function getChangedData() { $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) { + if ((empty($b) || empty($b)) && $a !== $b) { + return 1; + } return is_object($a) || $a != $b ? 1 : 0; }); @@ -1114,7 +1141,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } $result = []; - $db = $this->db(); + $db = $this->getQuery(); $db->startTrans(); try { $pk = $this->getPk(); @@ -1228,7 +1255,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } // 删除当前模型数据 - $result = $this->db()->where($where)->delete(); + $result = $this->getQuery()->where($where)->delete(); // 关联删除 if (!empty($this->relationWrite)) { @@ -1502,7 +1529,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } elseif ($data instanceof \Closure) { call_user_func_array($data, [ & $query]); $data = null; - } elseif (is_null($data)) { + } elseif (empty($data) && 0 !== $data) { return 0; } $resultSet = $query->select($data); diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php index d3547f8ba..5a8fa20e0 100644 --- a/thinkphp/library/think/Paginator.php +++ b/thinkphp/library/think/Paginator.php @@ -273,6 +273,23 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J return $this->items->isEmpty(); } + /** + * 给每个元素执行个回调 + * + * @param callable $callback + * @return $this + */ + public function each(callable $callback) + { + foreach ($this->items as $key => $item) { + if ($callback($item, $key) === false) { + break; + } + } + + return $this; + } + /** * Retrieve an external iterator * @return Traversable An instance of an object implementing Iterator or @@ -349,6 +366,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J 'total' => $total, 'per_page' => $this->listRows(), 'current_page' => $this->currentPage(), + 'last_page' => $this->lastPage, 'data' => $this->items->toArray(), ]; } diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index 1eb7f2971..ffd001f27 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -88,20 +88,18 @@ class Request * @var array 资源类型 */ protected $mimeType = [ - 'xml' => 'application/xml,text/xml,application/x-xml', - 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', - 'js' => 'text/javascript,application/javascript,application/x-javascript', - 'css' => 'text/css', - 'rss' => 'application/rss+xml', - 'yaml' => 'application/x-yaml,text/yaml', - 'atom' => 'application/atom+xml', - 'pdf' => 'application/pdf', - 'text' => 'text/plain', - 'png' => 'image/png', - 'jpg' => 'image/jpg,image/jpeg,image/pjpeg', - 'gif' => 'image/gif', - 'csv' => 'text/csv', - 'html' => 'text/html,application/xhtml+xml,*/*', + 'xml' => 'application/xml,text/xml,application/x-xml', + 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', + 'js' => 'text/javascript,application/javascript,application/x-javascript', + 'css' => 'text/css', + 'rss' => 'application/rss+xml', + 'yaml' => 'application/x-yaml,text/yaml', + 'atom' => 'application/atom+xml', + 'pdf' => 'application/pdf', + 'text' => 'text/plain', + 'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*', + 'csv' => 'text/csv', + 'html' => 'text/html,application/xhtml+xml,*/*', ]; protected $content; @@ -1034,7 +1032,7 @@ class Request $filter = []; } else { $filter = $filter ?: $this->filter; - if (is_string($filter)) { + if (is_string($filter) && false === strpos($filter, '/')) { $filter = explode(',', $filter); } else { $filter = (array) $filter; @@ -1060,7 +1058,7 @@ class Request // 调用函数或者方法过滤 $value = call_user_func($filter, $value); } elseif (is_scalar($value)) { - if (strpos($filter, '/')) { + if (false !== strpos($filter, '/')) { // 正则过滤 if (!preg_match($filter, $value)) { // 匹配不成功返回默认值 diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php index 1be3c68e4..96737dcd2 100644 --- a/thinkphp/library/think/Response.php +++ b/thinkphp/library/think/Response.php @@ -19,7 +19,6 @@ use think\response\Xml as XmlResponse; class Response { - // 原始数据 protected $data; @@ -50,12 +49,12 @@ class Response public function __construct($data = '', $code = 200, array $header = [], $options = []) { $this->data($data); - $this->header = $header; - $this->code = $code; if (!empty($options)) { $this->options = array_merge($this->options, $options); } $this->contentType($this->contentType, $this->charset); + $this->header = array_merge($this->header, $header); + $this->code = $code; } /** @@ -197,9 +196,9 @@ class Response public function content($content) { if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ - $content, - '__toString', - ]) + $content, + '__toString', + ]) ) { throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); } @@ -309,9 +308,9 @@ class Response $content = $this->output($this->data); if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ - $content, - '__toString', - ]) + $content, + '__toString', + ]) ) { throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); } diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index a3001d8f9..a5b193274 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -924,7 +924,7 @@ class Route } else { $str = $key; } - if (is_string($str) && $str && 0 !== strpos(str_replace('|', '/', $url), $str)) { + if (is_string($str) && $str && 0 !== stripos(str_replace('|', '/', $url), $str)) { continue; } self::setOption($option); diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php index d6e570376..8e716a5b5 100644 --- a/thinkphp/library/think/Url.php +++ b/thinkphp/library/think/Url.php @@ -297,7 +297,7 @@ class Url } foreach ($pattern as $key => $val) { if (isset($vars[$key])) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url); + $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], urlencode($vars[$key]), $url); unset($vars[$key]); $result = [$url, $domain, $suffix]; } elseif (2 == $val) { diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 019b03f80..7a589d08c 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -348,9 +348,14 @@ abstract class Builder $whereStr = ''; if (in_array($exp, ['=', '<>', '>', '>=', '<', '<='])) { - // 比较运算 及 模糊匹配 - $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); + // 比较运算 + if ($value instanceof \Closure) { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); + } else { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); + } } elseif ('LIKE' == $exp || 'NOT LIKE' == $exp) { + // 模糊匹配 if (is_array($value)) { foreach ($value as $item) { $array[] = $key . ' ' . $exp . ' ' . $this->parseValue($item, $field); diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index d2aa6ea95..fa773e51e 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -56,8 +56,6 @@ abstract class Connection protected $attrCase = PDO::CASE_LOWER; // 监听回调 protected static $event = []; - // 查询对象 - protected $query = []; // 使用Builder类 protected $builder; // 数据库连接参数配置 @@ -137,32 +135,14 @@ abstract class Connection } /** - * 指定当前使用的查询对象 - * @access public - * @param Query $query 查询对象 - * @return $this - */ - public function setQuery($query, $model = 'db') - { - $this->query[$model] = $query; - - return $this; - } - - /** - * 创建指定模型的查询对象 - * @access public + * 获取新的查询对象 + * @access protected * @return Query */ - public function getQuery($model = 'db') + protected function getQuery() { - if (!isset($this->query[$model])) { - $class = $this->config['query']; - - $this->query[$model] = new $class($this, 'db' == $model ? '' : $model); - } - - return $this->query[$model]; + $class = $this->config['query']; + return new $class($this); } /** @@ -402,10 +382,15 @@ abstract class Connection // 返回结果集 return $this->getResult($pdo, $procedure); } catch (\PDOException $e) { - if ($this->config['break_reconnect'] && $this->isBreak($e)) { + if ($this->isBreak($e)) { return $this->close()->query($sql, $bind, $master, $pdo); } throw new PDOException($e, $this->config, $this->getLastsql()); + } catch (\ErrorException $e) { + if ($this->isBreak($e)) { + return $this->close()->query($sql, $bind, $master, $pdo); + } + throw $e; } } @@ -460,10 +445,15 @@ abstract class Connection $this->numRows = $this->PDOStatement->rowCount(); return $this->numRows; } catch (\PDOException $e) { - if ($this->config['break_reconnect'] && $this->isBreak($e)) { + if ($this->isBreak($e)) { return $this->close()->execute($sql, $bind); } throw new PDOException($e, $this->config, $this->getLastsql()); + } catch (\ErrorException $e) { + if ($this->isBreak($e)) { + return $this->close()->execute($sql, $bind); + } + throw $e; } } @@ -638,13 +628,25 @@ abstract class Connection } ++$this->transTimes; + try { + if (1 == $this->transTimes) { + $this->linkID->beginTransaction(); + } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { + $this->linkID->exec( + $this->parseSavepoint('trans' . $this->transTimes) + ); + } - if (1 == $this->transTimes) { - $this->linkID->beginTransaction(); - } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { - $this->linkID->exec( - $this->parseSavepoint('trans' . $this->transTimes) - ); + } catch (\PDOException $e) { + if ($this->isBreak($e)) { + return $this->close()->startTrans(); + } + throw $e; + } catch (\ErrorException $e) { + if ($this->isBreak($e)) { + return $this->close()->startTrans(); + } + throw $e; } } @@ -780,11 +782,35 @@ abstract class Connection /** * 是否断线 * @access protected - * @param \PDOException $e 异常 + * @param \PDOException $e 异常对象 * @return bool */ protected function isBreak($e) { + if (!$this->config['break_reconnect']) { + return false; + } + + $info = [ + 'server has gone away', + 'no connection to the server', + 'Lost connection', + 'is dead or not enabled', + 'Error while sending', + 'decryption failed or bad record mac', + 'server closed the connection unexpectedly', + 'SSL connection has been closed unexpectedly', + 'Error writing data to the connection', + 'Resource deadlock avoided', + ]; + + $error = $e->getMessage(); + + foreach ($info as $msg) { + if (false !== stripos($error, $msg)) { + return true; + } + } return false; } @@ -869,7 +895,6 @@ abstract class Connection Debug::remark('queryEndTime', 'time'); $runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime'); $sql = $sql ?: $this->getLastsql(); - $log = $sql . ' [ RunTime:' . $runtime . 's ]'; $result = []; // SQL性能分析 if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) { diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 55b709413..d9cc56a53 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -401,7 +401,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options)); + $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($key); } if (false === $result) { @@ -444,7 +444,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options)); + $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($guid); } if (false === $result) { @@ -596,7 +596,7 @@ class Query } if ($lazyTime > 0) { // 延迟写入 - $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition)); + $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); $step = $this->lazyWrite('inc', $guid, $step, $lazyTime); if (false === $step) { // 清空查询条件 @@ -625,7 +625,7 @@ class Query } if ($lazyTime > 0) { // 延迟写入 - $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition)); + $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); $step = $this->lazyWrite('dec', $guid, $step, $lazyTime); if (false === $step) { // 清空查询条件 @@ -1134,6 +1134,7 @@ class Query if ($field) { $this->options['soft_delete'] = [$field, $condition ?: ['null', '']]; } + return $this; } /** @@ -1902,6 +1903,9 @@ class Query $closure = $relation; $relation = $key; $with[$key] = $key; + } elseif (is_array($relation)) { + $subRelation = $relation; + $relation = $key; } elseif (is_string($relation) && strpos($relation, '.')) { $with[$key] = $relation; list($relation, $subRelation) = explode('.', $relation, 2); @@ -2205,7 +2209,7 @@ class Query $options['where']['AND'] = $where; } } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); } // 生成UPDATE SQL语句 @@ -2293,7 +2297,7 @@ class Query // 判断查询缓存 $cache = $options['cache']; unset($options['cache']); - $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind)); $resultSet = Cache::get($key); } if (!$resultSet) { @@ -2385,8 +2389,9 @@ class Query * @access public * @param mixed $value 缓存数据 * @param array $options 缓存参数 + * @param array $bind 绑定参数 */ - protected function getCacheKey($value, $options) + protected function getCacheKey($value, $options, $bind = []) { if (is_scalar($value)) { $data = $value; @@ -2394,9 +2399,9 @@ class Query $data = $value[1]; } if (isset($data)) { - return 'think:' . $options['table'] . '|' . $data; + return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; } else { - return md5(serialize($options)); + return md5(serialize($options) . serialize($bind)); } } @@ -2424,7 +2429,7 @@ class Query // AR模式分析主键条件 $this->parsePkWhere($data, $options); } elseif (!empty($options['cache']) && true === $options['cache']['key'] && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); } $options['limit'] = 1; @@ -2437,7 +2442,7 @@ class Query } elseif (is_string($cache['key'])) { $key = $cache['key']; } elseif (!isset($key)) { - $key = md5(serialize($options)); + $key = md5(serialize($options) . serialize($this->bind)); } $result = Cache::get($key); } @@ -2648,7 +2653,7 @@ class Query // AR模式分析主键条件 $this->parsePkWhere($data, $options); } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($options['where']['AND'][$pk], $options); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); } if (true !== $data && empty($options['where'])) { diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php index 0081fb2ed..c38181dfc 100644 --- a/thinkphp/library/think/db/connector/Mysql.php +++ b/thinkphp/library/think/db/connector/Mysql.php @@ -51,7 +51,7 @@ class Mysql extends Connection */ public function getFields($tableName) { - $this->initConnect(true); + $this->initConnect(false); list($tableName) = explode(' ', $tableName); if (false === strpos($tableName, '`')) { if (strpos($tableName, '.')) { @@ -91,7 +91,7 @@ class Mysql extends Connection */ public function getTables($dbName = '') { - $this->initConnect(true); + $this->initConnect(false); $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; // 调试开始 $this->debug(true); @@ -130,17 +130,4 @@ class Mysql extends Connection return true; } - /** - * 是否断线 - * @access protected - * @param \PDOException $e 异常对象 - * @return bool - */ - protected function isBreak($e) - { - if (false !== stripos($e->getMessage(), 'server has gone away')) { - return true; - } - return false; - } } diff --git a/thinkphp/library/think/db/connector/Pgsql.php b/thinkphp/library/think/db/connector/Pgsql.php index 04c3e7829..3ad780792 100644 --- a/thinkphp/library/think/db/connector/Pgsql.php +++ b/thinkphp/library/think/db/connector/Pgsql.php @@ -44,7 +44,7 @@ class Pgsql extends Connection */ public function getFields($tableName) { - $this->initConnect(true); + $this->initConnect(false); list($tableName) = explode(' ', $tableName); $sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');'; // 调试开始 @@ -78,7 +78,7 @@ class Pgsql extends Connection */ public function getTables($dbName = '') { - $this->initConnect(true); + $this->initConnect(false); $sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'"; // 调试开始 $this->debug(true); diff --git a/thinkphp/library/think/db/connector/Sqlite.php b/thinkphp/library/think/db/connector/Sqlite.php index a0e0873ca..1de177a15 100644 --- a/thinkphp/library/think/db/connector/Sqlite.php +++ b/thinkphp/library/think/db/connector/Sqlite.php @@ -42,7 +42,7 @@ class Sqlite extends Connection */ public function getFields($tableName) { - $this->initConnect(true); + $this->initConnect(false); list($tableName) = explode(' ', $tableName); $sql = 'PRAGMA table_info( ' . $tableName . ' )'; // 调试开始 @@ -76,7 +76,7 @@ class Sqlite extends Connection */ public function getTables($dbName = '') { - $this->initConnect(true); + $this->initConnect(false); $sql = "SELECT name FROM sqlite_master WHERE type='table' " . "UNION ALL SELECT name FROM sqlite_temp_master " . "WHERE type='table' ORDER BY name"; diff --git a/thinkphp/library/think/db/connector/Sqlsrv.php b/thinkphp/library/think/db/connector/Sqlsrv.php index 20d3491d9..e9ee985b6 100644 --- a/thinkphp/library/think/db/connector/Sqlsrv.php +++ b/thinkphp/library/think/db/connector/Sqlsrv.php @@ -49,7 +49,7 @@ class Sqlsrv extends Connection */ public function getFields($tableName) { - $this->initConnect(true); + $this->initConnect(false); list($tableName) = explode(' ', $tableName); $sql = "SELECT column_name, data_type, column_default, is_nullable FROM information_schema.tables AS t @@ -99,7 +99,7 @@ class Sqlsrv extends Connection */ public function getTables($dbName = '') { - $this->initConnect(true); + $this->initConnect(false); $sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php index fdf726585..d82a5243e 100644 --- a/thinkphp/library/think/log/driver/File.php +++ b/thinkphp/library/think/log/driver/File.php @@ -76,7 +76,7 @@ class File { //检测日志文件大小,超过配置大小则备份日志文件重新生成 if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { - rename($destination, dirname($destination) . DS . $_SERVER['REQUEST_TIME'] . '-' . basename($destination)); + rename($destination, dirname($destination) . DS . time() . '-' . basename($destination)); $this->writed[$destination] = false; } diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php index 08e11ad82..4e4bb4dc6 100644 --- a/thinkphp/library/think/model/Collection.php +++ b/thinkphp/library/think/model/Collection.php @@ -16,6 +16,20 @@ use think\Model; class Collection extends BaseCollection { + /** + * 返回数组中指定的一列 + * @param string $column_key + * @param string|null $index_key + * @return array + */ + public function column($column_key, $index_key = null) + { + if (function_exists('array_column')) { + return array_column($this->toArray(), $column_key, $index_key); + } + return parent::column($column_key, $index_key); + } + /** * 延迟预载入关联查询 * @access public diff --git a/thinkphp/library/think/model/Relation.php b/thinkphp/library/think/model/Relation.php index 81b496ada..4869e5261 100644 --- a/thinkphp/library/think/model/Relation.php +++ b/thinkphp/library/think/model/Relation.php @@ -77,6 +77,32 @@ abstract class Relation return (new $this->model)->toCollection($resultSet); } + protected function getQueryFields($model) + { + $fields = $this->query->getOptions('field'); + return $this->getRelationQueryFields($fields, $model); + } + + protected function getRelationQueryFields($fields, $model) + { + if ($fields) { + + if (is_string($fields)) { + $fields = explode(',', $fields); + } + + foreach ($fields as &$field) { + if (false === strpos($field, '.')) { + $field = $model . '.' . $field; + } + } + } else { + $fields = $model . '.*'; + } + + return $fields; + } + /** * 执行基础查询(仅执行一次) * @access protected diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php index 79684fe7f..9eeb88ddf 100644 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -376,7 +376,9 @@ class BelongsToMany extends Relation // 关联查询封装 $tableName = $this->query->getTable(); $table = $this->pivot->getTable(); - $query = $this->query->field($tableName . '.*') + $fields = $this->getQueryFields($tableName); + + $query = $this->query->field($fields) ->field(true, false, $table, 'pivot', 'pivot__'); if (empty($this->baseQuery)) { diff --git a/thinkphp/tpl/think_exception.tpl b/thinkphp/tpl/think_exception.tpl index 2d898c304..0c9d31ed0 100644 --- a/thinkphp/tpl/think_exception.tpl +++ b/thinkphp/tpl/think_exception.tpl @@ -79,7 +79,7 @@ - <?php echo lang('System Error'); ?> + <?php echo \think\Lang::get('System Error'); ?>