From 94582d442ca0052c0127bd338185661668eeb894 Mon Sep 17 00:00:00 2001 From: molong Date: Tue, 23 Aug 2016 18:01:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/convention.php | 2 + core/library/think/App.php | 29 ++-- core/library/think/Debug.php | 21 ++- core/library/think/Model.php | 29 +++- core/library/think/Request.php | 4 +- core/library/think/Response.php | 27 ++-- core/library/think/Route.php | 105 +++++++------ core/library/think/Session.php | 32 +++- core/library/think/Url.php | 141 ++---------------- core/library/think/db/Connection.php | 8 +- core/library/think/db/Query.php | 12 +- .../exception/ClassNotFoundException.php | 22 +-- core/library/think/exception/DbException.php | 19 ++- .../library/think/exception/HttpException.php | 3 +- .../think/exception/HttpResponseException.php | 4 +- core/library/think/exception/PDOException.php | 12 +- .../exception/TemplateNotFoundException.php | 22 +-- .../think/exception/ThrowableError.php | 4 +- .../think/exception/ValidateException.php | 21 +-- core/library/think/log/driver/File.php | 4 +- core/library/traits/model/SoftDelete.php | 8 +- core/tpl/think_exception.tpl | 6 +- 22 files changed, 249 insertions(+), 286 deletions(-) diff --git a/core/convention.php b/core/convention.php index faf7571b..6a841a30 100644 --- a/core/convention.php +++ b/core/convention.php @@ -15,6 +15,8 @@ return [ 'app_status' => '', // 是否支持多模块 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, // 注册的根命名空间 'root_namespace' => [], // 扩展配置文件 diff --git a/core/library/think/App.php b/core/library/think/App.php index c0fed042..a9236f6f 100644 --- a/core/library/think/App.php +++ b/core/library/think/App.php @@ -79,6 +79,17 @@ class App is_null($request) && $request = Request::instance(); $config = self::initCommon(); + if (defined('BIND_MODULE')) { + // 模块/控制器绑定 + BIND_MODULE && Route::bind(BIND_MODULE); + } elseif ($config['auto_bind_module']) { + // 入口自动绑定 + $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); + if ($name && 'index' != $name && is_dir(APP_PATH . $name)) { + Route::bind($name); + } + } + $request->filter($config['default_filter']); try { @@ -102,8 +113,13 @@ class App // 记录当前调度信息 $request->dispatch($dispatch); - // 记录路由信息 - self::$debug && Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); + // 记录路由和请求信息 + if (self::$debug) { + Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); + Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info'); + Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); + } + // 监听app_begin Hook::listen('app_begin', $dispatch); @@ -156,11 +172,6 @@ class App // 监听app_end Hook::listen('app_end', $response); - // Trace调试注入 - if (Config::get('app_trace')) { - Debug::inject($response); - } - return $response; } @@ -322,7 +333,7 @@ class App try { $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']); if (is_null($instance)) { - throw new HttpException(404, 'controller not exists:' . $controller); + throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1)); } // 获取当前操作名 $action = $actionName . $config['action_suffix']; @@ -374,7 +385,7 @@ class App } } - // 应用命名空间 + // 注册应用命名空间 self::$namespace = $config['app_namespace']; Loader::addNamespace($config['app_namespace'], APP_PATH); if (!empty($config['root_namespace'])) { diff --git a/core/library/think/Debug.php b/core/library/think/Debug.php index 28b6ab1e..e36a764e 100644 --- a/core/library/think/Debug.php +++ b/core/library/think/Debug.php @@ -159,9 +159,10 @@ class Debug * @param mixed $var 变量 * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 * @param string $label 标签 默认为空 + * @param integer $flags htmlspecialchars flags * @return void|string */ - public static function dump($var, $echo = true, $label = null) + public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE) { $label = (null === $label) ? '' : rtrim($label) . ':'; ob_start(); @@ -172,7 +173,7 @@ class Debug $output = PHP_EOL . $label . $output . PHP_EOL; } else { if (!extension_loaded('xdebug')) { - $output = htmlspecialchars($output, ENT_QUOTES); + $output = htmlspecialchars($output, $flags); } $output = '
' . $label . $output . '
'; } @@ -184,14 +185,12 @@ class Debug } } - public static function inject(Response $response) + public static function inject(Response $response, &$content) { - $config = Config::get('trace'); - $type = isset($config['type']) ? $config['type'] : 'Html'; - $request = Request::instance(); - $accept = $request->header('accept'); - $contentType = $response->getHeader('Content-Type'); - $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + $config = Config::get('trace'); + $type = isset($config['type']) ? $config['type'] : 'Html'; + $request = Request::instance(); + $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); unset($config['type']); if (class_exists($class)) { $trace = new $class($config); @@ -205,14 +204,12 @@ class Debug $output = $trace->output($response, Log::getLog()); if (is_string($output)) { // trace调试信息注入 - $content = $response->getContent(); - $pos = strripos($content, ''); + $pos = strripos($content, ''); if (false !== $pos) { $content = substr($content, 0, $pos) . $output . substr($content, $pos); } else { $content = $content . $output; } - $response->content($content); } } } diff --git a/core/library/think/Model.php b/core/library/think/Model.php index cb7bd21f..f56aee93 100644 --- a/core/library/think/Model.php +++ b/core/library/think/Model.php @@ -607,7 +607,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @param array $data 数据 * @param array $where 更新条件 * @param string $sequence 自增序列名 - * @return integer + * @return integer|false */ public function save($data = [], $where = [], $sequence = null) { @@ -729,16 +729,35 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 保存多个数据到当前数据对象 * @access public * @param array $dataSet 数据 + * @param boolean $replace 是否自动识别更新和写入 * @return array|false */ - public function saveAll($dataSet) + public function saveAll($dataSet, $replace = true) { + if ($this->validate) { + // 数据批量验证 + $validate = $this->validate; + foreach ($dataSet as $data) { + if (!$this->validate($validate)->validateData($data)) { + return false; + } + } + } + $result = []; $db = $this->db(); $db->startTrans(); try { + $pk = $this->getPk(); + if (is_string($pk) && $replace) { + $auto = true; + } foreach ($dataSet as $key => $data) { - $result[$key] = self::create($data); + if (!empty($auto) && isset($data[$pk])) { + $result[$key] = self::update($data); + } else { + $result[$key] = self::create($data); + } } $db->commit(); return $result; @@ -969,8 +988,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function update($data = [], $where = []) { - $model = new static(); - $model->isUpdate(true)->save($data, $where); + $model = new static(); + $result = $model->isUpdate(true)->save($data, $where); return $model; } diff --git a/core/library/think/Request.php b/core/library/think/Request.php index 4d98c1e7..ccae2842 100644 --- a/core/library/think/Request.php +++ b/core/library/think/Request.php @@ -617,7 +617,7 @@ class Request $vars = []; } // 当前请求参数和URL地址中的参数合并 - $this->param = array_merge($this->route(false), $this->get(false), $vars); + $this->param = array_merge($this->get(false), $vars, $this->route(false)); } if (true === $name) { // 获取包含文件上传信息的数组 @@ -753,7 +753,7 @@ class Request $this->param = []; return $this->request = array_merge($this->request, $name); } - return $this->input($this->request ?: $_REQUEST, $name, $default, $filter); + return $this->input($this->request, $name, $default, $filter); } /** diff --git a/core/library/think/Response.php b/core/library/think/Response.php index 59d6a0cf..df97d97b 100644 --- a/core/library/think/Response.php +++ b/core/library/think/Response.php @@ -11,6 +11,8 @@ namespace think; +use think\Config; +use think\Debug; use think\response\Json as JsonResponse; use think\response\Jsonp as JsonpResponse; use think\response\Redirect as RedirectResponse; @@ -93,6 +95,11 @@ class Response // 处理输出数据 $data = $this->getContent(); + // Trace调试注入 + if (Config::get('app_trace')) { + Debug::inject($this, $data); + } + if (!headers_sent() && !empty($this->header)) { // 发送状态码 http_response_code($this->code); @@ -170,14 +177,14 @@ 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))); } - $this->content = (string)$content; + $this->content = (string) $content; return $this; } @@ -248,7 +255,7 @@ class Response $this->header['Content-Type'] = $contentType . '; charset=' . $charset; return $this; } - + /** * 获取头部信息 * @param string $name 头部名称 @@ -274,18 +281,18 @@ class Response */ public function getContent() { - if ($this->content == null) { + if (null == $this->content) { $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))); } - $this->content = (string)$content; + $this->content = (string) $content; } return $this->content; } diff --git a/core/library/think/Route.php b/core/library/think/Route.php index 44ef6d40..73b4b039 100644 --- a/core/library/think/Route.php +++ b/core/library/think/Route.php @@ -101,22 +101,20 @@ class Route foreach ($domain as $key => $item) { self::domain($key, $item, $option, $pattern); } + } elseif ($rule instanceof \Closure) { + // 执行闭包 + self::setDomain($domain); + call_user_func_array($rule, []); + self::setDomain(null); + } elseif (is_array($rule)) { + self::setDomain($domain); + self::group('', function () use ($rule) { + // 动态注册域名的路由规则 + self::registerRules($rule); + }, $option, $pattern); + self::setDomain(null); } else { - if ($rule instanceof \Closure) { - // 执行闭包 - self::setDomain($domain); - call_user_func_array($rule, []); - self::setDomain(null); - } elseif (is_array($rule)) { - self::setDomain($domain); - self::group('', function () use ($rule) { - // 动态注册域名的路由规则 - self::registerRules($rule); - }, $option, $pattern); - self::setDomain(null); - } else { - self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern]; - } + self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern]; } } @@ -284,11 +282,20 @@ class Route } elseif (is_string($route)) { $name = $route; } - if ('$' == substr($rule, -1, 1)) { + if (!isset($option['complete_match'])) { + if (Config::get('route_complete_match')) { + $option['complete_match'] = true; + } elseif ('$' == substr($rule, -1, 1)) { + // 是否完整匹配 + $option['complete_match'] = true; + $rule = substr($rule, 0, -1); + } + } elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) { // 是否完整匹配 $option['complete_match'] = true; $rule = substr($rule, 0, -1); } + if ('/' != $rule) { $rule = trim($rule, '/'); } @@ -864,14 +871,20 @@ class Route continue; } + if (isset($option['ext'])) { + // 路由ext参数 优先于系统配置的URL伪静态后缀参数 + $url = preg_replace('/\.' . $request->ext() . '$/i', '', $url); + } + if (is_array($rule)) { // 分组路由 - if (($pos = strpos($key, ':')) || ($pos = strpos($key, '<'))) { + $pos = strpos(str_replace('<', ':', $key), ':'); + if (false !== $pos) { $str = substr($key, 0, $pos); } else { $str = $key; } - if (is_string($str) && 0 !== strpos($url, $str)) { + if (is_string($str) && $str && 0 !== strpos($url, $str)) { continue; } @@ -1270,26 +1283,6 @@ class Route */ private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [], $merge = false) { - // 检测是否定义路由 - if (!empty($option['after_behavior'])) { - if ($option['after_behavior'] instanceof \Closure) { - $result = call_user_func_array($option['after_behavior'], [$route]); - } else { - foreach ((array) $option['after_behavior'] as $behavior) { - $result = Hook::exec($behavior, '', $route); - if (!is_null($result)) { - break; - } - } - } - // 路由规则重定向 - if ($result instanceof Response) { - return ['type' => 'response', 'response' => $result, 'params' => $matches]; - } elseif (is_array($result)) { - return $result; - } - } - // 解析路由规则 if ($rule) { $rule = explode('/', $rule); @@ -1311,6 +1304,7 @@ class Route } else { $paths = explode('/', $pathinfo); } + // 获取路由地址规则 if (is_string($route) && isset($option['prefix'])) { // 路由地址前缀 @@ -1325,6 +1319,32 @@ class Route } } } + + // 解析额外参数 + self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches); + // 记录匹配的路由信息 + Request::instance()->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]); + + // 检测路由after行为 + if (!empty($option['after_behavior'])) { + if ($option['after_behavior'] instanceof \Closure) { + $result = call_user_func_array($option['after_behavior'], []); + } else { + foreach ((array) $option['after_behavior'] as $behavior) { + $result = Hook::exec($behavior, ''); + if (!is_null($result)) { + break; + } + } + } + // 路由规则重定向 + if ($result instanceof Response) { + return ['type' => 'response', 'response' => $result, 'params' => $matches]; + } elseif (is_array($result)) { + return $result; + } + } + if ($route instanceof \Closure) { // 执行闭包 $result = ['type' => 'function', 'function' => $route, 'params' => $matches]; @@ -1342,10 +1362,6 @@ class Route // 路由到模块/控制器/操作 $result = self::parseModule($route); } - // 解析额外参数 - self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches); - // 记录匹配的路由信息 - Request::instance()->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option]); return $result; } @@ -1367,7 +1383,8 @@ class Route // 操作方法前缀支持 $action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action; } - $_GET = array_merge($_GET, $var); + // 设置当前请求的路由变量 + Request::instance()->route($var); // 路由到模块/控制器/操作 return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false]; } @@ -1379,7 +1396,7 @@ class Route * @param array $var 变量 * @return void */ - private static function parseUrlParams($url, $var = []) + private static function parseUrlParams($url, &$var = []) { if ($url) { if (Config::get('url_param_type')) { diff --git a/core/library/think/Session.php b/core/library/think/Session.php index 77719869..37afca2c 100644 --- a/core/library/think/Session.php +++ b/core/library/think/Session.php @@ -17,6 +17,7 @@ use think\exception\ClassNotFoundException; class Session { protected static $prefix = ''; + protected static $init = null; /** * 设置或者获取session作用域(前缀) @@ -98,6 +99,23 @@ class Session } if ($isDoStart) { session_start(); + self::$init = true; + } else { + self::$init = false; + } + } + + /** + * session自动启动或者初始化 + * @return void + */ + public static function boot() + { + if (is_null(self::$init)) { + self::init(); + } elseif (false === self::$init) { + session_start(); + self::$init = true; } } @@ -110,7 +128,8 @@ class Session */ public static function set($name, $value = '', $prefix = null) { - !isset($_SESSION) && self::init(); + empty(self::$init) && self::boot(); + $prefix = !is_null($prefix) ? $prefix : self::$prefix; if (strpos($name, '.')) { // 二维数组赋值 @@ -135,7 +154,7 @@ class Session */ public static function get($name = '', $prefix = null) { - !isset($_SESSION) && self::init(); + empty(self::$init) && self::boot(); $prefix = !is_null($prefix) ? $prefix : self::$prefix; if ('' == $name) { // 获取全部的session @@ -167,7 +186,7 @@ class Session */ public static function delete($name, $prefix = null) { - !isset($_SESSION) && self::init(); + empty(self::$init) && self::boot(); $prefix = !is_null($prefix) ? $prefix : self::$prefix; if (strpos($name, '.')) { list($name1, $name2) = explode('.', $name); @@ -192,7 +211,7 @@ class Session */ public static function clear($prefix = null) { - !isset($_SESSION) && self::init(); + empty(self::$init) && self::boot(); $prefix = !is_null($prefix) ? $prefix : self::$prefix; if ($prefix) { unset($_SESSION[$prefix]); @@ -209,7 +228,7 @@ class Session */ public static function has($name, $prefix = null) { - !isset($_SESSION) && self::init(); + empty(self::$init) && self::boot(); $prefix = !is_null($prefix) ? $prefix : self::$prefix; if (strpos($name, '.')) { // 支持数组 @@ -227,6 +246,7 @@ class Session public static function start() { session_start(); + self::$init = true; } /** @@ -240,6 +260,7 @@ class Session } session_unset(); session_destroy(); + self::$init = null; } /** @@ -260,5 +281,6 @@ class Session { // 暂停session session_write_close(); + self::$init = false; } } diff --git a/core/library/think/Url.php b/core/library/think/Url.php index a2d5e3d0..d6237eb1 100644 --- a/core/library/think/Url.php +++ b/core/library/think/Url.php @@ -11,8 +11,6 @@ namespace think; -use think\App; -use think\Cache; use think\Config; use think\Request; use think\Route; @@ -68,13 +66,15 @@ class Url parse_str($vars, $vars); } - if (isset($info['query'])) { - // 解析地址里面参数 合并到vars - parse_str($info['query'], $params); - $vars = array_merge($params, $vars); - } if ($url) { - $rule = Route::name(isset($name) ? $name : $url); + $rule = Route::name(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : '')); + if (is_null($rule) && isset($info['query'])) { + $rule = Route::name($url); + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); + unset($info['query']); + } } if (!empty($rule) && $match = self::getRuleUrl($rule, $vars)) { // 匹配路由命名标识 快速生成 @@ -85,16 +85,13 @@ class Url } elseif (!empty($rule) && isset($name)) { throw new \InvalidArgumentException('route name not exists:' . $name); } else { - // 获取路由别名 - $alias = self::getRouteAlias(); - // 检测路由 - if (0 !== strpos($url, '/') && isset($alias[$url]) && $match = self::getRouteUrl($alias[$url], $vars)) { - // 处理路由规则中的特殊字符 - $url = $match; - } else { - // 路由不存在 直接解析 - $url = self::parseUrl($url, $domain); + if (isset($info['query'])) { + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); } + // 路由不存在 直接解析 + $url = self::parseUrl($url, $domain); } // 检测URL绑定 @@ -222,18 +219,6 @@ class Url return $domain; } - // 检测路由规则中的变量是否有传入 - protected static function pattern($pattern, $vars) - { - foreach ($pattern as $key => $type) { - if (1 == $type && !isset($vars[$key])) { - // 变量未设置 - return false; - } - } - return true; - } - // 解析URL后缀 protected static function parseSuffix($suffix) { @@ -246,39 +231,6 @@ class Url return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix; } - // 匹配路由地址 - public static function getRouteUrl($alias, &$vars = []) - { - foreach ($alias as $key => $val) { - list($url, $pattern, $param) = $val; - // 检查变量匹配 - $array = $vars; - $match = false; - if ($pattern && self::pattern($pattern, $vars)) { - foreach ($pattern as $key => $val) { - if (isset($vars[$key])) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url); - unset($array[$key]); - } else { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>'], '', $url); - } - } - $match = true; - } elseif (empty($pattern) && array_intersect_assoc($param, $array) == $param) { - $match = true; - } - if ($match && !empty($param) && array_intersect_assoc($param, $array) != $param) { - $match = false; - } - if ($match) { - // 存在变量定义 - $vars = array_diff_key($array, $param); - return $url; - } - } - return false; - } - // 匹配路由地址 public static function getRuleUrl($rule, &$vars = []) { @@ -288,7 +240,7 @@ class Url $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url); unset($vars[$key]); } elseif (2 == $val) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>'], '', $url); + $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); } else { return false; } @@ -296,69 +248,6 @@ class Url return $url; } - // 生成路由映射并缓存 - private static function getRouteAlias() - { - if ($item = Cache::get('think_route_map')) { - return $item; - } - // 获取路由定义 - $array = Route::rules(); - foreach ($array as $type => $rules) { - foreach ($rules as $rule => $val) { - if (true === $val || empty($val['rule'])) { - continue; - } - $route = $val['route']; - $vars = $val['var']; - if (is_array($val['rule'])) { - foreach ($val['rule'] as $val) { - $key = $val['rule']; - $route = $val['route']; - $var = $val['var']; - $param = []; - if (is_array($route)) { - $route = implode('\\', $route); - } elseif ($route instanceof \Closure) { - continue; - } elseif (strpos($route, '?')) { - list($route, $str) = explode('?', $route, 2); - parse_str($str, $param); - } - $var = array_merge($vars, $var); - $item[$route][] = [$rule . '/' . $key, $var, $param]; - } - } else { - $param = []; - if (is_array($route)) { - $route = implode('\\', $route); - } elseif ($route instanceof \Closure) { - continue; - } elseif (strpos($route, '?')) { - list($route, $str) = explode('?', $route, 2); - parse_str($str, $param); - } - $item[$route][] = [$rule, $vars, $param]; - } - } - } - - // 检测路由别名 - $alias = Route::rules('alias'); - foreach ($alias as $rule => $route) { - $route = is_array($route) ? $route[0] : $route; - $item[$route][] = [$rule, [], []]; - } - !App::$debug && Cache::set('think_route_map', $item); - return $item; - } - - // 清空路由别名缓存 - public static function clearAliasCache() - { - Cache::rm('think_route_map'); - } - // 指定当前生成URL地址的root public static function root($root) { diff --git a/core/library/think/db/Connection.php b/core/library/think/db/Connection.php index dea797d2..c18cec0f 100644 --- a/core/library/think/db/Connection.php +++ b/core/library/think/db/Connection.php @@ -351,7 +351,7 @@ abstract class Connection $result = $this->PDOStatement->execute(); // 调试结束 $this->debug(false); - $procedure = 0 === strpos(strtolower(substr(trim($sql), 0, 4)), 'call'); + $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); return $this->getResult($class, $procedure); } catch (\PDOException $e) { throw new PDOException($e, $this->config, $this->queryStr); @@ -535,7 +535,7 @@ abstract class Connection /** * 启动事务 * @access public - * @return bool|null + * @return void */ public function startTrans() { @@ -558,7 +558,7 @@ abstract class Connection /** * 用于非自动提交状态下面的查询提交 * @access public - * @return boolean + * @return void * @throws PDOException */ public function commit() @@ -575,7 +575,7 @@ abstract class Connection /** * 事务回滚 * @access public - * @return boolean + * @return void * @throws PDOException */ public function rollback() diff --git a/core/library/think/db/Query.php b/core/library/think/db/Query.php index 0ebea9ad..5b30a04b 100644 --- a/core/library/think/db/Query.php +++ b/core/library/think/db/Query.php @@ -238,33 +238,33 @@ class Query /** * 启动事务 * @access public - * @return bool|null + * @return void */ public function startTrans() { - return $this->connection->startTrans(); + $this->connection->startTrans(); } /** * 用于非自动提交状态下面的查询提交 * @access public - * @return boolean + * @return void * @throws PDOException */ public function commit() { - return $this->connection->commit(); + $this->connection->commit(); } /** * 事务回滚 * @access public - * @return boolean + * @return void * @throws PDOException */ public function rollback() { - return $this->connection->rollback(); + $this->connection->rollback(); } /** diff --git a/core/library/think/exception/ClassNotFoundException.php b/core/library/think/exception/ClassNotFoundException.php index 7160f86b..0bca424d 100644 --- a/core/library/think/exception/ClassNotFoundException.php +++ b/core/library/think/exception/ClassNotFoundException.php @@ -13,20 +13,20 @@ namespace think\exception; class ClassNotFoundException extends \RuntimeException { - protected $class; - public function __construct($message,$class='') - { - $this->message = $message; - $this->class = $class; - } + protected $class; + public function __construct($message, $class = '') + { + $this->message = $message; + $this->class = $class; + } /** * 获取类名 * @access public * @return string */ - public function getClass() - { - return $this->class; - } -} \ No newline at end of file + public function getClass() + { + return $this->class; + } +} diff --git a/core/library/think/exception/DbException.php b/core/library/think/exception/DbException.php index 11c1c932..bd6fb442 100644 --- a/core/library/think/exception/DbException.php +++ b/core/library/think/exception/DbException.php @@ -16,28 +16,27 @@ use think\Exception; /** * Database相关异常处理类 */ -class DbException extends Exception +class DbException extends Exception { /** * DbException constructor. - * @param string $message - * @param array $config - * @param string $sql - * @param int $code + * @param string $message + * @param array $config + * @param string $sql + * @param int $code */ - public function __construct($message, Array $config, $sql, $code = 10500) + public function __construct($message, array $config, $sql, $code = 10500) { - $this->message = $message; - $this->code = $code; + $this->message = $message; + $this->code = $code; $this->setData('Database Status', [ 'Error Code' => $code, 'Error Message' => $message, - 'Error SQL' => $sql + 'Error SQL' => $sql, ]); $this->setData('Database Config', $config); } - } diff --git a/core/library/think/exception/HttpException.php b/core/library/think/exception/HttpException.php index 99beb002..ef6bbd82 100644 --- a/core/library/think/exception/HttpException.php +++ b/core/library/think/exception/HttpException.php @@ -11,7 +11,6 @@ namespace think\exception; - class HttpException extends \RuntimeException { private $statusCode; @@ -34,4 +33,4 @@ class HttpException extends \RuntimeException { return $this->headers; } -} \ No newline at end of file +} diff --git a/core/library/think/exception/HttpResponseException.php b/core/library/think/exception/HttpResponseException.php index 249e3da3..ff718f58 100644 --- a/core/library/think/exception/HttpResponseException.php +++ b/core/library/think/exception/HttpResponseException.php @@ -11,7 +11,6 @@ namespace think\exception; - use think\Response; class HttpResponseException extends \RuntimeException @@ -31,5 +30,4 @@ class HttpResponseException extends \RuntimeException return $this->response; } - -} \ No newline at end of file +} diff --git a/core/library/think/exception/PDOException.php b/core/library/think/exception/PDOException.php index 969a0e6c..abe94d70 100644 --- a/core/library/think/exception/PDOException.php +++ b/core/library/think/exception/PDOException.php @@ -17,23 +17,23 @@ use think\exception\DbException; * PDO异常处理类 * 重新封装了系统的\PDOException类 */ -class PDOException extends DbException +class PDOException extends DbException { /** * PDOException constructor. * @param \PDOException $exception - * @param array $config - * @param string $sql - * @param int $code + * @param array $config + * @param string $sql + * @param int $code */ - public function __construct(\PDOException $exception, Array $config, $sql, $code = 10501) + public function __construct(\PDOException $exception, array $config, $sql, $code = 10501) { $error = $exception->errorInfo; $this->setData('PDO Error Info', [ 'SQLSTATE' => $error[0], 'Driver Error Code' => $error[1], - 'Driver Error Message' => isset($error[2]) ? $error[2] : '' + 'Driver Error Message' => isset($error[2]) ? $error[2] : '', ]); parent::__construct($exception->getMessage(), $config, $sql, $code); diff --git a/core/library/think/exception/TemplateNotFoundException.php b/core/library/think/exception/TemplateNotFoundException.php index b9d5294e..24105c42 100644 --- a/core/library/think/exception/TemplateNotFoundException.php +++ b/core/library/think/exception/TemplateNotFoundException.php @@ -13,21 +13,21 @@ namespace think\exception; class TemplateNotFoundException extends \RuntimeException { - protected $template; + protected $template; - public function __construct($message,$template='') - { - $this->message = $message; - $this->template = $template; - } + public function __construct($message, $template = '') + { + $this->message = $message; + $this->template = $template; + } /** * 获取模板文件 * @access public * @return string */ - public function getTemplate() - { - return $this->template; - } -} \ No newline at end of file + public function getTemplate() + { + return $this->template; + } +} diff --git a/core/library/think/exception/ThrowableError.php b/core/library/think/exception/ThrowableError.php index 8ba26ea8..54823d78 100644 --- a/core/library/think/exception/ThrowableError.php +++ b/core/library/think/exception/ThrowableError.php @@ -11,7 +11,6 @@ namespace think\exception; - class ThrowableError extends \ErrorException { public function __construct(\Throwable $e) @@ -36,7 +35,6 @@ class ThrowableError extends \ErrorException $e->getLine() ); - $this->setTrace($e->getTrace()); } @@ -46,4 +44,4 @@ class ThrowableError extends \ErrorException $traceReflector->setAccessible(true); $traceReflector->setValue($this, $trace); } -} \ No newline at end of file +} diff --git a/core/library/think/exception/ValidateException.php b/core/library/think/exception/ValidateException.php index 6f1cd4d1..03599f5b 100644 --- a/core/library/think/exception/ValidateException.php +++ b/core/library/think/exception/ValidateException.php @@ -13,20 +13,21 @@ namespace think\exception; class ValidateException extends \RuntimeException { - protected $error; + protected $error; - public function __construct($error) - { - $this->error = $error; - } + public function __construct($error) + { + $this->error = $error; + $this->message = is_array($error) ? implode("\n\r", $error) : $error; + } /** * 获取验证错误信息 * @access public * @return array|string */ - public function getError() - { - return $this->error; - } -} \ No newline at end of file + public function getError() + { + return $this->error; + } +} diff --git a/core/library/think/log/driver/File.php b/core/library/think/log/driver/File.php index bb6844a9..995ef260 100644 --- a/core/library/think/log/driver/File.php +++ b/core/library/think/log/driver/File.php @@ -80,12 +80,12 @@ class File if (in_array($type, $this->config['apart_level'])) { // 独立记录的日志级别 $filename = $path . DS . $type . '.log'; - error_log("[{$now}] {$server} {$remote} {$method} {$uri}\r\n{$level}\r\n", 3, $filename); + error_log("[{$now}] {$server} {$remote} {$method} {$uri}\r\n{$level}\r\n---------------------------------------------------------------\r\n", 3, $filename); } else { $info .= $level; } } - return error_log("[{$now}] {$server} {$remote} {$method} {$uri}\r\n{$info}\r\n", 3, $destination); + return error_log("[{$now}] {$server} {$remote} {$method} {$uri}\r\n{$info}\r\n---------------------------------------------------------------\r\n", 3, $destination); } } diff --git a/core/library/traits/model/SoftDelete.php b/core/library/traits/model/SoftDelete.php index c2d56f1e..621cc8ce 100644 --- a/core/library/traits/model/SoftDelete.php +++ b/core/library/traits/model/SoftDelete.php @@ -37,7 +37,7 @@ trait SoftDelete public static function onlyTrashed() { $model = new static(); - return $model->db()->where(static::$deleteTime, '>', 0); + return $model->db()->where(static::$deleteTime, 'exp', 'is not null'); } /** @@ -104,7 +104,9 @@ trait SoftDelete { if (static::$deleteTime) { // 恢复删除 - $this->setAttr(static::$deleteTime, 0); + $name = static::$deleteTime; + $this->change[] = $name; + $this->data[$name] = null; return $this->isUpdate()->save(); } return false; @@ -118,7 +120,7 @@ trait SoftDelete protected static function base($query) { if (static::$deleteTime) { - $query->where(static::$deleteTime, 0); + $query->where(static::$deleteTime, 'null'); } } diff --git a/core/tpl/think_exception.tpl b/core/tpl/think_exception.tpl index 37b53999..e80c57b2 100644 --- a/core/tpl/think_exception.tpl +++ b/core/tpl/think_exception.tpl @@ -226,6 +226,8 @@ width: 100%; margin: 12px 0; box-sizing: border-box; + table-layout:fixed; + word-wrap:break-word; } .exception-var table caption{ text-align: left; @@ -249,7 +251,7 @@ word-break: break-all; } .exception-var table td:first-child{ - width: 12px; + width: 28%; font-weight: bold; white-space: nowrap; } @@ -292,7 +294,7 @@

[]

-

+