From ffa548b9247503521fde4f95eea5351e517c34ba Mon Sep 17 00:00:00 2001 From: Anyon Date: Mon, 26 Mar 2018 17:07:14 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=9B=B4=E6=96=B0]composerUpdate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 2 +- thinkphp/README.md | 11 +- thinkphp/base.php | 38 +- thinkphp/convention.php | 10 +- thinkphp/helper.php | 9 +- thinkphp/lang/zh-cn.php | 7 +- thinkphp/library/think/App.php | 112 ++-- thinkphp/library/think/Build.php | 63 +- thinkphp/library/think/Config.php | 13 +- thinkphp/library/think/Console.php | 38 +- thinkphp/library/think/Container.php | 200 ++----- thinkphp/library/think/Controller.php | 21 +- thinkphp/library/think/Db.php | 4 +- thinkphp/library/think/Debug.php | 3 +- thinkphp/library/think/Env.php | 26 +- thinkphp/library/think/Error.php | 4 +- thinkphp/library/think/Facade.php | 4 - thinkphp/library/think/File.php | 104 ++-- thinkphp/library/think/Hook.php | 9 +- thinkphp/library/think/Lang.php | 4 +- thinkphp/library/think/Loader.php | 51 +- thinkphp/library/think/Log.php | 83 +-- thinkphp/library/think/Model.php | 26 +- thinkphp/library/think/Paginator.php | 4 +- thinkphp/library/think/Request.php | 280 ++++----- thinkphp/library/think/Response.php | 8 +- thinkphp/library/think/Route.php | 444 ++++++++++---- thinkphp/library/think/Template.php | 94 ++- thinkphp/library/think/Url.php | 19 +- thinkphp/library/think/Validate.php | 55 +- thinkphp/library/think/cache/driver/File.php | 9 +- thinkphp/library/think/cache/driver/Redis.php | 37 +- .../library/think/console/command/Clear.php | 2 +- .../think/console/command/RunServer.php | 2 +- .../think/console/command/make/Controller.php | 11 +- .../think/console/command/make/Middleware.php | 36 -- .../think/console/command/make/Model.php | 2 +- .../command/make/stubs/controller.api.stub | 64 -- .../command/make/stubs/middleware.stub | 10 - .../think/console/command/optimize/Config.php | 17 +- .../think/console/command/optimize/Route.php | 6 +- .../think/console/command/optimize/Schema.php | 2 +- thinkphp/library/think/db/Builder.php | 38 +- thinkphp/library/think/db/Connection.php | 554 +++++++++--------- thinkphp/library/think/db/Query.php | 310 ++++------ thinkphp/library/think/db/builder/Mysql.php | 4 +- thinkphp/library/think/debug/Html.php | 2 +- .../middleware/Dispatcher.php} | 69 +-- .../http/middleware/DispatcherInterface.php | 45 ++ .../middleware/MissingResponseException.php} | 20 +- .../http/tests/middleware/DispatcherTest.php | 69 +++ thinkphp/library/think/log/driver/File.php | 31 +- thinkphp/library/think/model/Collection.php | 12 + .../library/think/model/concern/Attribute.php | 128 ++-- .../think/model/concern/RelationShip.php | 8 +- .../think/model/concern/SoftDelete.php | 7 +- .../think/model/relation/BelongsTo.php | 25 +- .../library/think/model/relation/HasOne.php | 30 +- .../think/model/relation/MorphMany.php | 2 +- .../library/think/process/pipes/Windows.php | 2 +- thinkphp/library/think/response/View.php | 1 + thinkphp/library/think/response/Xml.php | 9 - thinkphp/library/think/route/AliasRule.php | 126 ---- thinkphp/library/think/route/Domain.php | 146 +++-- thinkphp/library/think/route/Resource.php | 46 +- thinkphp/library/think/route/Rule.php | 326 +++-------- thinkphp/library/think/route/RuleGroup.php | 388 +++--------- thinkphp/library/think/route/RuleItem.php | 314 +++++----- thinkphp/library/think/route/RuleName.php | 63 -- .../library/think/route/dispatch/Module.php | 24 +- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 14 +- vendor/composer/autoload_static.php | 8 +- vendor/composer/installed.json | 12 +- 74 files changed, 1916 insertions(+), 2863 deletions(-) delete mode 100644 thinkphp/library/think/console/command/make/Middleware.php delete mode 100644 thinkphp/library/think/console/command/make/stubs/controller.api.stub delete mode 100644 thinkphp/library/think/console/command/make/stubs/middleware.stub rename thinkphp/library/think/{Middleware.php => http/middleware/Dispatcher.php} (52%) create mode 100644 thinkphp/library/think/http/middleware/DispatcherInterface.php rename thinkphp/library/think/{facade/Middleware.php => http/middleware/MissingResponseException.php} (50%) create mode 100644 thinkphp/library/think/http/tests/middleware/DispatcherTest.php delete mode 100644 thinkphp/library/think/route/AliasRule.php delete mode 100644 thinkphp/library/think/route/RuleName.php diff --git a/composer.json b/composer.json index 943a0ab45..83c836a9e 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.6.0", "endroid/qrcode": "^1.9", - "topthink/framework": "5.1.*", + "topthink/framework": "5.1.5", "zoujingli/ip2region": "dev-master", "aliyuncs/oss-sdk-php": "^2.2", "zoujingli/weopen-developer": "dev-master", diff --git a/thinkphp/README.md b/thinkphp/README.md index 52c34a4bf..5da1eef6a 100644 --- a/thinkphp/README.md +++ b/thinkphp/README.md @@ -1,11 +1,12 @@ -![](http://www.thinkphp.cn/Uploads/editor/2016-06-23/576b4732a6e04.png) - -ThinkPHP 5.1 —— 12载初心,你值得信赖的PHP框架 +ThinkPHP 5.1 =============== +[![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411) [![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework) +[![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master) [![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) [![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) +[![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework) [![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特性包括: @@ -29,12 +30,12 @@ ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特 + 内置控制器扩展类 + 模型自动验证 -> ThinkPHP5.1的运行环境要求PHP5.6+。 +> ThinkPHP5的运行环境要求PHP5.6以上。 ## 在线手册 -+ [完全开发手册](https://www.kancloud.cn/manual/thinkphp5_1/content) ++ [完全开发手册](https://www.kancloud.cn/manual/thinkphp5_1) + [升级指导](https://www.kancloud.cn/manual/thinkphp5_1/354155) ## 命名规范 diff --git a/thinkphp/base.php b/thinkphp/base.php index aad321d6a..fc8b7b130 100644 --- a/thinkphp/base.php +++ b/thinkphp/base.php @@ -40,7 +40,6 @@ Container::getInstance()->bind([ 'hook' => Hook::class, 'lang' => Lang::class, 'log' => Log::class, - 'middleware' => Middleware::class, 'request' => Request::class, 'response' => Response::class, 'route' => Route::class, @@ -48,31 +47,30 @@ Container::getInstance()->bind([ 'url' => Url::class, 'validate' => Validate::class, 'view' => View::class, - 'rule_name' => route\RuleName::class, + 'middlewareDispatcher' => http\middleware\Dispatcher::class, // 接口依赖注入 'think\LoggerInterface' => Log::class, ]); // 注册核心类的静态代理 Facade::bind([ - facade\App::class => App::class, - facade\Build::class => Build::class, - facade\Cache::class => Cache::class, - facade\Config::class => Config::class, - facade\Cookie::class => Cookie::class, - facade\Debug::class => Debug::class, - facade\Env::class => Env::class, - facade\Hook::class => Hook::class, - facade\Lang::class => Lang::class, - facade\Log::class => Log::class, - facade\Middleware::class => Middleware::class, - facade\Request::class => Request::class, - facade\Response::class => Response::class, - facade\Route::class => Route::class, - facade\Session::class => Session::class, - facade\Url::class => Url::class, - facade\Validate::class => Validate::class, - facade\View::class => View::class, + facade\App::class => App::class, + facade\Build::class => Build::class, + facade\Cache::class => Cache::class, + facade\Config::class => Config::class, + facade\Cookie::class => Cookie::class, + facade\Debug::class => Debug::class, + facade\Env::class => Env::class, + facade\Hook::class => Hook::class, + facade\Lang::class => Lang::class, + facade\Log::class => Log::class, + facade\Request::class => Request::class, + facade\Response::class => Response::class, + facade\Route::class => Route::class, + facade\Session::class => Session::class, + facade\Url::class => Url::class, + facade\Validate::class => Validate::class, + facade\View::class => View::class, ]); // 注册类库别名 diff --git a/thinkphp/convention.php b/thinkphp/convention.php index 4cae2c34c..01046c4f5 100644 --- a/thinkphp/convention.php +++ b/thinkphp/convention.php @@ -30,7 +30,7 @@ return [ // 默认JSONP处理方法 'var_jsonp_handler' => 'callback', // 默认时区 - 'default_timezone' => 'Asia/Shanghai', + 'default_timezone' => 'PRC', // 是否开启多语言 'lang_switch_on' => false, // 默认全局过滤方法 用逗号分隔多个 @@ -89,8 +89,6 @@ return [ 'url_lazy_route' => false, // 是否强制使用路由 'url_route_must' => false, - // 合并路由规则 - 'route_rule_merge' => false, // 路由是否完全匹配 'route_complete_match' => false, // 使用注解路由 @@ -291,10 +289,4 @@ return [ 'list_rows' => 15, ], - //控制台配置 - 'console' => [ - 'name' => 'Think Console', - 'version' => '0.1', - 'user' => null, - ], ]; diff --git a/thinkphp/helper.php b/thinkphp/helper.php index 18ade67df..461460ea3 100644 --- a/thinkphp/helper.php +++ b/thinkphp/helper.php @@ -29,7 +29,6 @@ use think\facade\Request; use think\facade\Route; use think\facade\Session; use think\facade\Url; -use think\Loader; use think\Response; use think\route\RuleItem; @@ -371,7 +370,7 @@ if (!function_exists('input')) { * @param string $filter 过滤方法 * @return mixed */ - function input($key = '', $default = null, $filter = '') + function input($key = '', $default = null, $filter = null) { if (0 === strpos($key, '?')) { $key = substr($key, 1); @@ -654,15 +653,11 @@ if (!function_exists('view')) { * @param string $template 模板文件 * @param array $vars 模板变量 * @param integer $code 状态码 - * @param callable $filter 内容过滤 + * @param callable $filer 内容过滤 * @return \think\response\View */ function view($template = '', $vars = [], $code = 200, $filter = null) { - if ('' === $template) { - $template = Loader::parseName(request()->action(true)); - } - return Response::create($template, 'view', $code)->assign($vars)->filter($filter); } } diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php index 16b1bb7ce..dd8084d16 100644 --- a/thinkphp/lang/zh-cn.php +++ b/thinkphp/lang/zh-cn.php @@ -24,7 +24,6 @@ return [ 'dispatch type not support' => '不支持的调度类型', 'method param miss' => '方法参数错误', 'method not exists' => '方法不存在', - 'function not exists' => '函数不存在', 'module not exists' => '模块不存在', 'controller not exists' => '控制器不存在', 'class not exists' => '类不存在', @@ -33,7 +32,7 @@ return [ 'illegal controller name' => '非法的控制器名称', 'illegal action name' => '非法的操作名称', 'url suffix deny' => '禁止的URL后缀访问', - 'Route Not Found' => '当前访问路由未定义或不匹配', + 'Route Not Found' => '当前访问路由未定义', 'Undefined db type' => '未定义数据库类型', 'variable type error' => '变量类型错误', 'PSR-4 error' => 'PSR-4 规范错误', @@ -67,8 +66,6 @@ return [ 'relation data not exists' => '关联数据不存在', 'relation not support' => '关联不支持', 'chunk not support order' => 'Chunk不支持调用order方法', - 'route pattern error' => '路由变量规则定义错误', - 'route behavior will not support' => '路由行为废弃(使用中间件替代)', // 上传错误信息 'unknown upload error' => '未知上传错误!', @@ -86,8 +83,6 @@ return [ 'filesize not match' => '上传文件大小不符!', 'directory {:path} creation failed' => '目录 {:path} 创建失败!', - 'The middleware must return Response instance' => '中间件方法必须返回Response对象实例', - 'The queue was exhausted, with no response returned' => '中间件队列为空', // Validate Error Message ':attribute require' => ':attribute不能为空', ':attribute must' => ':attribute必须', diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index ae87e5973..8892585c8 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -20,7 +20,7 @@ use think\route\Dispatch; */ class App implements \ArrayAccess { - const VERSION = '5.1.6'; + const VERSION = '5.1.5'; /** * 当前模块路径 @@ -126,7 +126,7 @@ class App implements \ArrayAccess public function __construct($appPath = '') { - $this->appPath = $appPath ?: realpath(dirname(dirname($_SERVER['SCRIPT_FILENAME'])) . DIRECTORY_SEPARATOR . 'application') . DIRECTORY_SEPARATOR; + $this->appPath = $appPath ?: realpath(dirname($_SERVER['SCRIPT_FILENAME']) . '/../application') . '/'; $this->container = Container::getInstance(); } @@ -163,11 +163,11 @@ class App implements \ArrayAccess { $this->beginTime = microtime(true); $this->beginMem = memory_get_usage(); - $this->thinkPath = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR; - $this->rootPath = dirname(realpath($this->appPath)) . DIRECTORY_SEPARATOR; - $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; - $this->routePath = $this->rootPath . 'route' . DIRECTORY_SEPARATOR; - $this->configPath = $this->rootPath . 'config' . DIRECTORY_SEPARATOR; + $this->thinkPath = dirname(dirname(__DIR__)) . '/'; + $this->rootPath = dirname(realpath($this->appPath)) . '/'; + $this->runtimePath = $this->rootPath . 'runtime/'; + $this->routePath = $this->rootPath . 'route/'; + $this->configPath = $this->rootPath . 'config/'; // 设置路径环境变量 $this->env->set([ @@ -177,8 +177,8 @@ class App implements \ArrayAccess 'config_path' => $this->configPath, 'route_path' => $this->routePath, 'runtime_path' => $this->runtimePath, - 'extend_path' => $this->rootPath . 'extend' . DIRECTORY_SEPARATOR, - 'vendor_path' => $this->rootPath . 'vendor' . DIRECTORY_SEPARATOR, + 'extend_path' => $this->rootPath . 'extend/', + 'vendor_path' => $this->rootPath . 'vendor/', ]); // 加载环境变量配置文件 @@ -228,9 +228,6 @@ class App implements \ArrayAccess // 设置系统时区 date_default_timezone_set($this->config('app.default_timezone')); - // 读取语言包 - $this->loadLangPack(); - // 监听app_init $this->hook->listen('app_init'); } @@ -255,10 +252,7 @@ class App implements \ArrayAccess } else { // 加载行为扩展文件 if (is_file($path . 'tags.php')) { - $tags = include $path . 'tags.php'; - if (is_array($tags)) { - $this->hook->import($tags); - } + $this->hook->import(include $path . 'tags.php'); } // 加载公共文件 @@ -269,21 +263,11 @@ class App implements \ArrayAccess if ('' == $module) { // 加载系统助手函数 include $this->thinkPath . 'helper.php'; - // 加载全局中间件 - if (is_file($path . 'middleware.php')) { - $middleware = include $path . 'middleware.php'; - if (is_array($middleware)) { - $this->middleware->import($middleware); - } - } } // 注册服务的容器对象实例 if (is_file($path . 'provider.php')) { - $provider = include $path . 'provider.php'; - if (is_array($provider)) { - $this->container->bind($provider); - } + $this->container->bind(include $path . 'provider.php'); } // 自动读取配置文件 @@ -314,10 +298,10 @@ class App implements \ArrayAccess */ public function run() { - try { - // 初始化应用 - $this->initialize(); + // 初始化应用 + $this->initialize(); + try { if ($this->bind) { // 模块/控制器绑定 $this->route->bind($this->bind); @@ -329,18 +313,28 @@ class App implements \ArrayAccess } } + // 读取默认语言 + $this->lang->range($this->config('app.default_lang')); + if ($this->config('app.lang_switch_on')) { + // 开启多语言机制 检测当前语言 + $this->lang->detect(); + } + + $this->request->langset($this->lang->range()); + + // 加载系统语言包 + $this->lang->load([ + $this->thinkPath . 'lang/' . $this->request->langset() . '.php', + $this->appPath . 'lang/' . $this->request->langset() . '.php', + ]); + // 监听app_dispatch $this->hook->listen('app_dispatch'); // 获取应用调度信息 $dispatch = $this->dispatch; if (empty($dispatch)) { - // 路由检测 - $this->route - ->lazy($this->config('app.url_lazy_route')) - ->autoSearchController($this->config('app.controller_auto_search')) - ->mergeRuleRegex($this->config('app.route_rule_merge')); - + // 进行URL路由检测 $dispatch = $this->routeCheck(); } @@ -364,22 +358,14 @@ class App implements \ArrayAccess $this->config('app.request_cache_except') ); - $data = null; + // 执行调度 + $data = $dispatch->run(); + } catch (HttpResponseException $exception) { - $dispatch = null; - $data = $exception->getResponse(); + $data = $exception->getResponse(); } - $this->middleware->add(function (Request $request, $next) use ($dispatch, $data) { - if (is_null($data)) { - try { - // 执行调度 - $data = $dispatch->run(); - } catch (HttpResponseException $exception) { - $data = $exception->getResponse(); - } - } - + $this->middlewareDispatcher->add(function (Request $request, $next) use ($data) { // 输出数据到客户端 if ($data instanceof Response) { $response = $data; @@ -395,7 +381,7 @@ class App implements \ArrayAccess return $response; }); - $response = $this->middleware->dispatch($this->request); + $response = $this->middlewareDispatcher->dispatch($this->request); // 监听app_end $this->hook->listen('app_end', $response); @@ -403,24 +389,6 @@ class App implements \ArrayAccess return $response; } - protected function loadLangPack() - { - // 读取默认语言 - $this->lang->range($this->config('app.default_lang')); - if ($this->config('app.lang_switch_on')) { - // 开启多语言机制 检测当前语言 - $this->lang->detect(); - } - - $this->request->langset($this->lang->range()); - - // 加载系统语言包 - $this->lang->load([ - $this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php', - $this->appPath . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php', - ]); - } - /** * 设置当前请求的调度信息 * @access public @@ -440,9 +408,9 @@ class App implements \ArrayAccess * @param string $type 信息类型 * @return void */ - public function log($msg, $type = 'info') + public function log($log, $type = 'info') { - $this->debug && $this->log->record($msg, $type); + $this->debug && $this->log->record($log, $type); } /** @@ -606,9 +574,9 @@ class App implements \ArrayAccess return $this->__get($class); } elseif ($empty && class_exists($emptyClass = $this->parseClass($module, $layer, $empty, $appendSuffix))) { return $this->__get($emptyClass); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); } - - throw new ClassNotFoundException('class not exists:' . $class, $class); } /** diff --git a/thinkphp/library/think/Build.php b/thinkphp/library/think/Build.php index 6de014023..ed3ffe43d 100644 --- a/thinkphp/library/think/Build.php +++ b/thinkphp/library/think/Build.php @@ -135,7 +135,7 @@ class Build // 创建子目录和文件 foreach ($list as $path => $file) { - $modulePath = $this->basePath . $module . DIRECTORY_SEPARATOR; + $modulePath = $this->basePath . $module . '/'; if ('__dir__' == $path) { // 生成子目录 foreach ($file as $dir) { @@ -187,7 +187,7 @@ class Build * @param string $layer 控制器层目录名 * @return string */ - public function buildRoute($suffix = false, $layer = '') + public function buildRoute($alias = false, $layer = '') { $namespace = $this->app->getNameSpace(); $modules = glob($this->basePath . '*', GLOB_ONLYDIR); @@ -204,8 +204,11 @@ class Build continue; } - $path = $this->basePath . $module . DIRECTORY_SEPARATOR . $layer . DIRECTORY_SEPARATOR; - $content .= $this->buildDirRoute($path, $namespace, $module, $suffix, $layer); + $controllers = glob($this->basePath . $module . '/' . $layer . '/*.php'); + + foreach ($controllers as $controller) { + $content .= $this->getControllerRoute($namespace, $module, basename($controller, '.php'), $alias, $layer); + } } $filename = $this->app->getRuntimePath() . 'build_route.php'; @@ -215,61 +218,25 @@ class Build } /** - * 生成子目录控制器类的路由规则 + * 生成控制器类的路由规则 * @access protected - * @param string $path 控制器目录 * @param string $namespace 应用命名空间 * @param string $module 模块 + * @param string $controller 控制器名 * @param bool $suffix 类库后缀 * @param string $layer 控制器层目录名 * @return string */ - protected function buildDirRoute($path, $namespace, $module, $suffix, $layer) - { - $content = ''; - $controllers = glob($path . '*.php'); - - foreach ($controllers as $controller) { - $controller = basename($controller, '.php'); - - if ($suffix) { - // 控制器后缀 - $controller = substr($controller, 0, -10); - } - - $class = new \ReflectionClass($namespace . '\\' . $module . '\\' . $layer . '\\' . $controller); - - if (strpos($layer, DIRECTORY_SEPARATOR)) { - // 多级控制器 - $level = str_replace(DIRECTORY_SEPARATOR, '.', substr($layer, 11)); - $controller = $level . '.' . $controller; - } - - $content .= $this->getControllerRoute($class, $module, $controller); - } - - $subDir = glob($path . '*', GLOB_ONLYDIR); - - foreach ($subDir as $dir) { - $content .= $this->buildDirRoute($dir . DIRECTORY_SEPARATOR, $namespace, $module, $suffix, $layer . '\\' . basename($dir)); - } - - return $content; - } - - /** - * 生成控制器类的路由规则 - * @access protected - * @param string $class 控制器完整类名 - * @param string $module 模块名 - * @param string $controller 控制器名 - * @return string - */ - protected function getControllerRoute($class, $module, $controller) + protected function getControllerRoute($namespace, $module, $controller, $alias = false, $layer = '') { + $class = new \ReflectionClass($namespace . '\\' . $module . '\\' . $layer . '\\' . $controller); $content = ''; $comment = $class->getDocComment(); + if ($alias) { + $controller = substr($controller, 0, -10); + } + if (false !== strpos($comment, '@route(')) { $comment = $this->parseRouteComment($comment); $route = $module . '/' . $controller; diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php index 603c655f4..e30471a5e 100644 --- a/thinkphp/library/think/Config.php +++ b/thinkphp/library/think/Config.php @@ -72,11 +72,12 @@ class Config implements \ArrayAccess return $this->set(include $file, $name); } elseif ('yaml' == $type && function_exists('yaml_parse_file')) { return $this->set(yaml_parse_file($file), $name); + } else { + return $this->parse($file, $type, $name); } - return $this->parse($file, $type, $name); + } else { + return $this->config; } - - return $this->config; } /** @@ -89,12 +90,12 @@ class Config implements \ArrayAccess { // 如果尚未载入 则动态加载配置文件 $module = Container::get('request')->module(); - $module = $module ? $module . DIRECTORY_SEPARATOR : ''; + $module = $module ? $module . '/' : ''; $app = Container::get('app'); $path = $app->getAppPath() . $module; if (is_dir($path . 'config')) { - $file = $path . 'config' . DIRECTORY_SEPARATOR . $name . $app->getConfigExt(); + $file = $path . 'config/' . $name . $app->getConfigExt(); } elseif (is_dir($app->getConfigPath() . $module)) { $file = $app->getConfigPath() . $module . $name . $app->getConfigExt(); } @@ -116,7 +117,7 @@ class Config implements \ArrayAccess $name = $this->prefix . '.' . $name; } - return !is_null($this->get($name)) ? true : false; + return $this->get($name) ? true : false; } /** diff --git a/thinkphp/library/think/Console.php b/thinkphp/library/think/Console.php index 8782aa92e..5cb1ccde7 100644 --- a/thinkphp/library/think/Console.php +++ b/thinkphp/library/think/Console.php @@ -41,7 +41,6 @@ class Console "think\\console\\command\\Clear", "think\\console\\command\\make\\Controller", "think\\console\\command\\make\\Model", - "think\\console\\command\\make\\Middleware", "think\\console\\command\\optimize\\Autoload", "think\\console\\command\\optimize\\Config", "think\\console\\command\\optimize\\Schema", @@ -49,22 +48,11 @@ class Console "think\\console\\command\\RunServer", ]; - /** - * Console constructor. - * @access public - * @param string $name 名称 - * @param string $version 版本 - * @param null|string $user 执行用户 - */ - public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', $user = null) + public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') { $this->name = $name; $this->version = $version; - if ($user) { - $this->setUser($user); - } - $this->defaultCommand = 'list'; $this->definition = $this->getDefaultInputDefinition(); @@ -73,33 +61,13 @@ class Console } } - /** - * 设置执行用户 - * @param $user - */ - public function setUser($user) - { - $user = posix_getpwnam($user); - if ($user) { - posix_setuid($user['uid']); - posix_setgid($user['gid']); - } - } - - /** - * 初始化 Console - * @access public - * @param bool $run 是否运行 Console - * @return int|Console - */ public static function init($run = true) { static $console; if (!$console) { - $config = Container::get('config')->pull('console'); - // 实例化 console - $console = new self($config['name'], $config['version'], $config['user']); + // 实例化console + $console = new self('Think Console', '0.1'); // 读取指令集 $file = Container::get('env')->get('app_path') . 'command.php'; diff --git a/thinkphp/library/think/Container.php b/thinkphp/library/think/Container.php index b138e6003..b934cb346 100644 --- a/thinkphp/library/think/Container.php +++ b/thinkphp/library/think/Container.php @@ -14,10 +14,8 @@ namespace think; use Closure; use InvalidArgumentException; use ReflectionClass; -use ReflectionException; use ReflectionFunction; use ReflectionMethod; -use think\exception\ClassNotFoundException; class Container { @@ -78,27 +76,6 @@ class Container return static::getInstance()->bind($abstract, $concrete); } - /** - * 移除容器中的对象实例 - * @access public - * @param string $abstract 类标识、接口 - * @return void - */ - public static function remove($abstract) - { - return static::getInstance()->delete($abstract); - } - - /** - * 清除容器中的对象实例 - * @access public - * @return void - */ - public static function clear() - { - return static::getInstance()->flush(); - } - /** * 绑定一个类、闭包、实例、接口实现到容器 * @access public @@ -178,184 +155,137 @@ class Container } if (isset($this->instances[$abstract]) && !$newInstance) { - return $this->instances[$abstract]; - } - - if (isset($this->bind[$abstract])) { - $concrete = $this->bind[$abstract]; - - if ($concrete instanceof Closure) { - $object = $this->invokeFunction($concrete, $vars); - } else { - $object = $this->make($concrete, $vars, $newInstance); - } + $object = $this->instances[$abstract]; } else { - $object = $this->invokeClass($abstract, $vars); - } + if (isset($this->bind[$abstract])) { + $concrete = $this->bind[$abstract]; - if (!$newInstance) { - $this->instances[$abstract] = $object; + if ($concrete instanceof Closure) { + $object = $this->invokeFunction($concrete, $vars); + } else { + $object = $this->make($concrete, $vars, $newInstance); + } + } else { + $object = $this->invokeClass($abstract, $vars); + } + + if (!$newInstance) { + $this->instances[$abstract] = $object; + } } return $object; } - /** - * 删除容器中的对象实例 - * @access public - * @param string $abstract 类名或者标识 - * @return void - */ - public function delete($abstract) - { - if (isset($this->instances[$abstract])) { - unset($this->instances[$abstract]); - } - } - - /** - * 清除容器中的对象实例 - * @access public - * @return void - */ - public function flush() - { - $this->instances = []; - $this->bind = []; - } - /** * 执行函数或者闭包方法 支持参数调用 * @access public - * @param mixed $function 函数或者闭包 - * @param array $vars 参数 + * @param string|array|\Closure $function 函数或者闭包 + * @param array $vars 变量 * @return mixed */ public function invokeFunction($function, $vars = []) { - try { - $reflect = new ReflectionFunction($function); + $reflect = new ReflectionFunction($function); + $args = $this->bindParams($reflect, $vars); - $args = $this->bindParams($reflect, $vars); - - return $reflect->invokeArgs($args); - } catch (ReflectionException $e) { - throw new Exception('function not exists: ' . $function . '()'); - } + return $reflect->invokeArgs($args); } /** * 调用反射执行类的方法 支持参数绑定 * @access public - * @param mixed $method 方法 - * @param array $vars 参数 + * @param string|array $method 方法 + * @param array $vars 变量 * @return mixed */ public function invokeMethod($method, $vars = []) { - try { - if (is_array($method)) { - $class = is_object($method[0]) ? $method[0] : $this->invokeClass($method[0]); - $reflect = new ReflectionMethod($class, $method[1]); - } else { - // 静态方法 - $reflect = new ReflectionMethod($method); - } - - $args = $this->bindParams($reflect, $vars); - - return $reflect->invokeArgs(isset($class) ? $class : null, $args); - } catch (ReflectionException $e) { - throw new Exception('method not exists: ' . (is_array($method) ? $method[0] . '::' . $method[1] : $method) . '()'); + if (is_array($method)) { + $class = is_object($method[0]) ? $method[0] : $this->invokeClass($method[0]); + $reflect = new ReflectionMethod($class, $method[1]); + } else { + // 静态方法 + $reflect = new ReflectionMethod($method); } - } - /** - * 调用反射执行类的方法 支持参数绑定 - * @access public - * @param object $instance 对象实例 - * @param mixed $reflect 反射类 - * @param array $vars 参数 - * @return mixed - */ - public function invokeReflectMethod($instance, $reflect, $vars = []) - { $args = $this->bindParams($reflect, $vars); - return $reflect->invokeArgs($instance, $args); + return $reflect->invokeArgs(isset($class) ? $class : null, $args); } /** * 调用反射执行callable 支持参数绑定 * @access public * @param mixed $callable - * @param array $vars 参数 + * @param array $vars 变量 * @return mixed */ public function invoke($callable, $vars = []) { if ($callable instanceof Closure) { - return $this->invokeFunction($callable, $vars); + $result = $this->invokeFunction($callable, $vars); + } else { + $result = $this->invokeMethod($callable, $vars); } - return $this->invokeMethod($callable, $vars); + return $result; } /** * 调用反射执行类的实例化 支持依赖注入 * @access public * @param string $class 类名 - * @param array $vars 参数 + * @param array $vars 变量 * @return mixed */ public function invokeClass($class, $vars = []) { - try { - $reflect = new ReflectionClass($class); + $reflect = new ReflectionClass($class); + $constructor = $reflect->getConstructor(); - $constructor = $reflect->getConstructor(); - - $args = $constructor ? $this->bindParams($constructor, $vars) : []; - - return $reflect->newInstanceArgs($args); - } catch (ReflectionException $e) { - throw new ClassNotFoundException('class not exists: ' . $class, $class); + if ($constructor) { + $args = $this->bindParams($constructor, $vars); + } else { + $args = []; } + + return $reflect->newInstanceArgs($args); } /** * 绑定参数 * @access protected * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 - * @param array $vars 参数 + * @param array $vars 变量 * @return array */ protected function bindParams($reflect, $vars = []) { - if ($reflect->getNumberOfParameters() == 0) { - return []; - } + $args = []; - // 判断数组类型 数字数组时按顺序绑定参数 - reset($vars); - $type = key($vars) === 0 ? 1 : 0; - $params = $reflect->getParameters(); + if ($reflect->getNumberOfParameters() > 0) { + // 判断数组类型 数字数组时按顺序绑定参数 + reset($vars); + $type = key($vars) === 0 ? 1 : 0; + $params = $reflect->getParameters(); - foreach ($params as $param) { - $name = $param->getName(); - $class = $param->getClass(); + foreach ($params as $param) { + $name = $param->getName(); + $class = $param->getClass(); - if ($class) { - $className = $class->getName(); - $args[] = $this->make($className); - } elseif (1 == $type && !empty($vars)) { - $args[] = array_shift($vars); - } elseif (0 == $type && isset($vars[$name])) { - $args[] = $vars[$name]; - } elseif ($param->isDefaultValueAvailable()) { - $args[] = $param->getDefaultValue(); - } else { - throw new InvalidArgumentException('method param miss:' . $name); + if ($class) { + $className = $class->getName(); + $args[] = $this->make($className); + } elseif (1 == $type && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $type && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + throw new InvalidArgumentException('method param miss:' . $name); + } } } diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php index 28909c89f..cc3953d24 100644 --- a/thinkphp/library/think/Controller.php +++ b/thinkphp/library/think/Controller.php @@ -70,10 +70,12 @@ class Controller $this->initialize(); // 前置操作方法 - foreach ((array) $this->beforeActionList as $method => $options) { - is_numeric($method) ? - $this->beforeAction($options) : - $this->beforeAction($method, $options); + if ($this->beforeActionList) { + foreach ($this->beforeActionList as $method => $options) { + is_numeric($method) ? + $this->beforeAction($options) : + $this->beforeAction($method, $options); + } } } @@ -118,10 +120,6 @@ class Controller */ protected function fetch($template = '', $vars = [], $config = []) { - if ('' === $template) { - $template = Loader::parseName($this->request->action(true)); - } - return $this->view->fetch($template, $vars, $config); } @@ -234,10 +232,11 @@ class Controller if (!$v->check($data)) { if ($this->failException) { throw new ValidateException($v->getError()); + } else { + return $v->getError(); } - return $v->getError(); + } else { + return true; } - - return true; } } diff --git a/thinkphp/library/think/Db.php b/thinkphp/library/think/Db.php index 6ce22f391..21770e081 100644 --- a/thinkphp/library/think/Db.php +++ b/thinkphp/library/think/Db.php @@ -14,7 +14,6 @@ namespace think; /** * Class Db * @package think - * @method \think\db\Query connect(array $config =[], mixed $name = false) static 连接/切换数据库连接 * @method \think\db\Query table(string $table) static 指定数据表(含前缀) * @method \think\db\Query name(string $name) static 指定数据表(不含前缀) * @method \think\db\Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 @@ -43,8 +42,7 @@ namespace think; * @method void commit() static 用于非自动提交状态下面的查询提交 * @method void rollback() static 事务回滚 * @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句 - * @method string getLastInsID(string $sequence = null) static 获取最近插入的ID - * @method mixed getConfig(string $name = '') static 获取数据库的配置参数 + * @method string getLastInsID($sequence = null) static 获取最近插入的ID */ class Db { diff --git a/thinkphp/library/think/Debug.php b/thinkphp/library/think/Debug.php index 75003770b..8a384e147 100644 --- a/thinkphp/library/think/Debug.php +++ b/thinkphp/library/think/Debug.php @@ -223,8 +223,9 @@ class Debug if ($echo) { echo($output); return; + } else { + return $output; } - return $output; } public function inject(Response $response, &$content) diff --git a/thinkphp/library/think/Env.php b/thinkphp/library/think/Env.php index ef5d9468d..2c41794ff 100644 --- a/thinkphp/library/think/Env.php +++ b/thinkphp/library/think/Env.php @@ -62,21 +62,21 @@ class Env { $result = getenv('PHP_' . $name); - if (false === $result) { + if (false !== $result) { + if ('false' === $result) { + $result = false; + } elseif ('true' === $result) { + $result = true; + } + + if (!isset($this->data[$name])) { + $this->data[$name] = $result; + } + + return $result; + } else { return $default; } - - if ('false' === $result) { - $result = false; - } elseif ('true' === $result) { - $result = true; - } - - if (!isset($this->data[$name])) { - $this->data[$name] = $result; - } - - return $result; } /** diff --git a/thinkphp/library/think/Error.php b/thinkphp/library/think/Error.php index b8c8fc585..c00a36a65 100644 --- a/thinkphp/library/think/Error.php +++ b/thinkphp/library/think/Error.php @@ -66,9 +66,9 @@ class Error if (error_reporting() & $errno) { // 将错误信息托管至 think\exception\ErrorException throw $exception; + } else { + self::getExceptionHandler()->report($exception); } - - self::getExceptionHandler()->report($exception); } /** diff --git a/thinkphp/library/think/Facade.php b/thinkphp/library/think/Facade.php index c455f6626..2cda381c7 100644 --- a/thinkphp/library/think/Facade.php +++ b/thinkphp/library/think/Facade.php @@ -88,10 +88,6 @@ class Facade */ public static function instance(...$args) { - if (__CLASS__ != static::class) { - return self::__callStatic('instance', $args); - } - return self::createFacade('', $args); } diff --git a/thinkphp/library/think/File.php b/thinkphp/library/think/File.php index e9985690c..00e83a58b 100644 --- a/thinkphp/library/think/File.php +++ b/thinkphp/library/think/File.php @@ -147,7 +147,7 @@ class File extends SplFileObject /** * 检查目录是否可写 - * @access protected + * @access public * @param string $path 目录 * @return boolean */ @@ -159,10 +159,10 @@ class File extends SplFileObject if (mkdir($path, 0755, true)) { return true; + } else { + $this->error = ['directory {:path} creation failed', ['path' => $path]]; + return false; } - - $this->error = ['directory {:path} creation failed', ['path' => $path]]; - return false; } /** @@ -227,10 +227,27 @@ class File extends SplFileObject { $rule = $rule ?: $this->validate; - if ((isset($rule['size']) && !$this->checkSize($rule['size'])) - || (isset($rule['type']) && !$this->checkMime($rule['type'])) - || (isset($rule['ext']) && !$this->checkExt($rule['ext'])) - || !$this->checkImg()) { + /* 检查文件大小 */ + if (isset($rule['size']) && !$this->checkSize($rule['size'])) { + $this->error = 'filesize not match'; + return false; + } + + /* 检查文件Mime类型 */ + if (isset($rule['type']) && !$this->checkMime($rule['type'])) { + $this->error = 'mimetype to upload is not allowed'; + return false; + } + + /* 检查文件后缀 */ + if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) { + $this->error = 'extensions to upload is not allowed'; + return false; + } + + /* 检查图像文件 */ + if (!$this->checkImg()) { + $this->error = 'illegal image files'; return false; } @@ -252,7 +269,6 @@ class File extends SplFileObject $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); if (!in_array($extension, $ext)) { - $this->error = 'extensions to upload is not allowed'; return false; } @@ -270,7 +286,6 @@ class File extends SplFileObject /* 对图像文件进行严格检测 */ if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13])) { - $this->error = 'illegal image files'; return false; } @@ -282,13 +297,13 @@ class File extends SplFileObject { if (function_exists('exif_imagetype')) { return exif_imagetype($image); - } - - try { - $info = getimagesize($image); - return $info ? $info[2] : false; - } catch (\Exception $e) { - return false; + } else { + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } } } @@ -301,7 +316,6 @@ class File extends SplFileObject public function checkSize($size) { if ($this->getSize() > $size) { - $this->error = 'filesize not match'; return false; } @@ -321,7 +335,6 @@ class File extends SplFileObject } if (!in_array(strtolower($this->getMime()), $mime)) { - $this->error = 'mimetype to upload is not allowed'; return false; } @@ -389,7 +402,7 @@ class File extends SplFileObject /** * 获取保存文件名 - * @access protected + * @access public * @param string|bool $savename 保存的文件名 默认自动生成 * @return string */ @@ -397,9 +410,25 @@ class File extends SplFileObject { if (true === $savename) { // 自动生成文件名 - $savename = $this->autoBuildName(); + if ($this->rule instanceof \Closure) { + $savename = call_user_func_array($this->rule, [$this]); + } else { + switch ($this->rule) { + case 'date': + $savename = date('Ymd') . '/' . md5(microtime(true)); + break; + default: + if (in_array($this->rule, hash_algos())) { + $hash = $this->hash($this->rule); + $savename = substr($hash, 0, 2) . '/' . substr($hash, 2); + } elseif (is_callable($this->rule)) { + $savename = call_user_func($this->rule); + } else { + $savename = date('Ymd') . '/' . md5(microtime(true)); + } + } + } } elseif ('' === $savename || false === $savename) { - // 保留原文件名 $savename = $this->getInfo('name'); } @@ -410,38 +439,9 @@ class File extends SplFileObject return $savename; } - /** - * 自动生成文件名 - * @access protected - * @return string - */ - protected function autoBuildName() - { - if ($this->rule instanceof \Closure) { - $savename = call_user_func_array($this->rule, [$this]); - } else { - switch ($this->rule) { - case 'date': - $savename = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true)); - break; - default: - if (in_array($this->rule, hash_algos())) { - $hash = $this->hash($this->rule); - $savename = substr($hash, 0, 2) . DIRECTORY_SEPARATOR . substr($hash, 2); - } elseif (is_callable($this->rule)) { - $savename = call_user_func($this->rule); - } else { - $savename = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true)); - } - } - } - - return $savename; - } - /** * 获取错误代码信息 - * @access private + * @access public * @param int $errorNo 错误号 */ private function error($errorNo) diff --git a/thinkphp/library/think/Hook.php b/thinkphp/library/think/Hook.php index b82fb5a09..30b673073 100644 --- a/thinkphp/library/think/Hook.php +++ b/thinkphp/library/think/Hook.php @@ -116,9 +116,9 @@ class Hook if (empty($tag)) { //获取全部的插件信息 return $this->tags; + } else { + return array_key_exists($tag, $this->tags) ? $this->tags[$tag] : []; } - - return array_key_exists($tag, $this->tags) ? $this->tags[$tag] : []; } /** @@ -137,7 +137,10 @@ class Hook foreach ($tags as $key => $name) { $results[$key] = $this->execTag($name, $tag, $params); - if (false === $results[$key] || (!is_null($results[$key]) && $once)) { + if (false === $results[$key]) { + // 如果返回false 则中断行为执行 + break; + } elseif (!is_null($results[$key]) && $once) { break; } } diff --git a/thinkphp/library/think/Lang.php b/thinkphp/library/think/Lang.php index 2168c13a5..ba4f700ab 100644 --- a/thinkphp/library/think/Lang.php +++ b/thinkphp/library/think/Lang.php @@ -79,9 +79,9 @@ class Lang if (is_array($name)) { return $this->lang[$range] = array_change_key_case($name) + $this->lang[$range]; + } else { + return $this->lang[$range][strtolower($name)] = $value; } - - return $this->lang[$range][strtolower($name)] = $value; } /** diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php index 168ed1f86..76fbde936 100644 --- a/thinkphp/library/think/Loader.php +++ b/thinkphp/library/think/Loader.php @@ -58,44 +58,29 @@ class Loader // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); - $path = realpath(dirname($_SERVER['SCRIPT_FILENAME'])); + // 注册命名空间定义 + self::addNamespace([ + 'think' => __DIR__ . '/', + 'traits' => __DIR__ . '/../traits/', + ]); - if ('cli-server' == PHP_SAPI || !is_file('./think')) { - $rootPath = dirname($path) . DIRECTORY_SEPARATOR; + $path = dirname($_SERVER['SCRIPT_FILENAME']); + if (is_file('./think')) { + $rootPath = realpath($path) . '/'; } else { - $rootPath = $path . DIRECTORY_SEPARATOR; + $rootPath = realpath($path . '/../') . '/'; } - self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR; + // 加载类库映射文件 + if (is_file($rootPath . 'runtime/classmap.php')) { + self::addClassMap(__include_file($rootPath . 'runtime/classmap.php')); + } + + self::$composerPath = $rootPath . 'vendor/composer/'; // Composer自动加载支持 if (is_dir(self::$composerPath)) { - if (is_file(self::$composerPath . 'autoload_static.php')) { - require self::$composerPath . 'autoload_static.php'; - - $declaredClass = get_declared_classes(); - $composerClass = array_pop($declaredClass); - - self::$prefixLengthsPsr4 = $composerClass::$prefixLengthsPsr4; - - self::$prefixDirsPsr4 = property_exists($composerClass, 'prefixDirsPsr4') ? $composerClass::$prefixDirsPsr4 : []; - - self::$prefixesPsr0 = property_exists($composerClass, 'prefixesPsr0') ? $composerClass::$prefixesPsr0 : []; - self::$map = property_exists($composerClass, 'classMap') ? $composerClass::$classMap : []; - } else { - self::registerComposerLoader(self::$composerPath); - } - } - - // 注册命名空间定义 - self::addNamespace([ - 'think' => __DIR__, - 'traits' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'traits', - ]); - - // 加载类库映射文件 - if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) { - self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')); + self::registerComposerLoader(self::$composerPath); } // 自动加载extend目录 @@ -361,9 +346,9 @@ class Loader return strtoupper($match[1]); }, $name); return $ucfirst ? ucfirst($name) : lcfirst($name); + } else { + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } - - return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } } diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php index 0e8248dfd..49258141b 100644 --- a/thinkphp/library/think/Log.php +++ b/thinkphp/library/think/Log.php @@ -49,12 +49,6 @@ class Log implements LoggerInterface */ protected $key; - /** - * 是否允许日志写入 - * @var bool - */ - protected $allowWrite = true; - /** * 应用对象 * @var App @@ -114,10 +108,6 @@ class Log implements LoggerInterface */ public function record($msg, $type = 'info', array $context = []) { - if (!$this->allowWrite) { - return; - } - if (is_string($msg)) { $replace = []; foreach ($context as $key => $val) { @@ -177,19 +167,6 @@ class Log implements LoggerInterface return true; } - /** - * 关闭本次请求日志写入 - * @access public - * @return $this - */ - public function close() - { - $this->allowWrite = false; - $this->log = []; - - return $this; - } - /** * 保存调试信息 * @access public @@ -197,41 +174,41 @@ class Log implements LoggerInterface */ public function save() { - if (empty($this->log) || !$this->allowWrite) { - return true; - } - - if (is_null($this->driver)) { - $this->init($this->app['config']->pull('log')); - } - - if (!$this->check($this->config)) { - // 检测日志写入权限 - return false; - } - - if (empty($this->config['level'])) { - // 获取全部日志 - $log = $this->log; - if (!$this->app->isDebug() && isset($log['debug'])) { - unset($log['debug']); + if (!empty($this->log)) { + if (is_null($this->driver)) { + $this->init($this->app['config']->pull('log')); } - } else { - // 记录允许级别 - $log = []; - foreach ($this->config['level'] as $level) { - if (isset($this->log[$level])) { - $log[$level] = $this->log[$level]; + + if (!$this->check($this->config)) { + // 检测日志写入权限 + return false; + } + + if (empty($this->config['level'])) { + // 获取全部日志 + $log = $this->log; + if (!$this->app->isDebug() && isset($log['debug'])) { + unset($log['debug']); + } + } else { + // 记录允许级别 + $log = []; + foreach ($this->config['level'] as $level) { + if (isset($this->log[$level])) { + $log[$level] = $this->log[$level]; + } } } + + $result = $this->driver->save($log); + if ($result) { + $this->log = []; + } + + return $result; } - $result = $this->driver->save($log); - if ($result) { - $this->log = []; - } - - return $result; + return true; } /** diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index 433e6d096..3b673464e 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -389,7 +389,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 检查数据是否允许写入 * @access protected - * @param array $append 自动完成的字段列表 + * @param array $autoFields 自动完成的字段列表 * @return array */ protected function checkAllowFields(array $append = []) @@ -478,11 +478,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $where = $array; } - foreach ((array) $this->relationWrite as $name => $val) { - if (is_array($val)) { - foreach ($val as $key) { - if (isset($data[$key])) { - unset($data[$key]); + if (!empty($this->relationWrite)) { + foreach ($this->relationWrite as $name => $val) { + if (is_array($val)) { + foreach ($val as $key) { + if (isset($data[$key])) { + unset($data[$key]); + } } } } @@ -859,15 +861,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function destroy($data) { - if (empty($data) && 0 !== $data) { - return 0; - } - $model = new static(); $query = $model->db(); - if (is_array($data) && key($data) !== 0) { + if (empty($data) && 0 !== $data) { + return 0; + } elseif (is_array($data) && key($data) !== 0) { $query->where($data); $data = null; } elseif ($data instanceof \Closure) { @@ -947,9 +947,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) { return true; + } else { + return false; } - - return false; } /** diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php index e2f9b898f..3fccdf9e6 100644 --- a/thinkphp/library/think/Paginator.php +++ b/thinkphp/library/think/Paginator.php @@ -104,8 +104,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @param $items * @param $listRows * @param null $currentPage - * @param null $total * @param bool $simple + * @param null $total * @param array $options * @return Paginator */ @@ -150,7 +150,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J $url = $path; if (!empty($parameters)) { - $url .= '?' . http_build_query($parameters, null, '&'); + $url .= '?' . urldecode(http_build_query($parameters, null, '&')); } return $url . $this->buildFragment(); diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index 66b88ce9c..1868c5f40 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -251,12 +251,6 @@ class Request */ protected $isCheckCache; - /** - * 请求安全Key - * @var string - */ - protected $secureKey; - /** * 架构函数 * @access public @@ -285,9 +279,9 @@ class Request if (array_key_exists($method, $this->hook)) { array_unshift($args, $this); return call_user_func_array($this->hook[$method], $args); + } else { + throw new Exception('method not exists:' . static::class . '->' . $method); } - - throw new Exception('method not exists:' . static::class . '->' . $method); } /** @@ -409,28 +403,10 @@ class Request return $this->domain; } - /** - * 获取当前根域名 - * @access public - * @return string - */ - public function rootDomain() - { - $root = $this->config->get('app.url_domain_root'); - - if (!$root) { - $item = explode('.', $this->host()); - $count = count($item); - $root = $count > 1 ? $item[$count - 2] . '.' . $item[$count - 1] : $item[0]; - } - - return $root; - } - /** * 获取当前子域名 * @access public - * @return string + * @return string|$this */ public function subDomain() { @@ -461,10 +437,10 @@ class Request { if (is_null($domain)) { return $this->panDomain; + } else { + $this->panDomain = $domain; + return $this; } - - $this->panDomain = $domain; - return $this; } /** @@ -616,7 +592,7 @@ class Request } } - $this->pathinfo = empty($_SERVER['PATH_INFO']) || '/' == $_SERVER['PATH_INFO'] ? '' : ltrim($_SERVER['PATH_INFO'], '/'); + $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/'); } return $this->pathinfo; @@ -1105,12 +1081,37 @@ class Request $files = $this->file; if (!empty($files)) { // 处理上传文件 - $array = $this->dealUploadFile($files); - + $array = []; + foreach ($files as $key => $file) { + if (is_array($file['name'])) { + $item = []; + $keys = array_keys($file); + $count = count($file['name']); + for ($i = 0; $i < $count; $i++) { + if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) { + continue; + } + $temp['key'] = $key; + foreach ($keys as $_key) { + $temp[$_key] = $file[$_key][$i]; + } + $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp); + } + $array[$key] = $item; + } else { + if ($file instanceof File) { + $array[$key] = $file; + } else { + if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) { + continue; + } + $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file); + } + } + } if (strpos($name, '.')) { list($name, $sub) = explode('.', $name); } - if ('' === $name) { // 获取全部文件 return $array; @@ -1124,46 +1125,6 @@ class Request return; } - protected function dealUploadFile($files) - { - $array = []; - foreach ($files as $key => $file) { - if (is_array($file['name'])) { - $item = []; - $keys = array_keys($file); - $count = count($file['name']); - - for ($i = 0; $i < $count; $i++) { - if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) { - continue; - } - - $temp['key'] = $key; - - foreach ($keys as $_key) { - $temp[$_key] = $file[$_key][$i]; - } - - $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp); - } - - $array[$key] = $item; - } else { - if ($file instanceof File) { - $array[$key] = $file; - } else { - if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) { - continue; - } - - $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file); - } - } - } - - return $array; - } - /** * 获取环境变量 * @access public @@ -1253,7 +1214,6 @@ class Request } else { $type = 's'; } - // 按.拆分成多维数组进行判断 foreach (explode('.', $name) as $val) { if (isset($data[$val])) { @@ -1263,7 +1223,6 @@ class Request return $default; } } - if (is_object($data)) { return $data; } @@ -1297,9 +1256,9 @@ class Request { if (is_null($filter)) { return $this->filter; + } else { + $this->filter = $filter; } - - $this->filter = $filter; } protected function getFilter($filter, $default) @@ -1519,9 +1478,9 @@ class Request if (true === $ajax) { return $result; + } else { + return $this->param($this->config->get('var_ajax')) ? true : $result; } - - return $this->param($this->config->get('var_ajax')) ? true : $result; } /** @@ -1536,9 +1495,9 @@ class Request if (true === $pjax) { return $result; + } else { + return $this->param($this->config->get('var_pjax')) ? true : $result; } - - return $this->param($this->config->get('var_pjax')) ? true : $result; } /** @@ -1596,9 +1555,9 @@ class Request return true; } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) { return true; + } else { + return false; } - - return false; } /** @@ -1696,9 +1655,9 @@ class Request { if (!empty($route)) { $this->routeInfo = $route; + } else { + return $this->routeInfo; } - - return $this->routeInfo; } /** @@ -1716,20 +1675,6 @@ class Request return $this->dispatch; } - /** - * 获取当前请求的安全Key - * @access public - * @return string - */ - public function secureKey() - { - if (is_null($this->secureKey)) { - $this->secureKey = uniqid('', true); - } - - return $this->secureKey; - } - /** * 设置或者获取当前的模块名 * @access public @@ -1741,9 +1686,9 @@ class Request if (!is_null($module)) { $this->module = $module; return $this; + } else { + return $this->module ?: ''; } - - return $this->module ?: ''; } /** @@ -1757,9 +1702,9 @@ class Request if (!is_null($controller)) { $this->controller = $controller; return $this; + } else { + return $this->controller ?: ''; } - - return $this->controller ?: ''; } /** @@ -1770,13 +1715,12 @@ class Request */ public function action($action = null) { - if (!is_null($action) && !is_bool($action)) { + if (!is_null($action)) { $this->action = $action; return $this; + } else { + return $this->action ?: ''; } - - $name = $this->action ?: ''; - return true === $action ? $name : strtolower($name); } /** @@ -1790,9 +1734,9 @@ class Request if (!is_null($lang)) { $this->langset = $lang; return $this; + } else { + return $this->langset ?: ''; } - - return $this->langset ?: ''; } /** @@ -1856,67 +1800,66 @@ class Request $except = []; } - if (false === $key || !$this->isGet() || $this->isCheckCache || false === $expire) { - // 关闭当前缓存 - return; - } - - // 标记请求缓存检查 - $this->isCheckCache = true; - - foreach ($except as $rule) { - if (0 === stripos($this->url(), $rule)) { + if (false !== $key && $this->isGet() && !$this->isCheckCache) { + // 标记请求缓存检查 + $this->isCheckCache = true; + if (false === $expire) { + // 关闭当前缓存 return; } - } - if ($key instanceof \Closure) { - $key = call_user_func_array($key, [$this]); - } elseif (true === $key) { - // 自动缓存功能 - $key = '__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(true))], $key); - } - - if (false !== strpos($key, ':')) { - $param = $this->param(); - foreach ($param as $item => $val) { - if (is_string($val) && false !== strpos($key, ':' . $item)) { - $key = str_replace(':' . $item, $val, $key); + foreach ($except as $rule) { + if (0 === stripos($this->url(), $rule)) { + return; } } - } elseif (strpos($key, ']')) { - if ('[' . $this->ext() . ']' == $key) { - // 缓存某个后缀的请求 - $key = md5($this->url()); + + if ($key instanceof \Closure) { + $key = call_user_func_array($key, [$this]); + } elseif (true === $key) { + // 自动缓存功能 + $key = '__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(true))], $key); + } + + if (false !== strpos($key, ':')) { + $param = $this->param(); + foreach ($param as $item => $val) { + if (is_string($val) && false !== strpos($key, ':' . $item)) { + $key = str_replace(':' . $item, $val, $key); + } + } + } elseif (strpos($key, ']')) { + if ('[' . $this->ext() . ']' == $key) { + // 缓存某个后缀的请求 + $key = md5($this->url()); + } else { + return; + } + } + + if (isset($fun)) { + $key = $fun($key); + } + $cache = Container::get('cache'); + if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) { + // 读取缓存 + $response = Response::create()->code(304); + throw new HttpResponseException($response); + } elseif ($cache->has($key)) { + list($content, $header) = $cache->get($key); + $response = Response::create($content)->header($header); + throw new HttpResponseException($response); } else { - return; + $this->cache = [$key, $expire, $tag]; } } - - if (isset($fun)) { - $key = $fun($key); - } - $cache = Container::get('cache'); - - if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) { - // 读取缓存 - $response = Response::create()->code(304); - throw new HttpResponseException($response); - } elseif ($cache->has($key)) { - list($content, $header) = $cache->get($key); - - $response = Response::create($content)->header($header); - throw new HttpResponseException($response); - } - - $this->cache = [$key, $expire, $tag]; } /** @@ -1929,15 +1872,4 @@ class Request return $this->cache; } - /** - * 获取请求数据的值 - * @access public - * @param string $name 名称 - * @return mixed - */ - public function __get($name) - { - return $this->param($name); - } - } diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php index 071d075c7..e554ab313 100644 --- a/thinkphp/library/think/Response.php +++ b/thinkphp/library/think/Response.php @@ -103,9 +103,9 @@ class Response if (class_exists($class)) { return new $class($data, $code, $header, $options); + } else { + return new static($data, $code, $header, $options); } - - return new static($data, $code, $header, $options); } /** @@ -352,9 +352,9 @@ class Response { if (!empty($name)) { return isset($this->header[$name]) ? $this->header[$name] : null; + } else { + return $this->header; } - - return $this->header; } /** diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index 81f914b9f..ae7919e22 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -12,7 +12,6 @@ namespace think; use think\exception\RouteNotFoundException; -use think\route\AliasRule; use think\route\dispatch\Url as UrlDispatch; use think\route\Domain; use think\route\Resource; @@ -72,11 +71,17 @@ class Route protected $domain; /** - * 当前分组对象 - * @var RuleGroup + * 当前分组 + * @var string */ protected $group; + /** + * 路由标识 + * @var array + */ + protected $name = []; + /** * 路由绑定 * @var array @@ -95,76 +100,27 @@ class Route */ protected $cross; + /** + * 当前路由标识 + * @var string + */ + protected $ruleName; + /** * 路由别名 * @var array */ protected $alias = []; - /** - * 路由是否延迟解析 - * @var bool - */ - protected $lazy = true; - - /** - * (分组)路由规则是否合并解析 - * @var bool - */ - protected $mergeRuleRegex = true; - - /** - * 路由解析自动搜索多级控制器 - * @var bool - */ - protected $autoSearchController = true; - - public function __construct(Request $request) + public function __construct(Request $request, Config $config) { + $this->config = $config; $this->request = $request; $this->host = $this->request->host(); $this->setDefaultDomain(); } - /** - * 设置路由域名及分组(包括资源路由)是否延迟解析 - * @access public - * @param bool $lazy 路由是否延迟解析 - * @return $this - */ - public function lazy($lazy = true) - { - $this->lazy = $lazy; - return $this; - } - - /** - * 设置路由域名及分组(包括资源路由)是否合并解析 - * @access public - * @param bool $merge 路由是否合并解析 - * @return $this - */ - public function mergeRuleRegex($merge = true) - { - $this->mergeRuleRegex = $merge; - $this->group->mergeRuleRegex($merge); - - return $this; - } - - /** - * 设置路由自动解析是否搜索多级控制器 - * @access public - * @param bool $auto 是否自动搜索多级控制器 - * @return $this - */ - public function autoSearchController($auto = true) - { - $this->autoSearchController = $auto; - return $this; - } - /** * 初始化默认域名 * @access protected @@ -181,7 +137,22 @@ class Route $this->domains[$this->host] = $domain; // 默认分组 - $this->group = $domain; + $this->group = $this->createTopGroup($domain); + } + + /** + * 创建一个域名下的顶级路由分组 + * @access protected + * @param Domain $domain 域名 + * @return RuleGroup + */ + protected function createTopGroup(Domain $domain) + { + $group = new RuleGroup($this); + // 注册分组到当前域名 + $domain->addRule($group); + + return $group; } /** @@ -233,6 +204,22 @@ class Route return $this; } + /** + * 获取当前根域名 + * @access protected + * @return string + */ + protected function getRootDomain() + { + $root = $this->config->get('app.url_domain_root'); + if (!$root) { + $item = explode('.', $this->host); + $count = count($item); + $root = $count > 1 ? $item[$count - 2] . '.' . $item[$count - 1] : $item[0]; + } + return $root; + } + /** * 注册域名路由 * @access public @@ -248,22 +235,33 @@ class Route $domainName = is_array($name) ? array_shift($name) : $name; if ('*' != $domainName && !strpos($domainName, '.')) { - $domainName .= '.' . $this->request->rootDomain(); + $domainName .= '.' . $this->getRootDomain(); } - if (!isset($this->domains[$domainName])) { - $domain = (new Domain($this, $domainName, $rule, $option, $pattern)) - ->lazy($this->lazy) - ->mergeRuleRegex($this->mergeRuleRegex); + $route = $this->config->get('url_lazy_route') ? $rule : null; - $this->domains[$domainName] = $domain; - } else { - $domain = $this->domains[$domainName]; - $domain->parseGroupRule($rule); + $domain = new Domain($this, $domainName, $route, $option, $pattern); + + if (is_null($route)) { + // 获取原始分组 + $originGroup = $this->group; + // 设置当前域名 + $this->domain = $domainName; + $this->group = $this->createTopGroup($domain); + + // 解析域名路由规则 + $this->parseGroupRule($domain, $rule); + + // 还原默认域名 + $this->domain = $this->host; + // 还原默认分组 + $this->group = $originGroup; } + $this->domains[$domainName] = $domain; + if (is_array($name) && !empty($name)) { - $root = $this->request->rootDomain(); + $root = $this->getRootDomain(); foreach ($name as $item) { if (!strpos($item, '.')) { $item .= '.' . $root; @@ -277,6 +275,32 @@ class Route return $domain; } + /** + * 解析分组和域名的路由规则及绑定 + * @access public + * @param RuleGroup $group 分组路由对象 + * @param mixed $rule 路由规则 + * @return void + */ + public function parseGroupRule($group, $rule) + { + if ($rule instanceof \Closure) { + Container::getInstance()->invokeFunction($rule); + } elseif ($rule instanceof Response) { + $group->setRule($rule); + } elseif (is_array($rule)) { + $this->rules($rule); + } elseif ($rule) { + if (false !== strpos($rule, '?')) { + list($rule, $query) = explode('?', $rule); + parse_str($query, $vars); + $group->append($vars); + } + + $this->bind($rule); + } + } + /** * 获取域名 * @access public @@ -291,14 +315,11 @@ class Route * 设置路由绑定 * @access public * @param string $bind 绑定信息 - * @param string $domain 域名 * @return $this */ - public function bind($bind, $domain = null) + public function bind($bind) { - $domain = is_null($domain) ? $this->domain : $domain; - - $this->bind[$domain] = $bind; + $this->bind[$this->domain] = $bind; return $this; } @@ -334,6 +355,19 @@ class Route return $result; } + /** + * 设置当前路由标识 + * @access public + * @param string $name 路由命名标识 + * @return $this + */ + public function name($name) + { + $this->ruleName = $name; + + return $this; + } + /** * 读取路由标识 * @access public @@ -342,7 +376,13 @@ class Route */ public function getName($name = null) { - return Container::get('rule_name')->get($name); + if (is_null($name)) { + return $this->name; + } + + $name = strtolower($name); + + return isset($this->name[$name]) ? $this->name[$name] : null; } /** @@ -353,7 +393,7 @@ class Route */ public function setName($name) { - Container::get('rule_name')->import($name); + $this->name = $name; return $this; } @@ -425,9 +465,68 @@ class Route * @param array $pattern 变量规则 * @return RuleItem */ - public function rule($rule, $route, $method = '*', array $option = [], array $pattern = []) + public function rule($rule, $route, $method = '*', $option = [], $pattern = []) { - return $this->group->addRule($rule, $route, $method, $option, $pattern); + // 读取路由标识 + if (is_array($rule)) { + $name = $rule[0]; + $rule = $rule[1]; + } elseif ($this->ruleName) { + $name = $this->ruleName; + + $this->ruleName = null; + } elseif (is_string($route)) { + $name = $route; + } + + $method = strtolower($method); + + // 创建路由规则实例 + $ruleItem = new RuleItem($this, $this->group, $rule, $route, $method, $option, $pattern); + + if (isset($name)) { + // 上级完整分组名 + $group = $this->group->getFullName(); + + if ($group) { + $rule = $group . '/' . $rule; + } + + // 设置路由标识 用于URL快速生成 + $this->setRuleName($rule, $name, $option); + } + + // 添加到当前分组 + $this->group->addRule($ruleItem, $method); + + if (!empty($option['cross_domain'])) { + $this->setCrossDomainRule($ruleItem, $method); + } + + return $ruleItem; + } + + /** + * 设置路由标识 用于URL反解生成 + * @access public + * @param string $rule 路由规则 + * @param string $name 路由标识 + * @param array $option 路由参数 + * @return void + */ + public function setRuleName($rule, $name, $option = []) + { + $vars = $this->parseVar($rule); + + if (isset($option['ext'])) { + $suffix = $option['ext']; + } elseif ($this->group->getOption('ext')) { + $suffix = $this->group->getOption('ext'); + } else { + $suffix = null; + } + + $this->name[strtolower($name)][] = [$rule, $vars, $this->domain, $suffix]; } /** @@ -440,10 +539,10 @@ class Route public function setCrossDomainRule($rule, $method = '*') { if (!isset($this->cross)) { - $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex); + $this->cross = new RuleGroup($this); } - $this->cross->addRuleItem($rule, $method); + $this->cross->addRule($rule, $method); return $this; } @@ -457,9 +556,23 @@ class Route * @param array $pattern 变量规则 * @return void */ - public function rules($rules, $method = '*', array $option = [], array $pattern = []) + public function rules($rules, $method = '*', $option = [], $pattern = []) { - $this->group->addRules($rules, $method, $option, $pattern); + foreach ($rules as $key => $val) { + if (is_numeric($key)) { + $key = array_shift($val); + } + + if (is_array($val)) { + $route = array_shift($val); + $option = $val ? array_shift($val) : []; + $pattern = $val ? array_shift($val) : []; + } else { + $route = $val; + } + + $this->rule($key, $route, $method, $option, $pattern); + } } /** @@ -471,28 +584,49 @@ class Route * @param array $pattern 变量规则 * @return RuleGroup */ - public function group($name, $route, array $option = [], array $pattern = []) + public function group($name, $route, $option = [], $pattern = []) { if (is_array($name)) { $option = $name; $name = isset($option['name']) ? $option['name'] : ''; } - return (new RuleGroup($this, $this->group, $name, $route, $option, $pattern)) - ->lazy($this->lazy) - ->mergeRuleRegex($this->mergeRuleRegex); + // 创建分组实例 + $rule = $this->config->get('url_lazy_route') ? $route : null; + $group = new RuleGroup($this, $this->group, $name, $rule, $option, $pattern); + + if (is_null($rule)) { + // 解析分组路由 + $parent = $this->getGroup(); + + $this->group = $group; + + // 解析分组路由规则 + $this->parseGroupRule($group, $route); + + $this->group = $parent; + } + + // 注册子分组 + $this->group->addRule($group); + + if (!empty($option['cross_domain'])) { + $this->setCrossDomainRule($group); + } + + return $group; } /** * 注册路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function any($rule, $route = '', array $option = [], array $pattern = []) + public function any($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, '*', $option, $pattern); } @@ -501,12 +635,12 @@ class Route * 注册GET路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function get($rule, $route = '', array $option = [], array $pattern = []) + public function get($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, 'GET', $option, $pattern); } @@ -515,12 +649,12 @@ class Route * 注册POST路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function post($rule, $route = '', array $option = [], array $pattern = []) + public function post($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, 'POST', $option, $pattern); } @@ -529,12 +663,12 @@ class Route * 注册PUT路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function put($rule, $route = '', array $option = [], array $pattern = []) + public function put($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, 'PUT', $option, $pattern); } @@ -543,12 +677,12 @@ class Route * 注册DELETE路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function delete($rule, $route = '', array $option = [], array $pattern = []) + public function delete($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, 'DELETE', $option, $pattern); } @@ -557,12 +691,12 @@ class Route * 注册PATCH路由 * @access public * @param string $rule 路由规则 - * @param mixed $route 路由地址 + * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function patch($rule, $route = '', array $option = [], array $pattern = []) + public function patch($rule, $route = '', $option = [], $pattern = []) { return $this->rule($rule, $route, 'PATCH', $option, $pattern); } @@ -576,31 +710,32 @@ class Route * @param array $pattern 变量规则 * @return Resource */ - public function resource($rule, $route = '', array $option = [], array $pattern = []) + public function resource($rule, $route = '', $option = [], $pattern = []) { - return (new Resource($this, $this->group, $rule, $route, $option, $pattern, $this->rest)) - ->lazy($this->lazy); + $resource = new Resource($this, $this->group, $rule, $route, $option, $pattern, $this->rest); + + // 添加到当前分组 + $this->group->addRule($resource); + + return $resource; } /** - * 注册控制器路由 操作方法对应不同的请求前缀 + * 注册控制器路由 操作方法对应不同的请求后缀 * @access public * @param string $rule 路由规则 * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 - * @return RuleGroup + * @return $this */ - public function controller($rule, $route = '', array $option = [], array $pattern = []) + public function controller($rule, $route = '', $option = [], $pattern = []) { - $group = new RuleGroup($this, $this->group, $rule, null, $option, $pattern); - foreach ($this->methodPrefix as $type => $val) { - $item = $this->$type(':action', $val . ':action'); - $group->addRuleItem($item, $type); + $this->$type($rule . '/:action', $route . '/' . $val . ':action', $option, $pattern); } - return $group->prefix($route . '/'); + return $this; } /** @@ -613,7 +748,7 @@ class Route * @param array $pattern 变量规则 * @return RuleItem */ - public function view($rule, $template = '', array $vars = [], array $option = [], array $pattern = []) + public function view($rule, $template = '', $vars = [], $option = [], $pattern = []) { return $this->rule($rule, $template, 'GET', $option, $pattern)->view($vars); } @@ -622,13 +757,13 @@ class Route * 注册重定向路由 * @access public * @param string|array $rule 路由规则 - * @param string $route 路由地址 + * @param string $template 路由模板地址 * @param array $status 状态码 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return RuleItem */ - public function redirect($rule, $route = '', $status = 301, array $option = [], array $pattern = []) + public function redirect($rule, $route = '', $status = 301, $option = [], $pattern = []) { return $this->rule($rule, $route, '*', $option, $pattern)->redirect()->status($status); } @@ -636,18 +771,20 @@ class Route /** * 注册别名路由 * @access public - * @param string $rule 路由别名 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @return AliasRule + * @param string|array $rule 路由别名 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @return $this */ - public function alias($rule, $route, array $option = []) + public function alias($rule = null, $route = '', $option = []) { - $aliasRule = new AliasRule($this, $this->group, $rule, $route, $option); + if (is_array($rule)) { + $this->alias = array_merge($this->alias, $rule); + } else { + $this->alias[$rule] = $option ? [$route, $option] : $route; + } - $this->alias[$rule] = $aliasRule; - - return $aliasRule; + return $this; } /** @@ -738,9 +875,9 @@ class Route * @param array $option 路由参数 * @return RuleItem */ - public function miss($route, $method = '*', array $option = []) + public function miss($route, $method = '*', $option = []) { - return $this->group->addMissRule($route, $method, $option); + return $this->rule('', $route, $method, $option)->isMiss(); } /** @@ -751,7 +888,7 @@ class Route */ public function auto($route) { - return $this->group->addAutoRule($route); + return $this->rule('', $route)->isAuto(); } /** @@ -773,7 +910,7 @@ class Route $result = $domain->check($this->request, $url, $depr, $completeMatch); if (false === $result && !empty($this->cross)) { - // 检测跨域路由 + // 检测跨越路由 $result = $this->cross->check($this->request, $url, $depr, $completeMatch); } @@ -783,15 +920,16 @@ class Route } elseif ($must) { // 强制路由不匹配则抛出异常 throw new RouteNotFoundException(); + } else { + // 默认路由解析 + return new UrlDispatch($url, ['depr' => $depr, 'auto_search' => $this->config->get('app.controller_auto_search')]); } - - // 默认路由解析 - return new UrlDispatch($url, ['depr' => $depr, 'auto_search' => $this->autoSearchController]); } /** * 检测域名的路由规则 * @access protected + * @param string $host 当前主机地址 * @return Domain */ protected function checkDomain() @@ -843,6 +981,52 @@ class Route return $item; } + /** + * 分析路由规则中的变量 + * @access public + * @param string $rule 路由规则 + * @return array + */ + public function parseVar($rule) + { + // 提取路由规则中的变量 + $var = []; + + foreach (explode('/', $rule) as $val) { + $optional = false; + + if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { + foreach ($matches[1] as $name) { + if (strpos($name, '?')) { + $name = substr($name, 0, -1); + $optional = true; + } else { + $optional = false; + } + $var[$name] = $optional ? 2 : 1; + } + } + + if (0 === strpos($val, '[:')) { + // 可选参数 + $optional = true; + $val = substr($val, 1, -1); + } + + if (0 === strpos($val, ':')) { + // URL变量 + $name = substr($val, 1); + if ('$' == substr($name, -1)) { + $name = substr($name, 0, -1); + } + + $var[$name] = $optional ? 2 : 1; + } + } + + return $var; + } + /** * 设置全局的路由分组参数 * @access public diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php index ef4a197f4..b97c83904 100644 --- a/thinkphp/library/think/Template.php +++ b/thinkphp/library/think/Template.php @@ -85,24 +85,35 @@ class Template */ public function __construct(array $config = []) { - $this->config['cache_path'] = Container::get('app')->getRuntimePath() . 'temp/'; - $this->config = array_merge($this->config, $config); - + $this->config['cache_path'] = Container::get('app')->getRuntimePath() . 'temp/'; + $this->config = array_merge($this->config, $config); $this->config['taglib_begin_origin'] = $this->config['taglib_begin']; $this->config['taglib_end_origin'] = $this->config['taglib_end']; - - $this->config['taglib_begin'] = preg_quote($this->config['taglib_begin'], '/'); - $this->config['taglib_end'] = preg_quote($this->config['taglib_end'], '/'); - $this->config['tpl_begin'] = preg_quote($this->config['tpl_begin'], '/'); - $this->config['tpl_end'] = preg_quote($this->config['tpl_end'], '/'); + $this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']); + $this->config['taglib_end'] = $this->stripPreg($this->config['taglib_end']); + $this->config['tpl_begin'] = $this->stripPreg($this->config['tpl_begin']); + $this->config['tpl_end'] = $this->stripPreg($this->config['tpl_end']); // 初始化模板编译存储器 - $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\template\\driver\\' . ucwords($type); - + $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\template\\driver\\' . ucwords($type); $this->storage = new $class(); } + /** + * 字符串替换 避免正则混淆 + * @access private + * @param string $str + * @return string + */ + private function stripPreg($str) + { + return str_replace( + ['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'], + ['\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'], + $str); + } + /** * 模板变量赋值 * @access public @@ -142,6 +153,8 @@ class Template $this->config = array_merge($this->config, $config); } elseif (isset($this->config[$config])) { return $this->config[$config]; + } else { + return; } } @@ -155,20 +168,20 @@ class Template { if ('' == $name) { return $this->data; - } + } else { + $data = $this->data; - $data = $this->data; - - foreach (explode('.', $name) as $key => $val) { - if (isset($data[$val])) { - $data = $data[$val]; - } else { - $data = null; - break; + foreach (explode('.', $name) as $key => $val) { + if (isset($data[$val])) { + $data = $data[$val]; + } else { + $data = null; + break; + } } - } - return $data; + return $data; + } } /** @@ -204,7 +217,7 @@ class Template $template = $this->parseTemplateFile($template); if ($template) { - $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_on'] . $this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.'); + $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.'); if (!$this->checkCache($cacheFile)) { // 缓存无效 重新模板编译 @@ -298,7 +311,18 @@ class Template */ private function checkCache($cacheFile) { - if (!$this->config['tpl_cache'] || !is_file($cacheFile) || !$handle = @fopen($cacheFile, "r")) { + // 未开启缓存功能 + if (!$this->config['tpl_cache']) { + return false; + } + + // 缓存文件不存在 + if (!is_file($cacheFile)) { + return false; + } + + // 读取缓存文件失败 + if (!$handle = @fopen($cacheFile, "r")) { return false; } @@ -393,6 +417,8 @@ class Template $this->storage->write($cacheFile, $content); $this->includeFile = []; + + return; } /** @@ -464,6 +490,8 @@ class Template // 还原被替换的Literal标签 $this->parseLiteral($content, true); + + return; } /** @@ -480,8 +508,10 @@ class Template // PHP语法检查 if ($this->config['tpl_deny_php'] && false !== strpos($content, 'parseTag($content, $hide ? '' : $tagLib); + + return; } /** @@ -791,9 +827,9 @@ class Template if (!empty($name) && isset($array[$name])) { return $array[$name]; + } else { + return $array; } - - return $array; } /** @@ -1232,9 +1268,9 @@ class Template $this->includeFile[$template] = filemtime($template); return $template; + } else { + throw new TemplateNotFoundException('template not exists:' . $template, $template); } - - throw new TemplateNotFoundException('template not exists:' . $template, $template); } /** diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php index a7281df46..e7cf75d3f 100644 --- a/thinkphp/library/think/Url.php +++ b/thinkphp/library/think/Url.php @@ -123,8 +123,10 @@ class Url if ($alias) { // 别名路由解析 - foreach ($alias as $key => $item) { - $val = $item->gerRoute(); + foreach ($alias as $key => $val) { + if (is_array($val)) { + $val = $val[0]; + } if (0 === strpos($url, $val)) { $url = $key . substr($url, strlen($val)); @@ -318,21 +320,20 @@ class Url foreach ($rule as $item) { list($url, $pattern, $domain, $suffix) = $item; if (empty($pattern)) { - return [rtrim($url, '?/-'), $domain, $suffix]; + return [rtrim($url, '$'), $domain, $suffix]; } $type = $this->app['config']->get('url_common_param'); foreach ($pattern as $key => $val) { if (isset($vars[$key])) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url); + $url = str_replace(['[:' . $key . ']', '[:' . $key . '$]', '<' . $key . '?>$', '<' . $key . '?>', ':' . $key . '$', ':' . $key . '', '<' . $key . '>$', '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url); unset($vars[$key]); - $url = str_replace(['/?', '-?'], ['/', '-'], $url); - $result = [rtrim($url, '?/-'), $domain, $suffix]; + + $result = [$url, $domain, $suffix]; } elseif (2 == $val) { - $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); - $url = str_replace(['/?', '-?'], ['/', '-'], $url); - $result = [rtrim($url, '?/-'), $domain, $suffix]; + $url = str_replace(['/[:' . $key . ']', '/[:' . $key . '$]', '[:' . $key . ']', '[:' . $key . '$]', '<' . $key . '?>$', '<' . $key . '?>'], '', $url); + $result = [$url, $domain, $suffix]; } else { break; } diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php index 90c5d8333..e078c88c1 100644 --- a/thinkphp/library/think/Validate.php +++ b/thinkphp/library/think/Validate.php @@ -187,7 +187,7 @@ class Validate */ public function __construct(array $rules = [], array $message = [], array $field = []) { - $this->rule = $rules + $this->rule; + $this->rule = array_merge($this->rule, $rules); $this->message = array_merge($this->message, $message); $this->field = array_merge($this->field, $field); } @@ -214,7 +214,7 @@ class Validate public function rule($name, $rule = '') { if (is_array($name)) { - $this->rule = $name + $this->rule; + $this->rule = array_merge($this->rule, $name); if (is_array($rule)) { $this->field = array_merge($this->field, $rule); } @@ -784,13 +784,13 @@ class Validate { if (function_exists('exif_imagetype')) { return exif_imagetype($image); - } - - try { - $info = getimagesize($image); - return $info ? $info[2] : false; - } catch (\Exception $e) { - return false; + } else { + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } } } @@ -844,9 +844,9 @@ class Validate return true; } elseif ($file instanceof File) { return $file->checkExt($rule); + } else { + return false; } - - return false; } /** @@ -867,9 +867,9 @@ class Validate return true; } elseif ($file instanceof File) { return $file->checkMime($rule); + } else { + return false; } - - return false; } /** @@ -890,9 +890,9 @@ class Validate return true; } elseif ($file instanceof File) { return $file->checkSize($rule); + } else { + return false; } - - return false; } /** @@ -928,9 +928,9 @@ class Validate list($w, $h) = $rule; return $w == $width && $h == $height; + } else { + return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]); } - - return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]); } /** @@ -1010,7 +1010,6 @@ class Validate if ($db->where($map)->field($pk)->find()) { return false; } - return true; } @@ -1062,9 +1061,9 @@ class Validate if ($this->getDataValue($data, $field) == $val) { return !empty($value) || '0' == $value; + } else { + return true; } - - return true; } /** @@ -1081,9 +1080,9 @@ class Validate if ($result) { return !empty($value) || '0' == $value; + } else { + return true; } - - return true; } /** @@ -1100,9 +1099,9 @@ class Validate if (!empty($val)) { return !empty($value) || '0' == $value; + } else { + return true; } - - return true; } /** @@ -1184,10 +1183,10 @@ class Validate // 长度区间 list($min, $max) = explode(',', $rule); return $length >= $min && $length <= $max; + } else { + // 指定长度 + return $length == $rule; } - - // 指定长度 - return $length == $rule; } /** @@ -1322,7 +1321,7 @@ class Validate $rule = '/^' . $rule . '$/'; } - return is_scalar($value) && 1 === preg_match($rule, (string) $value); + return 1 === preg_match($rule, (string) $value); } /** diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php index 3ff1a0128..d4c520334 100644 --- a/thinkphp/library/think/cache/driver/File.php +++ b/thinkphp/library/think/cache/driver/File.php @@ -43,7 +43,7 @@ class File extends Driver } if (empty($this->options['path'])) { - $this->options['path'] = Container::get('app')->getRuntimePath() . 'cache' . DIRECTORY_SEPARATOR; + $this->options['path'] = Container::get('app')->getRuntimePath() . 'cache/'; } elseif (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) { $this->options['path'] .= DIRECTORY_SEPARATOR; } @@ -242,10 +242,7 @@ class File extends Driver { $this->writeTimes++; - try { - return $this->unlink($this->getCacheKey($name)); - } catch (\Exception $e) { - } + return $this->unlink($this->getCacheKey($name)); } /** @@ -272,7 +269,7 @@ class File extends Driver foreach ($files as $path) { if (is_dir($path)) { - $matches = glob($path . DIRECTORY_SEPARATOR . '*.php'); + $matches = glob($path . '/*.php'); if (is_array($matches)) { array_map('unlink', $matches); } diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php index 2f019608c..ad4de7af6 100644 --- a/thinkphp/library/think/cache/driver/Redis.php +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -74,7 +74,7 @@ class Redis extends Driver */ public function has($name) { - return $this->handler->exists($this->getCacheKey($name)); + return $this->handler->get($this->getCacheKey($name)) ? true : false; } /** @@ -203,39 +203,4 @@ class Redis extends Driver return $this->handler->flushDB(); } - /** - * 如果不存在则写入缓存 - * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 - * @return mixed - */ - public function remember($name, $value, $expire = null) - { - if (is_null($expire)) { - $expire = $this->options['expire']; - } - - // 没有过期参数时,使用setnx - if (!$expire) { - $key = $this->getCacheKey($name); - $val = $this->serialize($value); - $res = $this->handler->setnx($key, $val); - if ($res) { - $this->writeTimes++; - return $value; - } else { - return $this->get($name); - } - } - - if ($this->has($name)) { - return $this->get($name); - } else { - $this->set($name, $value, $expire); - } - - return $value; - } } diff --git a/thinkphp/library/think/console/command/Clear.php b/thinkphp/library/think/console/command/Clear.php index 9896aea56..4ca0c4ffa 100644 --- a/thinkphp/library/think/console/command/Clear.php +++ b/thinkphp/library/think/console/command/Clear.php @@ -34,7 +34,7 @@ class Clear extends Command if ($files) { foreach ($files as $file) { if ('.' != $file && '..' != $file && is_dir($path . $file)) { - array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*')); + array_map('unlink', glob($path . $file . '/*.*')); } elseif ('.gitignore' != $file && is_file($path . $file)) { unlink($path . $file); } diff --git a/thinkphp/library/think/console/command/RunServer.php b/thinkphp/library/think/console/command/RunServer.php index 4dd610b6e..60edfd98b 100644 --- a/thinkphp/library/think/console/command/RunServer.php +++ b/thinkphp/library/think/console/command/RunServer.php @@ -42,7 +42,7 @@ class RunServer extends Command $host, $port, escapeshellarg($root), - escapeshellarg($root . DIRECTORY_SEPARATOR . 'router.php') + escapeshellarg($root . '/router.php') ); $output->writeln(sprintf('ThinkPHP Development server is started On ', $host, $port)); diff --git a/thinkphp/library/think/console/command/make/Controller.php b/thinkphp/library/think/console/command/make/Controller.php index e4cc5bb57..d702bd1af 100644 --- a/thinkphp/library/think/console/command/make/Controller.php +++ b/thinkphp/library/think/console/command/make/Controller.php @@ -24,24 +24,17 @@ class Controller extends Make { parent::configure(); $this->setName('make:controller') - ->addOption('api', null, Option::VALUE_NONE, 'Generate an api controller class.') ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty controller class.') ->setDescription('Create a new resource controller class'); } protected function getStub() { - $stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR; - - if ($this->input->getOption('api')) { - return $stubPath . 'controller.api.stub'; - } - if ($this->input->getOption('plain')) { - return $stubPath . 'controller.plain.stub'; + return __DIR__ . '/stubs/controller.plain.stub'; } - return $stubPath . 'controller.stub'; + return __DIR__ . '/stubs/controller.stub'; } protected function getClassName($name) diff --git a/thinkphp/library/think/console/command/make/Middleware.php b/thinkphp/library/think/console/command/make/Middleware.php deleted file mode 100644 index bfe821b03..000000000 --- a/thinkphp/library/think/console/command/make/Middleware.php +++ /dev/null @@ -1,36 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\console\command\make; - -use think\console\command\Make; - -class Middleware extends Make -{ - protected $type = "Middleware"; - - protected function configure() - { - parent::configure(); - $this->setName('make:middleware') - ->setDescription('Create a new middleware class'); - } - - protected function getStub() - { - return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'middleware.stub'; - } - - protected function getNamespace($appNamespace, $module) - { - return parent::getNamespace($appNamespace, 'http') . '\middleware'; - } -} diff --git a/thinkphp/library/think/console/command/make/Model.php b/thinkphp/library/think/console/command/make/Model.php index 03e6b3fcd..d4e9b5dd0 100644 --- a/thinkphp/library/think/console/command/make/Model.php +++ b/thinkphp/library/think/console/command/make/Model.php @@ -26,7 +26,7 @@ class Model extends Make protected function getStub() { - return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'model.stub'; + return __DIR__ . '/stubs/model.stub'; } protected function getNamespace($appNamespace, $module) diff --git a/thinkphp/library/think/console/command/make/stubs/controller.api.stub b/thinkphp/library/think/console/command/make/stubs/controller.api.stub deleted file mode 100644 index aed9edfbd..000000000 --- a/thinkphp/library/think/console/command/make/stubs/controller.api.stub +++ /dev/null @@ -1,64 +0,0 @@ -import(' . var_export($middleware, true) . ');' . PHP_EOL; - } - } } if (is_file($path . 'provider.php')) { - $provider = include $path . 'provider.php'; - if (is_array($provider)) { - $content .= PHP_EOL . '\think\Container::getInstance()->bind(' . var_export($provider, true) . ');' . PHP_EOL; - } + $content .= PHP_EOL . '\think\Container::getInstance()->bind(' . var_export(include $path . 'provider.php' ?: [], true) . ');' . PHP_EOL; } $content .= PHP_EOL . '\think\facade\Config::set(' . var_export($config->get(), true) . ');' . PHP_EOL; diff --git a/thinkphp/library/think/console/command/optimize/Route.php b/thinkphp/library/think/console/command/optimize/Route.php index d5f06d00f..0b1885833 100644 --- a/thinkphp/library/think/console/command/optimize/Route.php +++ b/thinkphp/library/think/console/command/optimize/Route.php @@ -28,16 +28,14 @@ class Route extends Command protected function execute(Input $input, Output $output) { - $filename = Container::get('app')->getRuntimePath() . 'route.php'; - unlink($filename); - file_put_contents($filename, $this->buildRouteCache()); + file_put_contents(Container::get('app')->getRuntimePath() . 'route.php', $this->buildRouteCache()); $output->writeln('Succeed!'); } protected function buildRouteCache() { Container::get('route')->setName([]); - Container::get('route')->lazy(false); + Container::get('config')->set('url_lazy_route', false); // 路由检测 $path = Container::get('app')->getRoutePath(); diff --git a/thinkphp/library/think/console/command/optimize/Schema.php b/thinkphp/library/think/console/command/optimize/Schema.php index 61620badd..179970137 100644 --- a/thinkphp/library/think/console/command/optimize/Schema.php +++ b/thinkphp/library/think/console/command/optimize/Schema.php @@ -99,7 +99,7 @@ class Schema extends Command $info = $class::getConnection()->getFields($table); $content .= var_export($info, true) . ';'; - file_put_contents(App::getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR . $dbName . '.' . $table . '.php', $content); + file_put_contents(App::getRuntimePath() . 'schema/' . $dbName . '.' . $table . '.php', $content); } } diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 239a02138..4f98ac952 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -135,19 +135,13 @@ abstract class Builder } elseif (is_array($val) && !empty($val)) { switch ($val[0]) { case 'exp': - if (isset($val[2]) && $query->getSecureKey() == $val[2]) { - $result[$item] = $val[1]; - } + $result[$item] = $val[1]; break; case 'inc': - if ($key == $val[1]) { - $result[$item] = $this->parseKey($query, $val[1]) . ' + ' . floatval($val[2]); - } + $result[$item] = $this->parseKey($query, $val[1]) . ' + ' . floatval($val[2]); break; case 'dec': - if ($key == $val[1]) { - $result[$item] = $this->parseKey($query, $val[1]) . ' - ' . floatval($val[2]); - } + $result[$item] = $this->parseKey($query, $val[1]) . ' - ' . floatval($val[2]); break; } } elseif (is_scalar($val)) { @@ -174,11 +168,12 @@ abstract class Builder // 过滤非标量数据 if (0 === strpos($data, ':') && $query->isBind(substr($data, 1))) { return $data; + } else { + $key = str_replace(['.', '->'], '_', $key); + $name = 'data__' . $key . $suffix; + $query->bind($name, $data, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); + return ':' . $name; } - $key = str_replace(['.', '->'], '_', $key); - $name = 'data__' . $key . $suffix; - $query->bind($name, $data, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); - return ':' . $name; } /** @@ -233,7 +228,6 @@ abstract class Builder { $item = []; $options = $query->getOptions(); - foreach ((array) $tables as $key => $table) { if (!is_numeric($key)) { $key = $this->connection->parseSqlTable($key); @@ -393,7 +387,7 @@ abstract class Builder $exp = $this->exp[$exp]; } - $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field); + $bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field); if (preg_match('/\W/', $bindName)) { // 处理带非单词字符的字段名 @@ -851,19 +845,7 @@ abstract class Builder */ protected function parseGroup(Query $query, $group) { - if (empty($group)) { - return ''; - } - - if (is_string($group)) { - $group = explode(',', $group); - } - - foreach ($group as $key) { - $val[] = $this->parseKey($query, $key); - } - - return ' GROUP BY ' . implode(',', $val); + return !empty($group) ? ' GROUP BY ' . $this->parseKey($query, $group) : ''; } /** diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index 142e80443..c7d3cd452 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -106,8 +106,6 @@ abstract class Connection 'query' => '\\think\\db\\Query', // 是否需要断线重连 'break_reconnect' => false, - // 断线标识字符串 - 'break_match_str' => [], ]; // PDO连接参数 @@ -119,21 +117,6 @@ abstract class Connection PDO::ATTR_EMULATE_PREPARES => false, ]; - // 服务器断线标识字符 - protected $breakMatchStr = [ - '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', - 'failed with errno', - ]; - // 绑定参数 protected $bind = []; @@ -210,9 +193,9 @@ abstract class Connection { if (!empty($this->builderClassName)) { return $this->builderClassName; + } else { + return $this->getConfig('builder') ?: '\\think\\db\\builder\\' . ucfirst($this->getConfig('type')); } - - return $this->getConfig('builder') ?: '\\think\\db\\builder\\' . ucfirst($this->getConfig('type')); } /** @@ -368,8 +351,7 @@ abstract class Connection if (!isset(self::$info[$schema])) { // 读取缓存 - $cacheFile = Container::get('app')->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR . $schema . '.php'; - + $cacheFile = Container::get('app')->getRuntimePath() . 'schema/' . $schema . '.php'; if (!$this->config['debug'] && is_file($cacheFile)) { $info = include $cacheFile; } else { @@ -383,7 +365,6 @@ abstract class Connection // 记录字段类型 $type[$key] = $val['type']; $bind[$key] = $this->getFieldBindType($val['type']); - if (!empty($val['primary'])) { $pk[] = $key; } @@ -491,55 +472,49 @@ abstract class Connection */ public function connect(array $config = [], $linkNum = 0, $autoConnection = false) { - if (isset($this->links[$linkNum])) { - return $this->links[$linkNum]; - } - - if (!$config) { - $config = $this->config; - } else { - $config = array_merge($this->config, $config); - } - - // 连接参数 - if (isset($config['params']) && is_array($config['params'])) { - $params = $config['params'] + $this->params; - } else { - $params = $this->params; - } - - // 记录当前字段属性大小写设置 - $this->attrCase = $params[PDO::ATTR_CASE]; - - if (!empty($config['break_match_str'])) { - $this->breakMatchStr = array_merge($this->breakMatchStr, (array) $config['break_match_str']); - } - - try { - if (empty($config['dsn'])) { - $config['dsn'] = $this->parseDsn($config); - } - - if ($config['debug']) { - $startTime = microtime(true); - } - - $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params); - - if ($config['debug']) { - // 记录数据库连接信息 - $this->log('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn']); - } - - return $this->links[$linkNum]; - } catch (\PDOException $e) { - if ($autoConnection) { - $this->log($e->getMessage(), 'error'); - return $this->connect($autoConnection, $linkNum); + if (!isset($this->links[$linkNum])) { + if (!$config) { + $config = $this->config; } else { - throw $e; + $config = array_merge($this->config, $config); + } + + // 连接参数 + if (isset($config['params']) && is_array($config['params'])) { + $params = $config['params'] + $this->params; + } else { + $params = $this->params; + } + + // 记录当前字段属性大小写设置 + $this->attrCase = $params[PDO::ATTR_CASE]; + + try { + if (empty($config['dsn'])) { + $config['dsn'] = $this->parseDsn($config); + } + + if ($config['debug']) { + $startTime = microtime(true); + } + + $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params); + + if ($config['debug']) { + // 记录数据库连接信息 + $this->log('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn']); + } + } catch (\PDOException $e) { + if ($autoConnection) { + $this->log($e->getMessage(), 'error'); + return $this->connect($autoConnection, $linkNum); + } else { + throw $e; + } } } + + return $this->links[$linkNum]; } /** @@ -560,9 +535,9 @@ abstract class Connection { if (!$this->linkID) { return false; + } else { + return $this->linkID; } - - return $this->linkID; } /** @@ -808,10 +783,11 @@ abstract class Connection $pk = $query->getPk($options); if (!empty($options['cache']) && true === $options['cache']['key'] && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($query, $options['where']['AND'][$pk]); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options); } - $data = $options['data']; + $data = $options['data']; + $result = false; if (empty($options['fetch_sql']) && !empty($options['cache'])) { // 判断查询缓存 @@ -820,57 +796,55 @@ abstract class Connection if (is_string($cache['key'])) { $key = $cache['key']; } elseif (!isset($key)) { - $key = $this->getCacheKey($query, $data); + $key = $this->getCacheKey($data, $options, $query->getBind(false)); } $result = Container::get('cache')->get($key); - - if (false !== $result) { - return $result; - } } - if (is_string($pk) && !is_array($data)) { - if (isset($key) && strpos($key, '|')) { - list($a, $val) = explode('|', $key); - $item[$pk] = $val; + if (false === $result) { + if (is_string($pk)) { + if (!is_array($data)) { + if (isset($key) && strpos($key, '|')) { + list($a, $val) = explode('|', $key); + $item[$pk] = $val; + } else { + $item[$pk] = $data; + } + $data = $item; + } + } + $query->setOption('data', $data); + $query->setOption('limit', 1); + + // 生成查询SQL + $sql = $this->builder->select($query); + + $bind = $query->getBind(); + + if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 + return $this->getRealSql($sql, $bind); + } + + // 事件回调 + if ($result = $query->trigger('before_find')) { } else { - $item[$pk] = $data; - } - $data = $item; - } + // 执行查询 + $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - $query->setOption('data', $data); - $query->setOption('limit', 1); + if ($resultSet instanceof \PDOStatement) { + // 返回PDOStatement对象 + return $resultSet; + } - // 生成查询SQL - $sql = $this->builder->select($query); - - $bind = $query->getBind(); - - if (!empty($options['fetch_sql'])) { - // 获取实际执行的SQL语句 - return $this->getRealSql($sql, $bind); - } - - // 事件回调 - $result = $query->trigger('before_find'); - - if (!$result) { - // 执行查询 - $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - - if ($resultSet instanceof \PDOStatement) { - // 返回PDOStatement对象 - return $resultSet; + $result = isset($resultSet[0]) ? $resultSet[0] : null; } - $result = isset($resultSet[0]) ? $resultSet[0] : null; - } - - if (isset($cache) && $result) { - // 缓存数据 - $this->cacheData($key, $result, $cache); + if (isset($cache) && $result) { + // 缓存数据 + $this->cacheData($key, $result, $cache); + } } return $result; @@ -911,41 +885,42 @@ abstract class Connection public function select(Query $query) { // 分析查询表达式 - $options = $query->getOptions(); + $options = $query->getOptions(); + $resultSet = false; if (empty($options['fetch_sql']) && !empty($options['cache'])) { - $resultSet = $this->getCacheData($query, $options['cache'], null, $key); + // 判断查询缓存 + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($query->getBind(false))); + $resultSet = Container::get('cache')->get($key); + } - if (false !== $resultSet) { - return $resultSet; + if (false === $resultSet) { + // 生成查询SQL + $sql = $this->builder->select($query); + + $bind = $query->getBind(); + + if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 + return $this->getRealSql($sql, $bind); } - } - // 生成查询SQL - $sql = $this->builder->select($query); + if ($resultSet = $query->trigger('before_select')) { + } else { + // 执行查询操作 + $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - $bind = $query->getBind(); - - if (!empty($options['fetch_sql'])) { - // 获取实际执行的SQL语句 - return $this->getRealSql($sql, $bind); - } - - $resultSet = $query->trigger('before_select'); - - if (!$resultSet) { - // 执行查询操作 - $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); - - if ($resultSet instanceof \PDOStatement) { - // 返回PDOStatement对象 - return $resultSet; + if ($resultSet instanceof \PDOStatement) { + // 返回PDOStatement对象 + return $resultSet; + } } - } - if (!empty($options['cache']) && false !== $resultSet) { - // 缓存数据集 - $this->cacheData($key, $resultSet, $options['cache']); + if (isset($cache) && false !== $resultSet) { + // 缓存数据集 + $this->cacheData($key, $resultSet, $cache); + } } return $resultSet; @@ -1033,7 +1008,6 @@ abstract class Connection foreach ($array as $item) { $sql = $this->builder->insertAll($query, $item, $replace); $bind = $query->getBind(); - if (!empty($options['fetch_sql'])) { $fetchSql[] = $this->getRealSql($sql, $bind); } else { @@ -1058,10 +1032,12 @@ abstract class Connection $bind = $query->getBind(); if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 return $this->getRealSql($sql, $bind); + } else { + // 执行操作 + return $this->execute($sql, $bind); } - - return $this->execute($sql, $bind); } /** @@ -1078,6 +1054,7 @@ abstract class Connection // 分析查询表达式 $options = $query->getOptions(); + // 生成SQL语句 $table = $this->parseSqlTable($table); $sql = $this->builder->selectInsert($query, $fields, $table); @@ -1085,10 +1062,12 @@ abstract class Connection $bind = $query->getBind(); if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 return $this->getRealSql($sql, $bind); + } else { + // 执行操作 + return $this->execute($sql, $bind); } - - return $this->execute($sql, $bind); } /** @@ -1115,7 +1094,7 @@ abstract class Connection if (is_string($pk) && isset($data[$pk])) { $where[$pk] = [$pk, '=', $data[$pk]]; if (!isset($key)) { - $key = $this->getCacheKey($query, $data[$pk]); + $key = $this->getCacheKey($data[$pk], $options); } unset($data[$pk]); } elseif (is_array($pk)) { @@ -1139,7 +1118,7 @@ abstract class Connection $query->setOption('where', ['AND' => $where]); } } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($query, $options['where']['AND'][$pk]); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options); } // 更新数据 @@ -1152,34 +1131,34 @@ abstract class Connection if (!empty($options['fetch_sql'])) { // 获取实际执行的SQL语句 return $this->getRealSql($sql, $bind); - } + } else { + // 检测缓存 + $cache = Container::get('cache'); - // 检测缓存 - $cache = Container::get('cache'); - - 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 (is_string($pk) && isset($where[$pk])) { - $data[$pk] = $where[$pk]; - } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { - list($a, $val) = explode('|', $key); - $data[$pk] = $val; + if (isset($key) && $cache->get($key)) { + // 删除缓存 + $cache->rm($key); + } elseif (!empty($options['cache']['tag'])) { + $cache->clear($options['cache']['tag']); } - $query->setOption('data', $data); - $query->trigger('after_update'); - } + // 执行操作 + $result = '' == $sql ? 0 : $this->execute($sql, $bind); - return $result; + if ($result) { + if (is_string($pk) && isset($where[$pk])) { + $data[$pk] = $where[$pk]; + } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { + list($a, $val) = explode('|', $key); + $data[$pk] = $val; + } + + $query->setOption('data', $data); + $query->trigger('after_update'); + } + + return $result; + } } /** @@ -1200,9 +1179,9 @@ abstract class Connection if (isset($options['cache']) && is_string($options['cache']['key'])) { $key = $options['cache']['key']; } elseif (!is_null($data) && true !== $data && !is_array($data)) { - $key = $this->getCacheKey($query, $data); + $key = $this->getCacheKey($data, $options); } elseif (is_string($pk) && isset($options['where']['AND'][$pk])) { - $key = $this->getCacheKey($query, $options['where']['AND'][$pk]); + $key = $this->getCacheKey($options['where']['AND'][$pk], $options); } if (true !== $data && empty($options['where'])) { @@ -1260,44 +1239,50 @@ abstract class Connection { $options = $query->getOptions(); + $result = false; if (empty($options['fetch_sql']) && !empty($options['cache'])) { + // 判断查询缓存 + $cache = $options['cache']; - $result = $this->getCacheData($query, $options['cache'], $field, $key); + $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($options) . serialize($query->getBind(false))); + $result = Container::get('cache')->get($key); + } - if (false !== $result) { - return $result; + if (false === $result) { + if (isset($options['field'])) { + $query->removeOption('field'); } - } - if (isset($options['field'])) { - $query->removeOption('field'); - } + if (is_string($field)) { + $field = array_map('trim', explode(',', $field)); + } - if (is_string($field)) { - $field = array_map('trim', explode(',', $field)); - } + $query->setOption('field', $field); + $query->setOption('limit', 1); + // 生成查询SQL + $sql = $this->builder->select($query); - $query->setOption('field', $field); - $query->setOption('limit', 1); + $bind = $query->getBind(); - // 生成查询SQL - $sql = $this->builder->select($query); + if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 + return $this->getRealSql($sql, $bind); + } - $bind = $query->getBind(); + // 执行查询操作 + $pdo = $this->query($sql, $bind, $options['master'], true); - if (!empty($options['fetch_sql'])) { - // 获取实际执行的SQL语句 - return $this->getRealSql($sql, $bind); - } + if (is_string($pdo)) { + // 返回SQL语句 + return $pdo; + } - // 执行查询操作 - $pdo = $this->query($sql, $bind, $options['master'], true); + $result = $pdo->fetchColumn(); - $result = $pdo->fetchColumn(); - - if (isset($cache) && false !== $result) { - // 缓存数据 - $this->cacheData($key, $result, $cache); + if (isset($cache) && false !== $result) { + // 缓存数据 + $this->cacheData($key, $result, $cache); + } } return false !== $result ? $result : $default; @@ -1330,83 +1315,82 @@ abstract class Connection { $options = $query->getOptions(); + $result = false; + if (empty($options['fetch_sql']) && !empty($options['cache'])) { // 判断查询缓存 $cache = $options['cache']; - $guid = is_string($cache['key']) ? $cache['key'] : $this->getCacheKey($query, $field); - + $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($options) . serialize($query->getBind(false))); $result = Container::get('cache')->get($guid); + } - if (false !== $result) { - return $result; + if (false === $result) { + if (isset($options['field'])) { + $query->removeOption('field'); } - } - if (isset($options['field'])) { - $query->removeOption('field'); - } + if (is_null($field)) { + $field = '*'; + } elseif ($key && '*' != $field) { + $field = $key . ',' . $field; + } - if (is_null($field)) { - $field = '*'; - } elseif ($key && '*' != $field) { - $field = $key . ',' . $field; - } + if (is_string($field)) { + $field = array_map('trim', explode(',', $field)); + } - if (is_string($field)) { - $field = array_map('trim', explode(',', $field)); - } + $query->setOption('field', $field); - $query->setOption('field', $field); + // 生成查询SQL + $sql = $this->builder->select($query); - // 生成查询SQL - $sql = $this->builder->select($query); + $bind = $query->getBind(); - $bind = $query->getBind(); + if (!empty($options['fetch_sql'])) { + // 获取实际执行的SQL语句 + return $this->getRealSql($sql, $bind); + } - if (!empty($options['fetch_sql'])) { - // 获取实际执行的SQL语句 - return $this->getRealSql($sql, $bind); - } + // 执行查询操作 + $pdo = $this->query($sql, $bind, $options['master'], true); - // 执行查询操作 - $pdo = $this->query($sql, $bind, $options['master'], true); - - if (1 == $pdo->columnCount()) { - $result = $pdo->fetchAll(PDO::FETCH_COLUMN); - } else { - $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC); - - if ('*' == $field && $key) { - $result = array_column($resultSet, null, $key); - } elseif ($resultSet) { - $fields = array_keys($resultSet[0]); - $count = count($fields); - $key1 = array_shift($fields); - $key2 = $fields ? array_shift($fields) : ''; - $key = $key ?: $key1; - - if (strpos($key, '.')) { - list($alias, $key) = explode('.', $key); - } - - if (2 == $count) { - $column = $key2; - } elseif (1 == $count) { - $column = $key1; - } else { - $column = null; - } - - $result = array_column($resultSet, $column, $key); + if (1 == $pdo->columnCount()) { + $result = $pdo->fetchAll(PDO::FETCH_COLUMN); } else { - $result = []; - } - } + $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC); - if (isset($cache) && isset($guid)) { - // 缓存数据 - $this->cacheData($guid, $result, $cache); + if ('*' == $field && $key) { + $result = array_column($resultSet, null, $key); + } elseif ($resultSet) { + $fields = array_keys($resultSet[0]); + $count = count($fields); + $key1 = array_shift($fields); + $key2 = $fields ? array_shift($fields) : ''; + $key = $key ?: $key1; + + if (strpos($key, '.')) { + list($alias, $key) = explode('.', $key); + } + + if (2 == $count) { + $column = $key2; + } elseif (1 == $count) { + $column = $key1; + } else { + $column = null; + } + + $result = array_column($resultSet, $column, $key); + } else { + $result = []; + } + } + + if (isset($cache) && isset($guid)) { + // 缓存数据 + $this->cacheData($guid, $result, $cache); + } } return $result; @@ -1800,9 +1784,22 @@ abstract class Connection 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 ($this->breakMatchStr as $msg) { + foreach ($info as $msg) { if (false !== stripos($error, $msg)) { return true; } @@ -2049,30 +2046,15 @@ abstract class Connection } } - /** - * 获取缓存数据 - * @access protected - * @param Query $query 查询对象 - * @param mixed $cache 缓存设置 - * @param array $options 缓存 - * @return mixed - */ - protected function getCacheData(Query $query, $cache, $data, &$key = null) - { - // 判断查询缓存 - $key = is_string($cache['key']) ? $cache['key'] : $this->getCacheKey($query, $data); - - return Container::get('cache')->get($key); - } - /** * 生成缓存标识 * @access protected - * @param Query $query 查询对象 * @param mixed $value 缓存数据 + * @param array $options 缓存参数 + * @param array $bind 绑定参数 * @return string */ - protected function getCacheKey(Query $query, $value) + protected function getCacheKey($value, $options, $bind = []) { if (is_scalar($value)) { $data = $value; @@ -2080,16 +2062,14 @@ abstract class Connection $data = $value[2]; } - $prefix = 'think:' . $this->getConfig('database') . '.'; - if (isset($data)) { - return $prefix . $query->getTable() . '|' . $data; - } - - try { - return md5($prefix . serialize($query->getOptions()) . serialize($query->getBind(false))); - } catch (\Exception $e) { - return; + return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } else { + try { + return md5(serialize($options) . serialize($bind)); + } catch (\Exception $e) { + return; + } } } diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 1d96724fc..99093acd2 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -58,12 +58,6 @@ class Query */ protected $pk; - /** - * 查询安全Key - * @var string - */ - protected $secureKey; - /** * 当前数据表前缀 * @var string @@ -127,8 +121,7 @@ class Query $this->connection = $connection; } - $this->prefix = $this->connection->getConfig('prefix'); - $this->secureKey = Container::get('request')->secureKey(); + $this->prefix = $this->connection->getConfig('prefix'); } /** @@ -271,16 +264,6 @@ class Query return $this->name ?: $this->model->getName(); } - /** - * 获取查询安全Key - * @access public - * @return string - */ - public function getSecureKey() - { - return $this->secureKey; - } - /** * 得到当前或者指定名称的数据表 * @access public @@ -309,8 +292,7 @@ class Query public function connect($config = [], $name = false) { $this->connection = Connection::instance($config, $name); - - $query = $this->connection->getConfig('query'); + $query = $this->connection->getConfig('query'); if (__CLASS__ != trim($query, '\\')) { return new $query($this->connection); @@ -373,16 +355,6 @@ class Query return $this->connection->getLastInsID($sequence); } - /** - * 获取返回或者影响的记录数 - * @access public - * @return integer - */ - public function getNumRows() - { - return $this->connection->getNumRows(); - } - /** * 获取最近一次查询的sql语句 * @access public @@ -452,7 +424,7 @@ class Query * 获取数据库的配置参数 * @access public * @param string $name 参数名称 - * @return mixed + * @return boolean */ public function getConfig($name = '') { @@ -535,17 +507,18 @@ class Query } } return $this->getTable() . '_' . $seq; - } - // 当设置的分表字段不在查询条件或者数据中 - // 进行联合查询,必须设定 partition['num'] - $tableName = []; - for ($i = 0; $i < $rule['num']; $i++) { - $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1); - } + } else { + // 当设置的分表字段不在查询条件或者数据中 + // 进行联合查询,必须设定 partition['num'] + $tableName = []; + for ($i = 0; $i < $rule['num']; $i++) { + $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1); + } - $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; + $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; - return $tableName; + return $tableName; + } } /** @@ -871,7 +844,6 @@ class Query { if (is_array($join)) { $table = $join; - $alias = array_shift($join); } else { $join = trim($join); @@ -1058,7 +1030,7 @@ class Query */ public function exp($field, $value) { - $this->data($field, ['exp', $value, $this->secureKey]); + $this->data($field, ['exp', $value]); return $this; } @@ -1075,9 +1047,9 @@ class Query { $this->options['view'] = true; - if (is_array($join) && key($join) === 0) { + if (is_array($join) && key($join) !== 0) { foreach ($join as $key => $val) { - $this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER'); + $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); } } else { $fields = []; @@ -1190,7 +1162,7 @@ class Query */ public function whereNull($field, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'null', null, [], true); + return $this->parseWhereExp($logic, $field, 'null', null); } /** @@ -1202,7 +1174,7 @@ class Query */ public function whereNotNull($field, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'notnull', null, [], true); + return $this->parseWhereExp($logic, $field, 'notnull', null); } /** @@ -1241,7 +1213,7 @@ class Query */ public function whereIn($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'in', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'in', $condition); } /** @@ -1254,7 +1226,7 @@ class Query */ public function whereNotIn($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'not in', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'not in', $condition); } /** @@ -1267,7 +1239,7 @@ class Query */ public function whereLike($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'like', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'like', $condition); } /** @@ -1280,7 +1252,7 @@ class Query */ public function whereNotLike($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'not like', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'not like', $condition); } /** @@ -1293,7 +1265,7 @@ class Query */ public function whereBetween($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'between', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'between', $condition); } /** @@ -1306,7 +1278,7 @@ class Query */ public function whereNotBetween($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'not between', $condition, [], true); + return $this->parseWhereExp($logic, $field, 'not between', $condition); } /** @@ -1349,27 +1321,25 @@ class Query * @access public * @param mixed $field 查询字段 * @param mixed $condition 查询条件 - * @param array $bind 参数绑定 * @param string $logic 查询逻辑 and or xor * @return $this */ - public function whereExp($field, $condition, $bind = [], $logic = 'AND') + public function whereExp($field, $condition, $logic = 'AND') { - return $this->parseWhereExp($logic, $field, 'exp', $condition, $bind, true); + return $this->parseWhereExp($logic, $field, 'exp', $condition); } /** * 分析查询表达式 - * @access protected + * @access public * @param string $logic 查询逻辑 and or xor * @param mixed $field 查询字段 * @param mixed $op 查询表达式 * @param mixed $condition 查询条件 * @param array $param 查询参数 - * @param bool $strict 严格模式 * @return $this */ - protected function parseWhereExp($logic, $field, $op, $condition, array $param = [], $strict = false) + protected function parseWhereExp($logic, $field, $op, $condition, $param = []) { if ($field instanceof $this) { $this->options['where'] = $field->getOptions('where'); @@ -1382,22 +1352,56 @@ class Query $field = $this->options['via'] . '.' . $field; } - if ($strict) { - // 使用严格模式查询 - $where = [$field, $op, $condition]; - if ('exp' == strtolower($op) && !empty($param)) { - // 参数绑定 - $this->bind($param); - } - } elseif (is_array($field)) { - // 解析数组批量查询 - return $this->parseArrayWhereItems($field, $logic); - } elseif ($field instanceof \Closure) { - $where = $field; + if ($field instanceof \Closure) { + $where = is_string($op) ? [$op, $field] : $field; $field = ''; - } elseif (is_string($field)) { - // 解析条件单元 - $where = $this->parseWhereItem($logic, $field, $op, $condition, $param); + } elseif (is_string($field) && preg_match('/[,=\<\'\"\(\s]/', $field)) { + $where = ['', 'exp', $field]; + if (is_array($op)) { + // 参数绑定 + $this->bind($op); + } + } elseif (is_null($op) && is_null($condition)) { + if (is_array($field)) { + if (key($field) !== 0) { + $where = []; + foreach ($field as $key => $val) { + if (is_null($val)) { + $where[$key] = [$key, 'null', '']; + } else { + $where[$key] = !is_scalar($val) ? $val : [$key, '=', $val]; + } + } + } else { + // 数组批量查询 + $where = $field; + } + + if (!empty($where)) { + $this->options['where'][$logic] = isset($this->options['where'][$logic]) ? array_merge($this->options['where'][$logic], $where) : $where; + } + + return $this; + } elseif ($field && is_string($field)) { + // 字符串查询 + $where = [$field, 'null', '']; + } + } elseif (is_array($op)) { + array_unshift($param, $field); + $where = $param; + } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { + // null查询 + $where = [$field, $op, '']; + } elseif (is_null($condition)) { + // 字段相等查询 + $where = [$field, '=', $op]; + } else { + $where = [$field, $op, $condition, isset($param[2]) ? $param[2] : null]; + + if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) { + // 参数绑定 + $this->bind($param[2]); + } } if (!empty($where)) { @@ -1411,80 +1415,6 @@ class Query return $this; } - /** - * 分析查询表达式 - * @access protected - * @param string $logic 查询逻辑 and or xor - * @param mixed $field 查询字段 - * @param mixed $op 查询表达式 - * @param mixed $condition 查询条件 - * @param array $param 查询参数 - * @return mixed - */ - protected function parseWhereItem($logic, $field, $op, $condition, $param = []) - { - if (preg_match('/[,=\<\'\"\(\s]/', $field)) { - $where = ['', 'exp', $field]; - if (is_array($op)) { - // 参数绑定 - $this->bind($op); - } - } elseif (is_array($op)) { - // 同一字段多条件查询 - array_unshift($param, $field); - $where = $param; - } elseif ($field && is_null($condition)) { - if (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { - // null查询 - $where = [$field, $op, '']; - } else { - // 字段相等查询 - $where = is_null($op) ? [$field, 'null', ''] : [$field, '=', $op]; - } - } elseif (strtolower($op) == 'exp') { - $bind = isset($param[2]) && is_array($param[2]) ? $param[2] : null; - $where = [$field, 'exp', $condition, $bind]; - if ($bind) { - // 参数绑定 - $this->bind($bind); - } - } else { - $where = $field ? [$field, $op, $condition] : null; - } - - return $where; - } - - /** - * 数组批量查询 - * @access protected - * @param array $field 批量查询 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - protected function parseArrayWhereItems($field, $logic) - { - if (key($field) !== 0) { - $where = []; - foreach ($field as $key => $val) { - if (is_null($val)) { - $where[$key] = [$key, 'null', '']; - } else { - $where[$key] = !is_scalar($val) ? $val : [$key, '=', $val]; - } - } - } else { - // 数组批量查询 - $where = $field; - } - - if (!empty($where)) { - $this->options['where'][$logic] = isset($this->options['where'][$logic]) ? array_merge($this->options['where'][$logic], $where) : $where; - } - - return $this; - } - /** * 去除某个查询条件 * @access public @@ -1692,7 +1622,6 @@ class Query } } } - $this->options['table'] = $table; return $this; @@ -1719,35 +1648,33 @@ class Query */ public function order($field, $order = null) { - if (empty($field)) { - return $this; - } + if (!empty($field)) { + if (is_string($field)) { + if (!empty($this->options['via'])) { + $field = $this->options['via'] . '.' . $field; + } - if (is_string($field)) { - if (!empty($this->options['via'])) { - $field = $this->options['via'] . '.' . $field; - } - - $field = empty($order) ? $field : [$field => $order]; - } elseif (!empty($this->options['via'])) { - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $field[$key] = $this->options['via'] . '.' . $val; - } else { - $field[$this->options['via'] . '.' . $key] = $val; - unset($field[$key]); + $field = empty($order) ? $field : [$field => $order]; + } elseif (!empty($this->options['via'])) { + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $field[$key] = $this->options['via'] . '.' . $val; + } else { + $field[$this->options['via'] . '.' . $key] = $val; + unset($field[$key]); + } } } - } - if (!isset($this->options['order'])) { - $this->options['order'] = []; - } + if (!isset($this->options['order'])) { + $this->options['order'] = []; + } - if (is_array($field)) { - $this->options['order'] = array_merge($this->options['order'], $field); - } else { - $this->options['order'][] = $field; + if (is_array($field)) { + $this->options['order'] = array_merge($this->options['order'], $field); + } else { + $this->options['order'][] = $field; + } } return $this; @@ -1806,7 +1733,7 @@ class Query /** * 指定group查询 * @access public - * @param string|array $group GROUP + * @param string $group GROUP * @return $this */ public function group($group) @@ -2059,10 +1986,9 @@ class Query * @param string $field 日期字段名 * @param string|array $op 比较运算符或者表达式 * @param string|array $range 比较范围 - * @param string $logic AND OR * @return $this */ - public function whereTime($field, $op, $range = null, $logic = 'AND') + public function whereTime($field, $op, $range = null) { if (is_null($range)) { if (is_array($op)) { @@ -2082,7 +2008,9 @@ class Query $op = is_array($range) ? 'between' : '>='; } - return $this->parseWhereExp($logic, $field, strtolower($op) . ' time', $range, [], true); + $this->where($field, strtolower($op) . ' time', $range); + + return $this; } /** @@ -2091,17 +2019,18 @@ class Query * @param string $field 日期字段名 * @param string $startTime 开始时间 * @param string $endTime 结束时间 - * @param string $logic AND OR * @return $this */ - public function whereBetweenTime($field, $startTime, $endTime = null, $logic = 'AND') + public function whereBetweenTime($field, $startTime, $endTime = null) { if (is_null($endTime)) { $time = is_string($startTime) ? strtotime($startTime) : $startTime; $endTime = strtotime('+1 day', $time); } - return $this->parseWhereExp($logic, $field, 'between time', [$startTime, $endTime], [], true); + $this->where($field, 'between time', [$startTime, $endTime]); + + return $this; } /** @@ -2115,7 +2044,7 @@ class Query if (!empty($this->pk)) { $pk = $this->pk; } else { - $pk = $this->connection->getPk(is_array($options) && isset($options['table']) ? $options['table'] : $this->getTable()); + $pk = $this->connection->getPk(is_array($options) ? $options['table'] : $this->getTable()); } return $pk; @@ -2151,19 +2080,6 @@ class Query return isset($this->bind[$key]); } - /** - * 查询参数赋值 - * @access public - * @param string $name 参数名 - * @param mixed $value 值 - * @return $this - */ - public function option($name, $value) - { - $this->options[$name] = $value; - return $this; - } - /** * 查询参数赋值 * @access protected @@ -2186,8 +2102,9 @@ class Query { if ('' === $name) { return $this->options; + } else { + return isset($this->options[$name]) ? $this->options[$name] : null; } - return isset($this->options[$name]) ? $this->options[$name] : null; } /** @@ -2762,9 +2679,10 @@ class Query if (!empty($this->model)) { $class = get_class($this->model); throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options); + } else { + $table = is_array($options['table']) ? key($options['table']) : $options['table']; + throw new DataNotFoundException('table data not Found:' . $table, $table, $options); } - $table = is_array($options['table']) ? key($options['table']) : $options['table']; - throw new DataNotFoundException('table data not Found:' . $table, $table, $options); } /** diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index d13ac0168..cea8d4ae2 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -116,9 +116,9 @@ class Mysql extends Builder if (strpos($key, '->') && false === strpos($key, '(')) { // JSON字段支持 - list($field, $name) = explode('->', $key, 2); + list($field, $name) = explode('->', $key); - $key = 'json_extract(' . $this->parseKey($query, $field) . ', \'$.' . str_replace('->', '.', $name) . '\')'; + $key = 'json_extract(' . $this->parseKey($query, $field) . ', \'$.' . $name . '\')'; } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { list($table, $key) = explode('.', $key, 2); diff --git a/thinkphp/library/think/debug/Html.php b/thinkphp/library/think/debug/Html.php index 85f354af0..ed4c62684 100644 --- a/thinkphp/library/think/debug/Html.php +++ b/thinkphp/library/think/debug/Html.php @@ -49,7 +49,7 @@ class Html return false; } // 获取基本信息 - $runtime = number_format(microtime(true) - Container::get('app')->getBeginTime(), 10, '.', ''); + $runtime = number_format(microtime(true) - Container::get('app')->getBeginTime(), 10); $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; $mem = number_format((memory_get_usage() - Container::get('app')->getBeginMem()) / 1024, 2); diff --git a/thinkphp/library/think/Middleware.php b/thinkphp/library/think/http/middleware/Dispatcher.php similarity index 52% rename from thinkphp/library/think/Middleware.php rename to thinkphp/library/think/http/middleware/Dispatcher.php index b59b72375..4218915db 100644 --- a/thinkphp/library/think/Middleware.php +++ b/thinkphp/library/think/http/middleware/Dispatcher.php @@ -9,17 +9,18 @@ // | Author: Slince // +---------------------------------------------------------------------- -namespace think; +namespace think\http\middleware; -class Middleware +use think\Request; +use think\Response; + +class Dispatcher implements DispatcherInterface { - protected $queue = []; + protected $queue; - public function import(array $middlewares = []) + public function __construct($middlewares = []) { - foreach ($middlewares as $middleware) { - $this->add($middleware); - } + $this->queue = (array) $middlewares; } /** @@ -27,26 +28,16 @@ class Middleware */ public function add($middleware) { - if (is_null($middleware)) { - return; - } - - $middleware = $this->buildMiddleware($middleware); - + $this->assertValid($middleware); $this->queue[] = $middleware; } /** * {@inheritdoc} */ - public function unshift($middleware) + public function insert($middleware) { - if (is_null($middleware)) { - return; - } - - $middleware = $this->buildMiddleware($middleware); - + $this->assertValid($middleware); array_unshift($this->queue, $middleware); } @@ -63,30 +54,8 @@ class Middleware */ public function dispatch(Request $request) { - return call_user_func($this->resolve(), $request); - } - - protected function buildMiddleware($middleware) - { - if (is_array($middleware)) { - list($middleware, $param) = $middleware; - } - - if ($middleware instanceof \Closure) { - return [$middleware, null]; - } - - if (!is_string($middleware)) { - throw new \InvalidArgumentException('The middleware is invalid'); - } - - $class = false === strpos($middleware, '\\') ? Container::get('app')->getNamespace() . '\\http\\middleware\\' . $middleware : $middleware; - - if (strpos($class, ':')) { - list($class, $param) = explode(':', $class, 2); - } - - return [[Container::get($class), 'handle'], isset($param) ? $param : null]; + $requestHandler = $this->resolve(); + return call_user_func($requestHandler, $request); } protected function resolve() @@ -95,9 +64,7 @@ class Middleware $middleware = array_shift($this->queue); if (null !== $middleware) { - list($call, $param) = $middleware; - - $response = call_user_func_array($call, [$request, $this->resolve(), $param]); + $response = call_user_func($middleware, $request, $this->resolve()); if (!$response instanceof Response) { throw new \LogicException('The middleware must return Response instance'); @@ -105,9 +72,15 @@ class Middleware return $response; } else { - throw new \InvalidArgumentException('The queue was exhausted, with no response returned'); + throw new MissingResponseException('The queue was exhausted, with no response returned'); } }; } + protected function assertValid($middleware) + { + if (!is_callable($middleware)) { + throw new \InvalidArgumentException('The middleware is invalid'); + } + } } diff --git a/thinkphp/library/think/http/middleware/DispatcherInterface.php b/thinkphp/library/think/http/middleware/DispatcherInterface.php new file mode 100644 index 000000000..1693f6093 --- /dev/null +++ b/thinkphp/library/think/http/middleware/DispatcherInterface.php @@ -0,0 +1,45 @@ + +// +---------------------------------------------------------------------- + +namespace think\http\middleware; + +use think\Request; +use think\Response; + +interface DispatcherInterface +{ + /** + * 在队尾添加 middleware + * @param callable $middleware + * @return DispatcherInterface + */ + public function add($middleware); + + /** + * 在队前插入 middleware + * @param callable $middleware + * @return DispatcherInterface + */ + public function insert($middleware); + + /** + * 获取所有的middleware + * @return array + */ + public function all(); + + /** + * 处理 request 并返回 response + * @param Request $request + * @return Response + */ + public function dispatch(Request $request); +} diff --git a/thinkphp/library/think/facade/Middleware.php b/thinkphp/library/think/http/middleware/MissingResponseException.php similarity index 50% rename from thinkphp/library/think/facade/Middleware.php rename to thinkphp/library/think/http/middleware/MissingResponseException.php index 468279642..7cdcb33df 100644 --- a/thinkphp/library/think/facade/Middleware.php +++ b/thinkphp/library/think/http/middleware/MissingResponseException.php @@ -6,22 +6,10 @@ // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- -// | Author: liu21st +// | Author: Slince // +---------------------------------------------------------------------- -namespace think\facade; +namespace think\http\middleware; -use think\Facade; - -/** - * @see \think\Middleware - * @mixin \think\Middleware - * @method void import(array $middlewares = []) static 批量设置中间件 - * @method void add(mixed $middleware) static 添加中间件到队列 - * @method void unshift(mixed $middleware) static 添加中间件到队列开头 - * @method array all() static 获取中间件队列 - * @method \think\Response dispatch(\think\Request $request) static 执行中间件调度 - */ -class Middleware extends Facade -{ -} +class MissingResponseException extends \InvalidArgumentException +{} diff --git a/thinkphp/library/think/http/tests/middleware/DispatcherTest.php b/thinkphp/library/think/http/tests/middleware/DispatcherTest.php new file mode 100644 index 000000000..298cbccc1 --- /dev/null +++ b/thinkphp/library/think/http/tests/middleware/DispatcherTest.php @@ -0,0 +1,69 @@ +add(function () { + }); + $this->assertCount(1, $dispatcher->all()); + $this->expectException(\InvalidArgumentException::class); + $dispatcher->add('foo middleware'); + } + + public function testAddAndInsert() + { + $middleware1 = function () {}; + $middleware2 = function () {}; + $dispatcher = new Dispatcher(); + $dispatcher->add($middleware1); + $dispatcher->insert($middleware2); + $this->assertSame([$middleware2, $middleware1], $dispatcher->all()); + } + + public function testDispatch() + { + $middleware1 = function ($request, $next) { + return $next($request); + }; + $middleware2 = function ($request) { + return Response::create('hello world'); + }; + $dispatcher = new Dispatcher([$middleware1, $middleware2]); + $response = $dispatcher->dispatch(new Request()); + $this->assertInstanceOf(Response::class, $response); + $this->assertEquals('hello world', $response->getContent()); + } + + public function testDispatchWithoutResponse() + { + $middleware1 = function ($request, $next) { + return $next($request); + }; + $middleware2 = function ($request, $next) { + return $next($request); + }; + $dispatcher = new Dispatcher([$middleware1, $middleware2]); + $this->expectException(MissingResponseException::class); + $dispatcher->dispatch(new Request()); + } + + public function testDispatchWithBadResponse() + { + $middleware = function ($request, $next) { + return 'invalid response'; + }; + $dispatcher = new Dispatcher($middleware); + $this->expectException(\LogicException::class); + $dispatcher->dispatch(new Request()); + } +} diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php index f71509222..3ec4cd1c4 100644 --- a/thinkphp/library/think/log/driver/File.php +++ b/thinkphp/library/think/log/driver/File.php @@ -24,7 +24,6 @@ class File 'file_size' => 2097152, 'path' => '', 'apart_level' => [], - 'max_files' => 0, ]; protected $writed = []; @@ -37,9 +36,7 @@ class File } if (empty($this->config['path'])) { - $this->config['path'] = Container::get('app')->getRuntimePath() . 'log' . DIRECTORY_SEPARATOR; - } elseif (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) { - $this->config['path'] .= DIRECTORY_SEPARATOR; + $this->config['path'] = Container::get('app')->getRuntimePath() . 'log/'; } } @@ -52,23 +49,11 @@ class File public function save(array $log = []) { if ($this->config['single']) { - $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; + $name = is_string($single) ? $single : 'single'; $destination = $this->config['path'] . $name . '.log'; } else { - $cli = PHP_SAPI == 'cli' ? '_cli' : ''; - - if ($this->config['max_files']) { - $filename = date('Ymd') . $cli . '.log'; - $files = glob($this->config['path'] . '*.log'); - - if (count($files) > $this->config['max_files']) { - unlink($files[0]); - } - } else { - $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . $cli . '.log'; - } - - $destination = $this->config['path'] . $filename; + $cli = PHP_SAPI == 'cli' ? '_cli' : ''; + $destination = $this->config['path'] . date('Ym') . '/' . date('d') . $cli . '.log'; } $path = dirname($destination); @@ -87,11 +72,9 @@ class File if (in_array($type, $this->config['apart_level'])) { // 独立记录的日志级别 if ($this->config['single']) { - $filename = $path . DIRECTORY_SEPARATOR . $name . '_' . $type . '.log'; - } elseif ($this->config['max_files']) { - $filename = $path . DIRECTORY_SEPARATOR . date('Ymd') . '_' . $type . $cli . '.log'; + $filename = $path . '/' . $name . '_' . $type . '.log'; } else { - $filename = $path . DIRECTORY_SEPARATOR . date('d') . '_' . $type . $cli . '.log'; + $filename = $path . '/' . date('d') . '_' . $type . $cli . '.log'; } $this->write($level, $filename, true); @@ -120,7 +103,7 @@ class File // 检测日志文件大小,超过配置大小则备份日志文件重新生成 if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { try { - rename($destination, dirname($destination) . DIRECTORY_SEPARATOR . time() . '-' . basename($destination)); + rename($destination, dirname($destination) . '/' . time() . '-' . basename($destination)); } catch (\Exception $e) { } diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php index 1b6061a27..3a9b60f59 100644 --- a/thinkphp/library/think/model/Collection.php +++ b/thinkphp/library/think/model/Collection.php @@ -16,6 +16,18 @@ use think\Model; class Collection extends BaseCollection { + /** + * 返回数组中指定的一列 + * @access public + * @param string $column_key + * @param string|null $index_key + * @return array + */ + public function column($column_key, $index_key = null) + { + return array_column($this->toArray(), $column_key, $index_key); + } + /** * 延迟预载入关联查询 * @access public diff --git a/thinkphp/library/think/model/concern/Attribute.php b/thinkphp/library/think/model/concern/Attribute.php index c91cd835a..dc104481c 100644 --- a/thinkphp/library/think/model/concern/Attribute.php +++ b/thinkphp/library/think/model/concern/Attribute.php @@ -139,38 +139,37 @@ trait Attribute { if (is_string($data)) { $this->data[$data] = $value; - return $this; - } - - // 清空数据 - $this->data = []; - - if (is_object($data)) { - $data = get_object_vars($data); - } - - if ($this->disuse) { - // 废弃字段 - foreach ((array) $this->disuse as $key) { - if (array_key_exists($key, $data)) { - unset($data[$key]); - } - } - } - - if (true === $value) { - // 数据对象赋值 - foreach ($data as $key => $value) { - $this->setAttr($key, $value, $data); - } - } elseif (is_array($value)) { - foreach ($value as $name) { - if (isset($data[$name])) { - $this->data[$name] = $data[$name]; - } - } } else { - $this->data = $data; + // 清空数据 + $this->data = []; + + if (is_object($data)) { + $data = get_object_vars($data); + } + + if ($this->disuse) { + // 废弃字段 + foreach ((array) $this->disuse as $key) { + if (array_key_exists($key, $data)) { + unset($data[$key]); + } + } + } + + if (true === $value) { + // 数据对象赋值 + foreach ($data as $key => $value) { + $this->setAttr($key, $value, $data); + } + } elseif (is_array($value)) { + foreach ($value as $name) { + if (isset($data[$name])) { + $this->data[$name] = $data[$name]; + } + } + } else { + $this->data = $data; + } } return $this; @@ -211,8 +210,9 @@ trait Attribute { if (is_null($name)) { return $this->origin; + } else { + return array_key_exists($name, $this->origin) ? $this->origin[$name] : null; } - return array_key_exists($name, $this->origin) ? $this->origin[$name] : null; } /** @@ -230,8 +230,9 @@ trait Attribute return $this->data[$name]; } elseif (array_key_exists($name, $this->relation)) { return $this->relation[$name]; + } else { + throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name); } - throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name); } /** @@ -453,51 +454,36 @@ trait Attribute $value = $this->formatDateTime($value, $this->dateFormat); } } elseif ($notFound) { - $value = $this->getRelationAttribute($name, $item); - } + $relation = $this->isRelationAttr($name); - return $value; - } + if ($relation) { + $modelRelation = $this->$relation(); + if ($modelRelation instanceof Relation) { + $value = $this->getRelationData($modelRelation); - /** - * 获取关联属性值 - * @access protected - * @param string $name 属性名 - * @param array $item 数据 - * @return mixed - */ - protected function getRelationAttribute($name, &$item) - { - $relation = $this->isRelationAttr($name); + if ($item && method_exists($modelRelation, 'getBindAttr') && $bindAttr = $modelRelation->getBindAttr()) { - if ($relation) { - $modelRelation = $this->$relation(); - if ($modelRelation instanceof Relation) { - $value = $this->getRelationData($modelRelation); + foreach ($bindAttr as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; - if ($item && method_exists($modelRelation, 'getBindAttr') && $bindAttr = $modelRelation->getBindAttr()) { - - foreach ($bindAttr as $key => $attr) { - $key = is_numeric($key) ? $attr : $key; - - if (isset($item[$key])) { - throw new Exception('bind attr has exists:' . $key); - } else { - $item[$key] = $value ? $value->getAttr($attr) : null; + if (isset($item[$key])) { + throw new Exception('bind attr has exists:' . $key); + } else { + $item[$key] = $value ? $value->getAttr($attr) : null; + } } + return false; } - return false; + // 保存关联对象值 + $this->relation[$name] = $value; + + return $value; } - - // 保存关联对象值 - $this->relation[$name] = $value; - - return $value; } + throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name); } - - throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name); + return $value; } /** @@ -555,11 +541,7 @@ trait Attribute $value = empty($value) ? new \stdClass() : json_decode($value); break; case 'serialize': - try { - $value = unserialize($value); - } catch (\Exception $e) { - $value = null; - } + $value = unserialize($value); break; default: if (false !== strpos($type, '\\')) { diff --git a/thinkphp/library/think/model/concern/RelationShip.php b/thinkphp/library/think/model/concern/RelationShip.php index 2c993bd20..516119589 100644 --- a/thinkphp/library/think/model/concern/RelationShip.php +++ b/thinkphp/library/think/model/concern/RelationShip.php @@ -89,8 +89,9 @@ trait RelationShip return $this->relation; } elseif (array_key_exists($name, $this->relation)) { return $this->relation[$name]; + } else { + return; } - return; } /** @@ -141,10 +142,9 @@ trait RelationShip * @param mixed $operator 比较操作符 * @param integer $count 个数 * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 * @return Query */ - public static function has($relation, $operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + public static function has($relation, $operator = '>=', $count = 1, $id = '*') { $relation = (new static())->$relation(); @@ -152,7 +152,7 @@ trait RelationShip return $relation->hasWhere($operator); } - return $relation->has($operator, $count, $id, $joinType); + return $relation->has($operator, $count, $id); } /** diff --git a/thinkphp/library/think/model/concern/SoftDelete.php b/thinkphp/library/think/model/concern/SoftDelete.php index 473f9e3ea..16b75b728 100644 --- a/thinkphp/library/think/model/concern/SoftDelete.php +++ b/thinkphp/library/think/model/concern/SoftDelete.php @@ -52,8 +52,9 @@ trait SoftDelete return $model ->db(false) ->useSoftDelete($field, ['not null', '']); + } else { + return $model->db(false); } - return $model->db(false); } /** @@ -153,9 +154,9 @@ trait SoftDelete ->where($where) ->useSoftDelete($name, ['not null', '']) ->update([$name => null]); + } else { + return 0; } - - return 0; } /** diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php index bf2dbe53a..bcbab2ac1 100644 --- a/thinkphp/library/think/model/relation/BelongsTo.php +++ b/thinkphp/library/think/model/relation/BelongsTo.php @@ -52,7 +52,6 @@ class BelongsTo extends OneToOne $foreignKey = $this->foreignKey; $relationModel = $this->query - ->removeWhereField($this->localKey) ->where($this->localKey, $this->parent->$foreignKey) ->relation($subRelation) ->find(); @@ -70,10 +69,9 @@ class BelongsTo extends OneToOne * @param string $operator 比较操作符 * @param integer $count 个数 * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 * @return Query */ - public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + public function has($operator = '>=', $count = 1, $id = '*') { return $this->parent; } @@ -127,8 +125,6 @@ class BelongsTo extends OneToOne } if (!empty($range)) { - $this->query->removeWhereField($localKey); - $data = $this->eagerlyWhere([ [$localKey, 'in', $range], ], $localKey, $relation, $subRelation, $closure); @@ -172,8 +168,6 @@ class BelongsTo extends OneToOne $localKey = $this->localKey; $foreignKey = $this->foreignKey; - $this->query->removeWhereField($localKey); - $data = $this->eagerlyWhere([ [$localKey, '=', $result->$foreignKey], ], $localKey, $relation, $subRelation, $closure); @@ -227,21 +221,4 @@ class BelongsTo extends OneToOne return $this->parent->setRelation($this->relation, null); } - - /** - * 执行基础查询(仅执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery)) { - if (isset($this->parent->{$this->foreignKey})) { - // 关联查询带入关联条件 - $this->query->where($this->localKey, '=', $this->parent->{$this->foreignKey}); - } - - $this->baseQuery = true; - } - } } diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php index 02c743c59..915dea47c 100644 --- a/thinkphp/library/think/model/relation/HasOne.php +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -52,7 +52,6 @@ class HasOne extends OneToOne // 判断关联类型执行查询 $relationModel = $this->query - ->removeWhereField($this->foreignKey) ->where($this->foreignKey, $this->parent->$localKey) ->relation($subRelation) ->find(); @@ -67,13 +66,9 @@ class HasOne extends OneToOne /** * 根据关联条件查询当前模型 * @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') + public function has() { $table = $this->query->getTable(); $model = basename(str_replace('\\', '/', get_class($this->parent))); @@ -139,8 +134,6 @@ class HasOne extends OneToOne } if (!empty($range)) { - $this->query->removeWhereField($foreignKey); - $data = $this->eagerlyWhere([ [$foreignKey, 'in', $range], ], $foreignKey, $relation, $subRelation, $closure); @@ -183,10 +176,7 @@ class HasOne extends OneToOne { $localKey = $this->localKey; $foreignKey = $this->foreignKey; - - $this->query->removeWhereField($foreignKey); - - $data = $this->eagerlyWhere([ + $data = $this->eagerlyWhere([ [$foreignKey, '=', $result->$localKey], ], $foreignKey, $relation, $subRelation, $closure); @@ -207,20 +197,4 @@ class HasOne extends OneToOne } } - /** - * 执行基础查询(仅执行一次) - * @access protected - * @return void - */ - protected function baseQuery() - { - if (empty($this->baseQuery)) { - if (isset($this->parent->{$this->localKey})) { - // 关联查询带入关联条件 - $this->query->where($this->foreignKey, '=', $this->parent->{$this->localKey}); - } - - $this->baseQuery = true; - } - } } diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php index 2b489113d..b3a4f39f2 100644 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -244,7 +244,7 @@ class MorphMany extends Relation protected function eagerlyMorphToMany($where, $relation, $subRelation = '', $closure = false) { // 预载入关联查询 支持嵌套预载入 - $this->query->removeOption('where'); + $this->query->removeOptions('where'); if ($closure) { $closure($this->query); diff --git a/thinkphp/library/think/process/pipes/Windows.php b/thinkphp/library/think/process/pipes/Windows.php index 1b8b0d4f2..bba7e9b86 100644 --- a/thinkphp/library/think/process/pipes/Windows.php +++ b/thinkphp/library/think/process/pipes/Windows.php @@ -196,7 +196,7 @@ class Windows extends Pipes return; } - if (null !== $r && 0 < count($r)) { + if (null !== $w && 0 < count($r)) { $data = ''; while ($dataread = fread($r['input'], self::CHUNK_SIZE)) { $data .= $dataread; diff --git a/thinkphp/library/think/response/View.php b/thinkphp/library/think/response/View.php index 0b4cb28e0..fc32aa567 100644 --- a/thinkphp/library/think/response/View.php +++ b/thinkphp/library/think/response/View.php @@ -64,6 +64,7 @@ class View extends Response { if (is_array($name)) { $this->vars = array_merge($this->vars, $name); + return $this; } else { $this->vars[$name] = $value; } diff --git a/thinkphp/library/think/response/Xml.php b/thinkphp/library/think/response/Xml.php index 9c1681a4a..f92b99c77 100644 --- a/thinkphp/library/think/response/Xml.php +++ b/thinkphp/library/think/response/Xml.php @@ -41,15 +41,6 @@ class Xml extends Response */ protected function output($data) { - if (is_string($data)) { - if (0 !== strpos($data, 'options['encoding']; - $xml = ""; - $data = $xml . $data; - } - return $data; - } - // XML数据转换 return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); } diff --git a/thinkphp/library/think/route/AliasRule.php b/thinkphp/library/think/route/AliasRule.php deleted file mode 100644 index 217046596..000000000 --- a/thinkphp/library/think/route/AliasRule.php +++ /dev/null @@ -1,126 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\route; - -use think\Route; - -class AliasRule extends Domain -{ - protected $route; - - /** - * 架构函数 - * @access public - * @param Route $router 路由实例 - * @param RuleGroup $parent 上级对象 - * @param string $name 路由别名 - * @param string $route 路由绑定 - * @param array $option 路由参数 - */ - public function __construct(Route $router, RuleGroup $parent, $name, $route, $option = []) - { - $this->router = $router; - $this->parent = $parent; - $this->name = $name; - $this->route = $route; - $this->option = $option; - } - - /** - * 检测域名路由 - * @access public - * @param Request $request 请求对象 - * @param string $url 访问地址 - * @param string $depr 路径分隔符 - * @param bool $completeMatch 路由是否完全匹配 - * @return Dispatch|false - */ - public function check($request, $url, $depr = '/', $completeMatch = false) - { - if ($dispatch = $this->checkCrossDomain($request)) { - // 允许跨域 - return $dispatch; - } - - // 检查参数有效性 - if (!$this->checkOption($this->option, $request)) { - return false; - } - - list($action, $bind) = array_pad(explode('|', $url, 2), 2, ''); - - if (isset($this->option['allow']) && !in_array($action, $this->option['allow'])) { - // 允许操作 - return false; - } elseif (isset($this->option['except']) && in_array($action, $this->option['except'])) { - // 排除操作 - return false; - } - - if (isset($this->option['method'][$action])) { - $this->option['method'] = $this->option['method'][$action]; - } - - // 匹配后执行的行为 - $this->afterMatchGroup($request); - - if ($this->parent) { - // 合并分组参数 - $this->mergeGroupOptions(); - } - - $this->parseBindAppendParam($this->route); - - if (0 === strpos($this->route, '\\')) { - // 路由到类 - return $this->bindToClass($bind, substr($this->route, 1)); - } elseif (0 === strpos($this->route, '@')) { - // 路由到控制器类 - return $this->bindToController($bind, substr($this->route, 1)); - } else { - // 路由到模块/控制器 - return $this->bindToModule($bind, $this->route); - } - } - - /** - * 设置允许的操作方法 - * @access public - * @param array $action 操作方法 - * @return $this - */ - public function allow($action = []) - { - return $this->option('allow', $action); - } - - /** - * 设置排除的操作方法 - * @access public - * @param array $action 操作方法 - * @return $this - */ - public function except($action = []) - { - return $this->option('except', $action); - } - - /** - * 获取当前的路由 - * @access public - * @return string - */ - public function getRoute() - { - return $this->route; - } -} diff --git a/thinkphp/library/think/route/Domain.php b/thinkphp/library/think/route/Domain.php index 12ef39f30..d8f3e4f28 100644 --- a/thinkphp/library/think/route/Domain.php +++ b/thinkphp/library/think/route/Domain.php @@ -13,10 +13,12 @@ namespace think\route; use think\Container; use think\Loader; +use think\Response; use think\Route; use think\route\dispatch\Callback as CallbackDispatch; use think\route\dispatch\Controller as ControllerDispatch; use think\route\dispatch\Module as ModuleDispatch; +use think\route\dispatch\Response as ResponseDispatch; class Domain extends RuleGroup { @@ -24,7 +26,7 @@ class Domain extends RuleGroup * 架构函数 * @access public * @param Route $router 路由对象 - * @param string $name 路由域名 + * @param string $name 分组名称 * @param mixed $rule 域名路由 * @param array $option 路由参数 * @param array $pattern 变量规则 @@ -32,7 +34,7 @@ class Domain extends RuleGroup public function __construct(Route $router, $name = '', $rule = null, $option = [], $pattern = []) { $this->router = $router; - $this->domain = $name; + $this->name = trim($name, '/'); $this->option = $option; $this->rule = $rule; $this->pattern = $pattern; @@ -49,11 +51,30 @@ class Domain extends RuleGroup */ public function check($request, $url, $depr = '/', $completeMatch = false) { - // 检测别名路由 - $result = $this->checkRouteAlias($request, $url, $depr); + if ($this->rule) { + // 延迟解析域名路由 + if ($this->rule instanceof Response) { + return new ResponseDispatch($this->rule); + } - if (false !== $result) { - return $result; + $group = new RuleGroup($this->router); + + $this->addRule($group); + + $this->router->setGroup($group); + + $this->router->parseGroupRule($this, $this->rule); + + $this->rule = null; + } + + // 检测别名路由 + if ($this->router->getAlias($url) || $this->router->getAlias(strstr($url, '|', true))) { + // 检测路由别名 + $result = $this->checkRouteAlias($request, $url, $depr); + if (false !== $result) { + return $result; + } } // 检测URL绑定 @@ -66,19 +87,6 @@ class Domain extends RuleGroup return parent::check($request, $url, $depr, $completeMatch); } - /** - * 设置路由绑定 - * @access public - * @param string $bind 绑定信息 - * @return $this - */ - public function bind($bind) - { - $this->router->bind($bind, $this->domain); - - return $this; - } - /** * 检测路由别名 * @access private @@ -89,11 +97,45 @@ class Domain extends RuleGroup */ private function checkRouteAlias($request, $url, $depr) { - $alias = strpos($url, '|') ? strstr($url, '|', true) : $url; + $array = explode('|', $url); + $alias = array_shift($array); + $item = $this->router->getAlias($alias); - $item = $this->router->getAlias($alias); + if (is_array($item)) { + list($rule, $option) = $item; + $action = $array[0]; - return $item ? $item->check($request, $url, $depr) : false; + if (isset($option['allow']) && !in_array($action, explode(',', $option['allow']))) { + // 允许操作 + return false; + } elseif (isset($option['except']) && in_array($action, explode(',', $option['except']))) { + // 排除操作 + return false; + } + + if (isset($option['method'][$action])) { + $option['method'] = $option['method'][$action]; + } + } else { + $rule = $item; + } + + $bind = implode('|', $array); + + // 参数有效性检查 + if (isset($option) && !$this->checkOption($option, $request)) { + // 路由不匹配 + return false; + } elseif (0 === strpos($rule, '\\')) { + // 路由到类 + return $this->bindToClass($bind, substr($rule, 1), $depr); + } elseif (0 === strpos($rule, '@')) { + // 路由到控制器类 + return $this->bindToController($bind, substr($rule, 1), $depr); + } else { + // 路由到模块/控制器 + return $this->bindToModule($bind, $rule, $depr); + } } /** @@ -103,53 +145,41 @@ class Domain extends RuleGroup * @param string $depr URL分隔符 * @return Dispatch|false */ - private function checkUrlBind($url, $depr = '/') + private function checkUrlBind(&$url, $depr = '/') { - $bind = $this->router->getBind($this->domain); + $bind = $this->router->getBind($this->name); if (!empty($bind)) { - - $this->parseBindAppendParam($bind); - // 记录绑定信息 Container::get('app')->log('[ BIND ] ' . var_export($bind, true)); // 如果有URL绑定 则进行绑定检测 - $type = substr($bind, 0, 1); - $bind = substr($bind, 1); - - $bindTo = [ - '\\' => 'bindToClass', - '@' => 'bindToController', - ':' => 'bindToNamespace', - ]; - - if (isset($bindTo[$type])) { - return $this->{$bindTo[$type]}($url, $bind, $depr); + if (0 === strpos($bind, '\\')) { + // 绑定到类 + return $this->bindToClass($url, substr($bind, 1), $depr); + } elseif (0 === strpos($bind, '@')) { + // 绑定到控制器类 + return $this->bindToController($url, substr($bind, 1), $depr); + } elseif (0 === strpos($bind, ':')) { + // 绑定到命名空间 + return $this->bindToNamespace($url, substr($bind, 1), $depr); } } return false; } - protected function parseBindAppendParam(&$bind) - { - if (false !== strpos($bind, '?')) { - list($bind, $query) = explode('?', $bind); - parse_str($query, $vars); - $this->append($vars); - } - } - /** * 绑定到类 - * @access protected + * @access public * @param string $url URL地址 * @param string $class 类名(带命名空间) + * @param string $depr URL分隔符 * @return CallbackDispatch */ - protected function bindToClass($url, $class) + public function bindToClass($url, $class, $depr = '/') { + $url = str_replace($depr, '|', $url); $array = explode('|', $url, 2); $action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action'); @@ -162,13 +192,15 @@ class Domain extends RuleGroup /** * 绑定到命名空间 - * @access protected + * @access public * @param string $url URL地址 * @param string $namespace 命名空间 + * @param string $depr URL分隔符 * @return CallbackDispatch */ - protected function bindToNamespace($url, $namespace) + public function bindToNamespace($url, $namespace, $depr = '/') { + $url = str_replace($depr, '|', $url); $array = explode('|', $url, 3); $class = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_controller'); $method = !empty($array[1]) ? $array[1] : Container::get('config')->get('default_action'); @@ -182,13 +214,15 @@ class Domain extends RuleGroup /** * 绑定到控制器类 - * @access protected + * @access public * @param string $url URL地址 * @param string $controller 控制器名 (支持带模块名 index/user ) + * @param string $depr URL分隔符 * @return ControllerDispatch */ - protected function bindToController($url, $controller) + public function bindToController($url, $controller, $depr = '/') { + $url = str_replace($depr, '|', $url); $array = explode('|', $url, 2); $action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action'); @@ -201,13 +235,15 @@ class Domain extends RuleGroup /** * 绑定到模块/控制器 - * @access protected + * @access public * @param string $url URL地址 * @param string $controller 控制器类名(带命名空间) + * @param string $depr URL分隔符 * @return ModuleDispatch */ - protected function bindToModule($url, $controller) + public function bindToModule($url, $controller, $depr = '/') { + $url = str_replace($depr, '|', $url); $array = explode('|', $url, 2); $action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action'); diff --git a/thinkphp/library/think/route/Resource.php b/thinkphp/library/think/route/Resource.php index 6873132ee..7072623c7 100644 --- a/thinkphp/library/think/route/Resource.php +++ b/thinkphp/library/think/route/Resource.php @@ -26,17 +26,17 @@ class Resource extends RuleGroup * 架构函数 * @access public * @param Route $router 路由对象 - * @param RuleGroup $parent 上级对象 + * @param RuleGroup $group 路由所属分组对象 * @param string $name 资源名称 * @param string $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 * @param array $rest 资源定义 */ - public function __construct(Route $router, RuleGroup $parent = null, $name = '', $route = '', $option = [], $pattern = [], $rest = []) + public function __construct(Route $router, RuleGroup $group = null, $name = '', $route = '', $option = [], $pattern = [], $rest = []) { $this->router = $router; - $this->parent = $parent; + $this->parent = $group; $this->resource = $name; $this->route = $route; $this->name = strpos($name, '.') ? strstr($name, '.', true) : $name; @@ -49,28 +49,23 @@ class Resource extends RuleGroup $this->pattern = $pattern; $this->option = $option; $this->rest = $rest; - - if ($this->parent) { - $this->domain = $this->parent->getDomain(); - $this->parent->addRuleItem($this); - } } /** - * 解析资源路由规则 + * 检测分组路由 * @access public - * @param mixed $rule 路由规则 - * @return void + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param string $depr 路径分隔符 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch */ - public function parseGroupRule($rule) + public function check($request, $url, $depr = '/', $completeMatch = false) { - $origin = $this->router->getGroup(); - $this->router->setGroup($this); - // 生成资源路由的路由规则 $this->buildResourceRule($this->resource, $this->option); - $this->router->setGroup($origin); + return parent::check($request, $url, $depr, $completeMatch); } /** @@ -89,12 +84,17 @@ class Resource extends RuleGroup $item = []; foreach ($array as $val) { - $item[] = $val . '/<' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id') . '>'; + $item[] = $val . '/:' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id'); } $rule = implode('/', $item) . '/' . $last; } + // 注册分组 + $group = $this->router->getGroup(); + + $this->router->setGroup($this); + // 注册资源路由 foreach ($this->rest as $key => $val) { if ((isset($option['only']) && !in_array($key, $option['only'])) @@ -102,16 +102,18 @@ class Resource extends RuleGroup continue; } - if (isset($last) && strpos($val[1], '') && isset($option['var'][$last])) { - $val[1] = str_replace('', '<' . $option['var'][$last] . '>', $val[1]); - } elseif (strpos($val[1], '') && isset($option['var'][$rule])) { - $val[1] = str_replace('', '<' . $option['var'][$rule] . '>', $val[1]); + if (isset($last) && strpos($val[1], ':id') && isset($option['var'][$last])) { + $val[1] = str_replace(':id', ':' . $option['var'][$last], $val[1]); + } elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) { + $val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]); } $option['rest'] = $key; - $this->addRule(trim($val[1], '/'), $this->route . '/' . $val[2], $val[0], $option); + $this->router->rule(trim($val[1], '/'), $this->route . '/' . $val[2], $val[0], $option); } + + $this->router->setGroup($group); } /** diff --git a/thinkphp/library/think/route/Rule.php b/thinkphp/library/think/route/Rule.php index 92f1ce9de..7fe8d3e84 100644 --- a/thinkphp/library/think/route/Rule.php +++ b/thinkphp/library/think/route/Rule.php @@ -34,7 +34,7 @@ abstract class Rule // 路由变量规则 protected $pattern = []; // 需要合并的路由参数 - protected $mergeOptions = ['after', 'before', 'model', 'header', 'response', 'append', 'middleware']; + protected $mergeOptions = ['after', 'before', 'model']; abstract public function check($request, $url, $depr = '/'); @@ -75,14 +75,14 @@ abstract class Rule } /** - * 设置标识 + * 设置Name * @access public - * @param string $name 标识名 + * @param string|array $name 变量名 * @return $this */ public function name($name) { - $this->name = $name; + $this->name = '/' != $name ? ltrim($name, '/') : '/'; return $this; } @@ -127,6 +127,23 @@ abstract class Rule return isset($this->option[$name]) ? $this->option[$name] : null; } + /** + * 附加路由隐式参数 + * @access public + * @param array $append + * @return $this + */ + public function append(array $append = []) + { + if (isset($this->option['append'])) { + $this->option['append'] = array_merge($this->option['append'], $append); + } else { + $this->option['append'] = $append; + } + + return $this; + } + /** * 设置路由请求类型 * @access public @@ -203,9 +220,7 @@ abstract class Rule */ public function model($var, $model = null, $exception = true) { - if ($var instanceof \Closure) { - $this->option['model'][] = $var; - } elseif (is_array($var)) { + if (is_array($var)) { $this->option['model'] = $var; } elseif (is_null($model)) { $this->option['model']['id'] = [$var, true]; @@ -216,23 +231,6 @@ abstract class Rule return $this; } - /** - * 附加路由隐式参数 - * @access public - * @param array $append - * @return $this - */ - public function append(array $append = []) - { - if (isset($this->option['append'])) { - $this->option['append'] = array_merge($this->option['append'], $append); - } else { - $this->option['append'] = $append; - } - - return $this; - } - /** * 绑定验证 * @access public @@ -257,8 +255,7 @@ abstract class Rule */ public function response($response) { - $this->option['response'][] = $response; - return $this; + return $this->option('response', $response); } /** @@ -270,30 +267,14 @@ abstract class Rule */ public function header($header, $value = null) { - if (is_array($header)) { - $this->option['header'] = $header; - } else { - $this->option['header'][$header] = $value; + if (empty($this->option['header'])) { + $this->option['header'] = []; } - return $this; - } - - /** - * 指定路由中间件 - * @access public - * @param string|array|\Closure $middleware - * @param mixed $param - * @return $this - */ - public function middleware($middleware, $param = null) - { - if (is_null($param) && is_array($middleware)) { - $this->option['middleware'] = $middleware; + if (is_array($header)) { + $this->option['header'] = array_merge($this->option['header'], $header); } else { - foreach ((array) $middleware as $item) { - $this->option['middleware'][] = [$item, $param]; - } + $this->option['header'][$header] = $value; } return $this; @@ -435,7 +416,7 @@ abstract class Rule } if ($allow && $this->parent) { - $this->parent->addRuleItem($this, 'options'); + $this->parent->addRule($this, 'options'); } return $this->option('cross_domain', $allow); @@ -503,8 +484,6 @@ abstract class Rule } $this->option = array_merge($parentOption, $this->option); - - return $this->option; } /** @@ -595,15 +574,34 @@ abstract class Rule // 替换路由地址中的变量 if (is_string($route) && !empty($matches)) { foreach ($matches as $key => $val) { - if (false !== strpos($route, '<' . $key . '>')) { - $route = str_replace('<' . $key . '>', $val, $route); - } elseif (false !== strpos($route, ':' . $key)) { + if (false !== strpos($route, ':' . $key)) { $route = str_replace(':' . $key, $val, $route); } } } - $this->afterMatchRule($request, $option, $matches); + // 绑定模型数据 + if (isset($option['model'])) { + $this->createBindModel($option['model'], $matches); + } + + // 指定Header数据 + if (!empty($option['header'])) { + $header = $option['header']; + Container::get('hook')->add('response_send', function ($response) use ($header) { + $response->header($header); + }); + } + + // 指定Response响应数据 + if (!empty($option['response'])) { + Container::get('hook')->add('response_send', $option['response']); + } + + // 开启请求缓存 + if (isset($option['cache']) && $request->isGet()) { + $this->parseRequestCache($request, $option['cache']); + } // 解析额外参数 $count = substr_count($rule, '/'); @@ -631,43 +629,6 @@ abstract class Rule return $this->dispatch($request, $route, $option); } - protected function afterMatchRule($request, $option = [], $matches = []) - { - // 添加中间件 - if (!empty($option['middleware'])) { - foreach ($option['middleware'] as $middleware) { - Container::get('middleware')->add($middleware); - } - } - - // 绑定模型数据 - if (!empty($option['model'])) { - $this->createBindModel($option['model'], $matches); - } - - // 指定Header数据 - if (!empty($option['header'])) { - $header = $option['header']; - Container::get('hook')->add('response_send', function ($response) use ($header) { - $response->header($header); - }); - } - - // 指定Response响应数据 - if (!empty($option['response'])) { - Container::get('hook')->add('response_send', $option['response']); - } - - // 开启请求缓存 - if (isset($option['cache']) && $request->isGet()) { - $this->parseRequestCache($request, $option['cache']); - } - - if (!empty($option['append'])) { - $request->route($option['append']); - } - } - /** * 验证数据 * @access protected @@ -733,8 +694,6 @@ abstract class Rule */ protected function checkAfter($after) { - Container::get('log')->notice('路由后置行为建议使用中间件替代!'); - $hook = Container::get('hook'); $result = null; @@ -752,9 +711,9 @@ abstract class Rule return new ResponseDispatch($result); } elseif ($result instanceof Dispatch) { return $result; + } else { + return false; } - - return false; } /** @@ -779,13 +738,24 @@ abstract class Rule $result = new RedirectDispatch($route, [], isset($option['status']) ? $option['status'] : 301); } elseif (false !== strpos($route, '\\')) { // 路由到方法 - $result = $this->dispatchMethod($route); + list($path, $var) = $this->parseUrlPath($route); + $route = str_replace('/', '@', implode('/', $path)); + $method = strpos($route, '@') ? explode('@', $route) : $route; + $result = new CallbackDispatch($method, $var); } elseif (0 === strpos($route, '@')) { // 路由到控制器 - $result = $this->dispatchController($request, substr($route, 1)); + $route = substr($route, 1); + list($route, $var) = $this->parseUrlPath($route); + $result = new ControllerDispatch(implode('/', $route), $var); + + $request->action(array_pop($route)); + $app = Container::get('app'); + $request->controller($route ? array_pop($route) : $app->config('default_controller')); + $request->module($route ? array_pop($route) : $app->config('default_module')); + $app->setModulePath($app->getAppPath() . ($app->config('app_multi_module') ? $request->module() . DIRECTORY_SEPARATOR : '')); } else { // 路由到模块/控制器/操作 - $result = $this->dispatchModule($request, $route); + $result = $this->parseModule($route); } return $result; @@ -794,57 +764,18 @@ abstract class Rule /** * 解析URL地址为 模块/控制器/操作 * @access protected - * @param string $route 路由地址 - * @return CallbackDispatch + * @param string $url URL地址 + * @return array */ - protected function dispatchMethod($route) + protected function parseModule($url) { - list($path, $var) = $this->parseUrlPath($route); - - $route = str_replace('/', '@', implode('/', $path)); - $method = strpos($route, '@') ? explode('@', $route) : $route; - - return new CallbackDispatch($method, $var); - } - - /** - * 解析URL地址为 模块/控制器/操作 - * @access protected - * @param Request $request Request对象 - * @param string $route 路由地址 - * @return ControllerDispatch - */ - protected function dispatchController($request, $route) - { - list($route, $var) = $this->parseUrlPath($route); - - $result = new ControllerDispatch(implode('/', $route), $var); - - $request->action(array_pop($route)); - $app = Container::get('app'); - $request->controller($route ? array_pop($route) : $app->config('default_controller')); - $request->module($route ? array_pop($route) : $app->config('default_module')); - $app->setModulePath($app->getAppPath() . ($app->config('app_multi_module') ? $request->module() . DIRECTORY_SEPARATOR : '')); - - return $result; - } - - /** - * 解析URL地址为 模块/控制器/操作 - * @access protected - * @param Request $request Request对象 - * @param string $route 路由地址 - * @return ModuleDispatch - */ - protected function dispatchModule($request, $route) - { - list($path, $var) = $this->parseUrlPath($route); - - $config = Container::get('config'); - $action = array_pop($path); - $controller = !empty($path) ? array_pop($path) : null; - $module = $config->get('app_multi_module') && !empty($path) ? array_pop($path) : null; - $method = $request->method(); + list($path, $var) = $this->parseUrlPath($url); + $config = Container::get('config'); + $request = Container::get('request'); + $action = array_pop($path); + $controller = !empty($path) ? array_pop($path) : null; + $module = $config->get('app_multi_module') && !empty($path) ? array_pop($path) : null; + $method = $request->method(); if ($config->get('use_action_prefix') && $this->router->getMethodPrefix($method)) { $prefix = $this->router->getMethodPrefix($method); @@ -959,107 +890,6 @@ abstract class Rule return [$path, $var]; } - /** - * 生成路由的正则规则 - * @access protected - * @param string $rule 路由规则 - * @param array $match 匹配的变量 - * @param array $pattern 路由变量规则 - * @param array $option 路由参数 - * @param bool $completeMatch 路由是否完全匹配 - * @param string $suffix 路由正则变量后缀 - * @return string - */ - protected function buildRuleRegex($rule, $match, $pattern = [], $option = [], $completeMatch = false, $suffix = '') - { - foreach ($match as $name) { - $replace[] = $this->buildNameRegex($name, $pattern, $suffix); - } - - // 是否区分 / 地址访问 - if (!empty($option['remove_slash']) && '/' != $rule) { - $rule = rtrim($rule, '/'); - } - - $regex = str_replace($match, $replace, $rule); - $regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex); - - return $regex . ($completeMatch ? '$' : ''); - } - - /** - * 生成路由变量的正则规则 - * @access protected - * @param string $name 路由变量 - * @param string $pattern 变量规则 - * @param string $suffix 路由正则变量后缀 - * @return string - */ - protected function buildNameRegex($name, $pattern, $suffix) - { - $optional = ''; - $slash = substr($name, 0, 1); - - if (in_array($slash, ['/', '-'])) { - $prefix = '\\' . $slash; - $name = substr($name, 1); - $slash = substr($name, 0, 1); - } else { - $prefix = ''; - } - - if ('<' != $slash) { - return $prefix . preg_quote($name, '/'); - } - - if (strpos($name, '?')) { - $name = substr($name, 1, -2); - $optional = '?'; - } elseif (strpos($name, '>')) { - $name = substr($name, 1, -1); - } - - if (isset($pattern[$name])) { - $nameRule = $pattern[$name]; - if (0 === strpos($nameRule, '/') && '/' == substr($nameRule, -1)) { - $nameRule = substr($nameRule, 1, -1); - } - } else { - $nameRule = '\w+'; - } - - return '(' . $prefix . '(?<' . $name . $suffix . '>' . $nameRule . '))' . $optional; - } - - /** - * 分析路由规则中的变量 - * @access protected - * @param string $rule 路由规则 - * @return array - */ - protected function parseVar($rule) - { - // 提取路由规则中的变量 - $var = []; - - if (preg_match_all('/<\w+\??>/', $rule, $matches)) { - foreach ($matches[0] as $name) { - $optional = false; - - if (strpos($name, '?')) { - $name = substr($name, 1, -2); - $optional = true; - } else { - $name = substr($name, 1, -1); - } - - $var[$name] = $optional ? 2 : 1; - } - } - - return $var; - } - /** * 设置路由参数 * @access public diff --git a/thinkphp/library/think/route/RuleGroup.php b/thinkphp/library/think/route/RuleGroup.php index 333c49977..3f8317414 100644 --- a/thinkphp/library/think/route/RuleGroup.php +++ b/thinkphp/library/think/route/RuleGroup.php @@ -12,7 +12,6 @@ namespace think\route; use think\Container; -use think\Exception; use think\Request; use think\Response; use think\Route; @@ -44,51 +43,35 @@ class RuleGroup extends Rule // 完整名称 protected $fullName; - // 所在域名 - protected $domain; - /** * 架构函数 * @access public * @param Route $router 路由对象 - * @param RuleGroup $parent 上级对象 + * @param RuleGroup $group 路由所属分组对象 * @param string $name 分组名称 * @param mixed $rule 分组路由 * @param array $option 路由参数 * @param array $pattern 变量规则 */ - public function __construct(Route $router, RuleGroup $parent = null, $name = '', $rule = [], $option = [], $pattern = []) + public function __construct(Route $router, RuleGroup $group = null, $name = '', $rule = [], $option = [], $pattern = []) { $this->router = $router; - $this->parent = $parent; + $this->parent = $group; $this->rule = $rule; $this->name = trim($name, '/'); $this->option = $option; $this->pattern = $pattern; $this->setFullName(); - - if ($this->parent) { - $this->domain = $this->parent->getDomain(); - $this->parent->addRuleItem($this); - } - - if (!empty($option['cross_domain'])) { - $this->router->setCrossDomainRule($this); - } } /** * 设置分组的路由规则 * @access public - * @return void + * @return $this */ protected function setFullName() { - if (false !== strpos($this->name, ':')) { - $this->name = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $this->name); - } - if ($this->parent && $this->parent->getFullName()) { $this->fullName = $this->parent->getFullName() . ($this->name ? '/' . $this->name : ''); } else { @@ -97,13 +80,15 @@ class RuleGroup extends Rule } /** - * 获取所属域名 + * 设置分组的路由规则 * @access public - * @return string + * @param mixed $rule 路由规则 + * @return $this */ - public function getDomain() + public function setRule($rule) { - return $this->domain; + $this->rule = $rule; + return $this; } /** @@ -118,53 +103,87 @@ class RuleGroup extends Rule public function check($request, $url, $depr = '/', $completeMatch = false) { if ($dispatch = $this->checkCrossDomain($request)) { - // 跨域OPTIONS请求 + // 允许跨域 return $dispatch; } - // 检查分组有效性 - if (!$this->checkOption($this->option, $request) || !$this->checkUrl($url)) { + // 检查参数有效性 + if (!$this->checkOption($this->option, $request)) { return false; } - // 解析分组路由 + if ($this->fullName) { + // 分组URL匹配检查 + $pos = strpos(str_replace('<', ':', $this->fullName), ':'); + + if (false !== $pos) { + $str = substr($this->fullName, 0, $pos); + } else { + $str = $this->fullName; + } + + if (0 !== stripos(str_replace('|', '/', $url), $str)) { + return false; + } + } + if ($this->rule) { + // 延迟解析分组路由 if ($this->rule instanceof Response) { return new ResponseDispatch($this->rule); } - $this->parseGroupRule($this->rule); + $group = $this->router->getGroup(); + + $this->router->setGroup($this); + + $this->router->parseGroupRule($this, $this->rule); + + $this->router->setGroup($group); + + $this->rule = null; + } + + // 分组匹配后执行的行为 + + // 指定Response响应数据 + if (!empty($this->option['response'])) { + Container::get('hook')->add('response_send', $this->option['response']); + } + + // 开启请求缓存 + if (isset($this->option['cache']) && $request->isGet()) { + $this->parseRequestCache($request, $this->option['cache']); } // 获取当前路由规则 $method = strtolower($request->method()); - $rules = $this->getMethodRules($method); - - if (count($rules) == 0) { - return false; - } + $rules = array_merge($this->rules['*'], $this->rules[$method]); if ($this->parent) { // 合并分组参数 $this->mergeGroupOptions(); - // 合并分组变量规则 - $this->pattern = array_merge($this->parent->getPattern(), $this->pattern); } if (isset($this->option['complete_match'])) { $completeMatch = $this->option['complete_match']; } - if (!empty($this->option['merge_rule_regex'])) { - // 合并路由正则规则进行路由匹配检查 - $result = $this->checkMergeRuleRegex($request, $rules, $url, $depr, $completeMatch); + if (!empty($this->option['append'])) { + $request->route($this->option['append']); + } + + if (isset($rules[$url])) { + // 快速定位 + $item = $rules[$url]; + $result = $item->check($request, $url, $depr, $completeMatch); if (false !== $result) { return $result; } } - // 检查分组路由 + // 遍历分组路由 foreach ($rules as $key => $item) { $result = $item->check($request, $url, $depr, $completeMatch); @@ -173,10 +192,10 @@ class RuleGroup extends Rule } } - if ($this->auto) { + if (isset($this->auto)) { // 自动解析URL地址 - $result = new UrlDispatch($this->auto . '/' . $url, ['depr' => $depr, 'auto_search' => false]); - } elseif ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) { + $result = new UrlDispatch($this->auto->getRoute() . '/' . $url, ['depr' => $depr, 'auto_search' => false]); + } elseif (isset($this->miss)) { // 未匹配所有路由的路由规则处理 $result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption()); } else { @@ -187,275 +206,37 @@ class RuleGroup extends Rule } /** - * 获取当前请求的路由规则(包括子分组、资源路由) - * @access protected - * @param string $method - * @return array - */ - protected function getMethodRules($method) - { - return array_merge($this->rules['*'], $this->rules[$method]); - } - - /** - * 分组URL匹配检查 - * @access protected - * @param string $url - * @return bool - */ - protected function checkUrl($url) - { - if ($this->fullName) { - $pos = strpos($this->fullName, '<'); - - if (false !== $pos) { - $str = substr($this->fullName, 0, $pos); - } else { - $str = $this->fullName; - } - - if ($str && 0 !== stripos(str_replace('|', '/', $url), $str)) { - return false; - } - } - - return true; - } - - /** - * 延迟解析分组的路由规则 + * 设置自动路由 * @access public - * @param bool $lazy 路由是否延迟解析 + * @param RuleItem $rule 路由规则 * @return $this */ - public function lazy($lazy = true) + public function setAutoRule(RuleItem $rule) { - if (!$lazy && !is_object($this->rule)) { - $this->parseGroupRule($this->rule); - $this->rule = null; - } - + $this->auto = $rule; return $this; } /** - * 解析分组和域名的路由规则及绑定 + * 设置为MISS路由 * @access public - * @param mixed $rule 路由规则 - * @return void + * @param RuleItem $rule 路由规则 + * @return $this */ - public function parseGroupRule($rule) + public function setMissRule(RuleItem $rule) { - $origin = $this->router->getGroup(); - $this->router->setGroup($this); - - if ($rule instanceof \Closure) { - Container::getInstance()->invokeFunction($rule); - } elseif (is_array($rule)) { - $this->addRules($rule); - } elseif (is_string($rule) && $rule) { - $this->router->bind($rule, $this->domain); - } - - $this->router->setGroup($origin); - } - - /** - * 检测分组路由 - * @access public - * @param Request $request 请求对象 - * @param array $rules 路由规则 - * @param string $url 访问地址 - * @param string $depr 路径分隔符 - * @param bool $completeMatch 路由是否完全匹配 - * @return Dispatch|false - */ - protected function checkMergeRuleRegex($request, &$rules, $url, $depr, $completeMatch) - { - $url = $depr . str_replace('|', $depr, $url); - - foreach ($rules as $key => $item) { - if ($item instanceof RuleItem) { - $rule = $depr . str_replace('/', $depr, $item->getRule()); - if ($depr == $rule && $depr != $url) { - unset($rules[$key]); - continue; - } - - $complete = null !== $item->getOption('complete_match') ? $item->getOption('complete_match') : $completeMatch; - - if (false === strpos($rule, '<')) { - if (0 === strcasecmp($rule, $url) || (!$complete && 0 === strncasecmp($rule, $url, strlen($rule)))) { - return $item->checkRule($request, $url, []); - } - - unset($rules[$key]); - continue; - } - - $slash = preg_quote('/-' . $depr, '/'); - - if ($matchRule = preg_split('/[' . $slash . ']<\w+\??>/', $rule, 2)) { - if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) { - unset($rules[$key]); - continue; - } - } - - if (preg_match_all('/[' . $slash . ']??/', $rule, $matches)) { - unset($rules[$key]); - $pattern = array_merge($this->getPattern(), $item->getPattern()); - $option = array_merge($this->getOption(), $item->getOption()); - - $regex[$key] = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $complete, '_THINK_' . $key); - $items[$key] = $item; - } - } - } - - try { - if (!empty($regex) && preg_match('/^(?:' . implode('|', $regex) . ')/', $url, $match)) { - $var = []; - foreach ($match as $key => $val) { - if (is_string($key) && '' !== $val) { - list($name, $pos) = explode('_THINK_', $key); - - $var[$name] = $val; - } - } - - if (!isset($pos)) { - foreach ($regex as $key => $item) { - if (0 === strpos(str_replace(['\/', '\-', '\\' . $depr], ['/', '-', $depr], $item), $match[0])) { - $pos = $key; - break; - } - } - } - - return $items[$pos]->checkRule($request, $url, $var); - } - - return false; - } catch (\Exception $e) { - throw new Exception('route pattern error'); - } - } - - /** - * 获取分组的MISS路由 - * @access public - * @return RuleItem|null - */ - public function getMissRule() - { - return $this->miss; - } - - /** - * 获取分组的自动路由 - * @access public - * @return string - */ - public function getAutoRule() - { - return $this->auto; - } - - /** - * 注册自动路由 - * @access public - * @param string $route 路由规则 - * @return void - */ - public function addAutoRule($route) - { - $this->auto = $route; - } - - /** - * 注册MISS路由 - * @access public - * @param string $route 路由地址 - * @param string $method 请求类型 - * @param array $option 路由参数 - * @return RuleItem - */ - public function addMissRule($route, $method = '*', $option = []) - { - // 创建路由规则实例 - $ruleItem = new RuleItem($this->router, $this, null, '', $route, strtolower($method), $option); - - $this->miss = $ruleItem; - - return $ruleItem; + $this->miss = $rule; + return $this; } /** * 添加分组下的路由规则或者子分组 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $method 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param Rule $rule 路由规则 + * @param string $method 请求类型 * @return $this */ - public function addRule($rule, $route, $method = '*', $option = [], $pattern = []) - { - // 读取路由标识 - if (is_array($rule)) { - $name = $rule[0]; - $rule = $rule[1]; - } elseif (is_string($route)) { - $name = $route; - } else { - $name = null; - } - - $method = strtolower($method); - - // 创建路由规则实例 - $ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method, $option, $pattern); - - if (!empty($option['cross_domain'])) { - $this->router->setCrossDomainRule($ruleItem, $method); - } - - $this->addRuleItem($ruleItem, $method); - - return $ruleItem; - } - - /** - * 批量注册路由规则 - * @access public - * @param array $rules 路由规则 - * @param string $method 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @return void - */ - public function addRules($rules, $method = '*', $option = [], $pattern = []) - { - foreach ($rules as $key => $val) { - if (is_numeric($key)) { - $key = array_shift($val); - } - - if (is_array($val)) { - $route = array_shift($val); - $option = $val ? array_shift($val) : []; - $pattern = $val ? array_shift($val) : []; - } else { - $route = $val; - } - - $this->addRule($key, $route, $method, $option, $pattern); - } - } - - public function addRuleItem($rule, $method = '*') + public function addRule($rule, $method = '*') { if (strpos($method, '|')) { $rule->method($method); @@ -475,24 +256,13 @@ class RuleGroup extends Rule */ public function prefix($prefix) { - if ($this->parent && $this->parent->getOption('prefix')) { + if ($this->parent->getOption('prefix')) { $prefix = $this->parent->getOption('prefix') . $prefix; } return $this->option('prefix', $prefix); } - /** - * 合并分组的路由规则正则 - * @access public - * @param bool $merge - * @return $this - */ - public function mergeRuleRegex($merge = true) - { - return $this->option('merge_rule_regex', $merge); - } - /** * 获取完整分组Name * @access public @@ -513,9 +283,9 @@ class RuleGroup extends Rule { if ('' === $method) { return $this->rules; + } else { + return isset($this->rules[strtolower($method)]) ? $this->rules[strtolower($method)] : []; } - - return isset($this->rules[strtolower($method)]) ? $this->rules[strtolower($method)] : []; } } diff --git a/thinkphp/library/think/route/RuleItem.php b/thinkphp/library/think/route/RuleItem.php index b7873b0cf..e26637f62 100644 --- a/thinkphp/library/think/route/RuleItem.php +++ b/thinkphp/library/think/route/RuleItem.php @@ -11,8 +11,6 @@ namespace think\route; -use think\Container; -use think\Exception; use think\Route; class RuleItem extends Rule @@ -21,7 +19,7 @@ class RuleItem extends Rule * 路由规则 * @var string */ - protected $rule; + protected $name; /** * 路由地址 @@ -39,29 +37,23 @@ class RuleItem extends Rule * 架构函数 * @access public * @param Route $router 路由实例 - * @param RuleGroup $parent 上级对象 - * @param string $name 路由标识 - * @param string|array $rule 路由规则 + * @param RuleGroup $group 路由所属分组对象 + * @param string|array $name 路由规则 * @param string $method 请求类型 * @param string|\Closure $route 路由地址 * @param array $option 路由参数 * @param array $pattern 变量规则 */ - public function __construct(Route $router, RuleGroup $parent, $name, $rule, $route, $method = '*', $option = [], $pattern = []) + public function __construct(Route $router, RuleGroup $group, $name, $route, $method = '*', $option = [], $pattern = []) { $this->router = $router; - $this->parent = $parent; - $this->name = $name; + $this->parent = $group; $this->route = $route; $this->method = $method; $this->option = $option; $this->pattern = $pattern; - $this->setRule($rule); - - if (!empty($option['cross_domain'])) { - $this->router->setCrossDomainRule($this, $method); - } + $this->setRule($name); } /** @@ -79,30 +71,7 @@ class RuleItem extends Rule $this->option['complete_match'] = true; } - $rule = '/' != $rule ? ltrim($rule, '/') : ''; - - if ($this->parent && $prefix = $this->parent->getFullName()) { - $rule = $prefix . ($rule ? '/' . ltrim($rule, '/') : ''); - } - - if (false !== strpos($rule, ':')) { - $this->rule = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $rule); - } else { - $this->rule = $rule; - } - - // 生成路由标识的快捷访问 - $this->setRuleName(); - } - - /** - * 获取当前路由规则 - * @access public - * @return string - */ - public function getRule() - { - return $this->rule; + $this->name($rule); } /** @@ -116,53 +85,25 @@ class RuleItem extends Rule } /** - * 获取当前路由的请求类型 + * 设置为自动路由 * @access public - * @return string - */ - public function getMethod() - { - return strtolower($this->method); - } - - /** - * 检查后缀 - * @access public - * @param string $ext * @return $this */ - public function ext($ext = '') + public function isAuto() { - $this->option('ext', $ext); - $this->setRuleName(true); - + $this->parent->setAutoRule($this); return $this; } /** - * 设置路由标识 用于URL反解生成 - * @access protected - * @param bool $first 是否插入开头 - * @return void + * 设置为MISS路由 + * @access public + * @return $this */ - protected function setRuleName($first = false) + public function isMiss() { - if ($this->name) { - $vars = $this->parseVar($this->rule); - $name = strtolower($this->name); - - if (isset($this->option['ext'])) { - $suffix = $this->option['ext']; - } elseif ($this->parent->getOption('ext')) { - $suffix = $this->parent->getOption('ext'); - } else { - $suffix = null; - } - - $value = [$this->rule, $vars, $this->parent->getDomain(), $suffix]; - - Container::get('rule_name')->set($name, $value, $first); - } + $this->parent->setMissRule($this); + return $this; } /** @@ -170,13 +111,16 @@ class RuleItem extends Rule * @access public * @param Request $request 请求对象 * @param string $url 访问地址 - * @param array $match 匹配路由变量 * @param string $depr 路径分隔符 * @param bool $completeMatch 路由是否完全匹配 - * @return Dispatch|false + * @return Dispatch */ - public function checkRule($request, $url, $match = null, $depr = '/', $completeMatch = false) + public function check($request, $url, $depr = '/', $completeMatch = false) { + if ($this->parent && $prefix = $this->parent->getFullName()) { + $this->name = $prefix . ($this->name ? '/' . ltrim($this->name, '/') : ''); + } + if ($dispatch = $this->checkCrossDomain($request)) { // 允许跨域 return $dispatch; @@ -188,124 +132,162 @@ class RuleItem extends Rule } // 合并分组参数 - $option = $this->mergeGroupOptions(); + $this->mergeGroupOptions(); + $option = $this->option; + + if (!empty($option['append'])) { + $request->route($option['append']); + } + + // 是否区分 / 地址访问 + if (!empty($option['remove_slash']) && '/' != $this->name) { + $this->name = rtrim($this->name, '/'); + $url = rtrim($url, '|'); + } // 检查前置行为 if (isset($option['before']) && false === $this->checkBefore($option['before'])) { return false; } - $url = $this->urlSuffixCheck($request, $url, $option); - - if (is_null($match)) { - $match = $this->match($url, $option, $depr, $completeMatch); - } - - if (false !== $match) { - return $this->parseRule($request, $this->rule, $this->route, $url, $option, $match); - } - - return false; - } - - /** - * 检测路由(含路由匹配) - * @access public - * @param Request $request 请求对象 - * @param string $url 访问地址 - * @param string $depr 路径分隔符 - * @param bool $completeMatch 路由是否完全匹配 - * @return Dispatch|false - */ - public function check($request, $url, $depr = '/', $completeMatch = false) - { - return $this->checkRule($request, $url, null, $depr, $completeMatch); - } - - /** - * URL后缀及Slash检查 - * @access protected - * @param Request $request 请求对象 - * @param string $url 访问地址 - * @param array $option 路由参数 - * @return string - */ - protected function urlSuffixCheck($request, $url, $option = []) - { - // 是否区分 / 地址访问 - if (!empty($option['remove_slash']) && '/' != $this->rule) { - $this->rule = rtrim($this->rule, '/'); - $url = rtrim($url, '|'); - } - if (isset($option['ext'])) { // 路由ext参数 优先于系统配置的URL伪静态后缀参数 $url = preg_replace('/\.(' . $request->ext() . ')$/i', '', $url); } - return $url; + return $this->checkRule($request, $url, $depr, $completeMatch, $option); + } + + /** + * 检测路由规则 + * @access private + * @param Request $request 请求对象 + * @param string $url URL地址 + * @param string $depr URL分隔符(全局) + * @param bool $completeMatch 路由是否完全匹配 + * @param array $option 路由参数 + * @return array|false + */ + private function checkRule($request, $url, $depr, $completeMatch = false, $option = []) + { + // 检查完整规则定义 + if (isset($this->pattern['__url__']) && !preg_match(0 === strpos($this->pattern['__url__'], '/') ? $this->pattern['__url__'] : '/^' . $this->pattern['__url__'] . '/', str_replace('|', $depr, $url))) { + return false; + } + + // 检查路由的参数分隔符 + if (isset($option['param_depr'])) { + $url = str_replace(['|', $option['param_depr']], [$depr, '|'], $url); + } + + $len1 = substr_count($url, '|'); + $len2 = substr_count($this->name, '/'); + + // 多余参数是否合并 + $merge = !empty($option['merge_extra_vars']) ? true : false; + + if ($merge && $len1 > $len2) { + $url = str_replace('|', $depr, $url); + $url = implode('|', explode($depr, $url, $len2 + 1)); + } + + if (isset($option['complete_match'])) { + $completeMatch = $option['complete_match']; + } + + if ($len1 >= $len2 || strpos($this->name, '[')) { + // 完整匹配 + if ($completeMatch && (!$merge && $len1 != $len2 && (false === strpos($this->name, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($this->name, '[')))) { + return false; + } + + $pattern = array_merge($this->parent->getPattern(), $this->pattern); + + if (false !== $match = $this->match($url, $pattern)) { + // 匹配到路由规则 + return $this->parseRule($request, $this->name, $this->route, $url, $option, $match); + } + } + + return false; } /** * 检测URL和规则路由是否匹配 * @access private * @param string $url URL地址 - * @param array $option 路由参数 - * @param string $depr URL分隔符(全局) - * @param bool $completeMatch 路由是否完全匹配 + * @param array $pattern 变量规则 * @return array|false */ - private function match($url, $option, $depr, $completeMatch) + private function match($url, $pattern) { - if (isset($option['complete_match'])) { - $completeMatch = $option['complete_match']; - } + $m2 = explode('/', $this->name); + $m1 = explode('|', $url); - $pattern = array_merge($this->parent->getPattern(), $this->pattern); + $var = []; - // 检查完整规则定义 - if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) { - return false; - } + foreach ($m2 as $key => $val) { + // val中定义了多个变量 + if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { + $value = []; + $replace = []; - $var = []; - $url = $depr . str_replace('|', $depr, $url); - $rule = $depr . str_replace('/', $depr, $this->rule); + foreach ($matches[1] as $name) { + if (strpos($name, '?')) { + $name = substr($name, 0, -1); + $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')?'; + } else { + $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')'; + } + $value[] = $name; + } - if ($depr == $rule && $depr != $url) { - return false; - } + $val = str_replace($matches[0], $replace, $val); - if (false === strpos($rule, '<')) { - if (0 === strcasecmp($rule, $url) || (!$completeMatch && 0 === strncasecmp($rule, $url, strlen($rule)))) { - return $var; - } - return false; - } - - $slash = preg_quote('/-' . $depr, '/'); - - if ($matchRule = preg_split('/[' . $slash . ']?<\w+\??>/', $rule, 2)) { - if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) { - return false; - } - } - - if (preg_match_all('/[' . $slash . ']??/', $rule, $matches)) { - $regex = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $completeMatch); - - try { - if (!preg_match('/^' . $regex . ($completeMatch ? '$' : '') . '/', $url, $match)) { + if (preg_match('/^' . $val . '$/', isset($m1[$key]) ? $m1[$key] : '', $match)) { + array_shift($match); + foreach ($value as $k => $name) { + if (isset($match[$k])) { + $var[$name] = $match[$k]; + } + } + continue; + } else { return false; } - } catch (\Exception $e) { - throw new Exception('route pattern error'); } - foreach ($match as $key => $val) { - if (is_string($key)) { - $var[$key] = $val; + if (0 === strpos($val, '[:')) { + // 可选参数 + $val = substr($val, 1, -1); + $optional = true; + } else { + $optional = false; + } + + if (0 === strpos($val, ':')) { + // URL变量 + $name = substr($val, 1); + + if (!$optional && !isset($m1[$key])) { + return false; } + + if (isset($m1[$key]) && isset($pattern[$name])) { + // 检查变量规则 + if ($pattern[$name] instanceof \Closure) { + $result = call_user_func_array($pattern[$name], [$m1[$key]]); + if (false === $result) { + return false; + } + } elseif (!preg_match(0 === strpos($pattern[$name], '/') ? $pattern[$name] : '/^' . $pattern[$name] . '$/', $m1[$key])) { + return false; + } + } + + $var[$name] = isset($m1[$key]) ? $m1[$key] : ''; + } elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) { + return false; } } diff --git a/thinkphp/library/think/route/RuleName.php b/thinkphp/library/think/route/RuleName.php deleted file mode 100644 index 460ccab39..000000000 --- a/thinkphp/library/think/route/RuleName.php +++ /dev/null @@ -1,63 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace think\route; - -class RuleName -{ - protected $item = []; - - /** - * 注册路由标识 - * @access public - * @param string $name 路由标识 - * @param array $value 路由规则 - * @param bool $first 是否置顶 - * @return void - */ - public function set($name, $value, $first = false) - { - if ($first) { - array_unshift($this->item[$name], $value); - } else { - $this->item[$name][] = $value; - } - } - - /** - * 导入路由标识 - * @access public - * @param array $name 路由标识 - * @return void - */ - public function import($item) - { - $this->item = $item; - } - - /** - * 根据路由标识获取路由信息(用于URL生成) - * @access public - * @param string $name 路由标识 - * @return array|null - */ - public function get($name = null) - { - if (is_null($name)) { - return $this->item; - } - - $name = strtolower($name); - - return isset($this->item[$name]) ? $this->item[$name] : null; - } - -} diff --git a/thinkphp/library/think/route/dispatch/Module.php b/thinkphp/library/think/route/dispatch/Module.php index 93d5bf103..20bb812df 100644 --- a/thinkphp/library/think/route/dispatch/Module.php +++ b/thinkphp/library/think/route/dispatch/Module.php @@ -11,7 +11,6 @@ namespace think\route\dispatch; -use ReflectionMethod; use think\Container; use think\exception\ClassNotFoundException; use think\exception\HttpException; @@ -55,7 +54,7 @@ class Module extends Dispatch $this->app->init($module); // 加载当前模块语言包 - $this->app['lang']->load($this->app->getAppPath() . $module . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $this->app['request']->langset() . '.php'); + $this->app['lang']->load($this->app->getAppPath() . $module . '/lang/' . $this->app['request']->langset() . '.php'); // 模块请求缓存检查 $this->app['request']->cache( @@ -73,7 +72,7 @@ class Module extends Dispatch } // 当前模块路径 - $this->app->setModulePath($this->app->getAppPath() . ($module ? $module . DIRECTORY_SEPARATOR : '')); + $this->app->setModulePath($this->app->getAppPath() . ($module ? $module . '/' : '')); // 是否自动转换控制器和操作名 $convert = is_bool($this->convert) ? $this->convert : $this->app->config('app.url_convert'); @@ -83,9 +82,10 @@ class Module extends Dispatch // 获取操作名 $actionName = strip_tags($result[2] ?: $this->app->config('app.default_action')); + $actionName = $convert ? strtolower($actionName) : $actionName; // 设置当前请求的控制器、操作 - $this->app['request']->controller(Loader::parseName($controller, 1)); + $this->app['request']->controller(Loader::parseName($controller, 1))->action($actionName); // 监听module_init $this->app['hook']->listen('module_init'); @@ -106,24 +106,14 @@ class Module extends Dispatch if (is_callable([$instance, $action])) { // 执行操作方法 $call = [$instance, $action]; - - // 严格获取当前操作方法名 - $reflect = new ReflectionMethod($instance, $action); - $methodName = $reflect->getName(); - $suffix = $this->app->config('app.action_suffix'); - $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName; - $this->app['request']->action($actionName); - // 自动获取请求变量 $vars = $this->app->config('app.url_param_type') ? $this->app['request']->route() : $this->app['request']->param(); } elseif (is_callable([$instance, '_empty'])) { // 空操作 - $this->app['request']->action($actionName); - $call = [$instance, '_empty']; - $vars = [$actionName]; - $reflect = new ReflectionMethod($instance, '_empty'); + $call = [$instance, '_empty']; + $vars = [$actionName]; } else { // 操作不存在 throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); @@ -131,6 +121,6 @@ class Module extends Dispatch $this->app['hook']->listen('action_begin', $call); - return Container::getInstance()->invokeReflectMethod($instance, $reflect, $vars); + return Container::getInstance()->invokeMethod($call, $vars); } } diff --git a/vendor/autoload.php b/vendor/autoload.php index 3cc741d8f..6022434f0 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece::getLoader(); +return ComposerAutoloaderInitba64bd31f645bcd87c20ea0144cdca77::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index d7a24189a..ae3eddf22 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece +class ComposerAutoloaderInitba64bd31f645bcd87c20ea0144cdca77 { private static $loader; @@ -19,15 +19,15 @@ class ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitba64bd31f645bcd87c20ea0144cdca77', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitba64bd31f645bcd87c20ea0144cdca77', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -48,19 +48,19 @@ class ComposerAutoloaderInitcf980ce2ebc944e5d847ad4152559ece $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequirecf980ce2ebc944e5d847ad4152559ece($fileIdentifier, $file); + composerRequireba64bd31f645bcd87c20ea0144cdca77($fileIdentifier, $file); } return $loader; } } -function composerRequirecf980ce2ebc944e5d847ad4152559ece($fileIdentifier, $file) +function composerRequireba64bd31f645bcd87c20ea0144cdca77($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6d426f836..08b1f9162 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece +class ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77 { public static $files = array ( '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', @@ -257,9 +257,9 @@ class ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitcf980ce2ebc944e5d847ad4152559ece::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitba64bd31f645bcd87c20ea0144cdca77::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index e12607dca..7b4e00b1e 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -175,17 +175,17 @@ }, { "name": "topthink/framework", - "version": "5.1.6", - "version_normalized": "5.1.6.0", + "version": "v5.1.5", + "version_normalized": "5.1.5.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "98aaf52dd364af7fdecc7214224678d180676b4f" + "reference": "f81c4282cdf401be44fbe1a28b3e3df425e3017f" }, "dist": { "type": "zip", - "url": "https://files.phpcomposer.com/files/top-think/framework/98aaf52dd364af7fdecc7214224678d180676b4f.zip", - "reference": "98aaf52dd364af7fdecc7214224678d180676b4f", + "url": "https://files.phpcomposer.com/files/top-think/framework/f81c4282cdf401be44fbe1a28b3e3df425e3017f.zip", + "reference": "f81c4282cdf401be44fbe1a28b3e3df425e3017f", "shasum": "" }, "require": { @@ -201,7 +201,7 @@ "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, - "time": "2018-03-26T07:10:00+00:00", + "time": "2018-02-02T05:39:38+00:00", "type": "think-framework", "installation-source": "dist", "notification-url": "https://packagist.org/downloads/",