Browse Source

[更新]ComposerUpdate for ThinkPHP

邹景立 7 years ago
parent
commit
699e4e038a
100 changed files with 0 additions and 32203 deletions
  1. 0 8
      thinkphp/.gitignore
  2. 0 1
      thinkphp/.htaccess
  3. 0 119
      thinkphp/CONTRIBUTING.md
  4. 0 32
      thinkphp/LICENSE.txt
  5. 0 60
      thinkphp/README.md
  6. 0 105
      thinkphp/base.php
  7. 0 35
      thinkphp/composer.json
  8. 0 302
      thinkphp/convention.php
  9. 0 691
      thinkphp/helper.php
  10. 0 141
      thinkphp/lang/zh-cn.php
  11. 0 916
      thinkphp/library/think/App.php
  12. 0 407
      thinkphp/library/think/Build.php
  13. 0 117
      thinkphp/library/think/Cache.php
  14. 0 388
      thinkphp/library/think/Collection.php
  15. 0 313
      thinkphp/library/think/Config.php
  16. 0 794
      thinkphp/library/think/Console.php
  17. 0 365
      thinkphp/library/think/Container.php
  18. 0 239
      thinkphp/library/think/Controller.php
  19. 0 262
      thinkphp/library/think/Cookie.php
  20. 0 72
      thinkphp/library/think/Db.php
  21. 0 258
      thinkphp/library/think/Debug.php
  22. 0 109
      thinkphp/library/think/Env.php
  23. 0 128
      thinkphp/library/think/Error.php
  24. 0 56
      thinkphp/library/think/Exception.php
  25. 0 126
      thinkphp/library/think/Facade.php
  26. 0 494
      thinkphp/library/think/File.php
  27. 0 212
      thinkphp/library/think/Hook.php
  28. 0 265
      thinkphp/library/think/Lang.php
  29. 0 405
      thinkphp/library/think/Loader.php
  30. 0 398
      thinkphp/library/think/Log.php
  31. 0 132
      thinkphp/library/think/Middleware.php
  32. 0 1014
      thinkphp/library/think/Model.php
  33. 0 437
      thinkphp/library/think/Paginator.php
  34. 0 1268
      thinkphp/library/think/Process.php
  35. 0 1966
      thinkphp/library/think/Request.php
  36. 0 401
      thinkphp/library/think/Response.php
  37. 0 858
      thinkphp/library/think/Route.php
  38. 0 531
      thinkphp/library/think/Session.php
  39. 0 1304
      thinkphp/library/think/Template.php
  40. 0 357
      thinkphp/library/think/Url.php
  41. 0 1487
      thinkphp/library/think/Validate.php
  42. 0 236
      thinkphp/library/think/View.php
  43. 0 353
      thinkphp/library/think/cache/Driver.php
  44. 0 305
      thinkphp/library/think/cache/driver/File.php
  45. 0 209
      thinkphp/library/think/cache/driver/Lite.php
  46. 0 203
      thinkphp/library/think/cache/driver/Memcache.php
  47. 0 216
      thinkphp/library/think/cache/driver/Memcached.php
  48. 0 206
      thinkphp/library/think/cache/driver/Redis.php
  49. 0 233
      thinkphp/library/think/cache/driver/Sqlite.php
  50. 0 174
      thinkphp/library/think/cache/driver/Wincache.php
  51. 0 177
      thinkphp/library/think/cache/driver/Xcache.php
  52. 0 24
      thinkphp/library/think/config/driver/Ini.php
  53. 0 26
      thinkphp/library/think/config/driver/Json.php
  54. 0 33
      thinkphp/library/think/config/driver/Xml.php
  55. 0 470
      thinkphp/library/think/console/Command.php
  56. 0 464
      thinkphp/library/think/console/Input.php
  57. 0 19
      thinkphp/library/think/console/LICENSE
  58. 0 222
      thinkphp/library/think/console/Output.php
  59. 0 1
      thinkphp/library/think/console/bin/README.md
  60. BIN
      thinkphp/library/think/console/bin/hiddeninput.exe
  61. 0 60
      thinkphp/library/think/console/command/Build.php
  62. 0 45
      thinkphp/library/think/console/command/Clear.php
  63. 0 69
      thinkphp/library/think/console/command/Help.php
  64. 0 74
      thinkphp/library/think/console/command/Lists.php
  65. 0 111
      thinkphp/library/think/console/command/Make.php
  66. 0 54
      thinkphp/library/think/console/command/RunServer.php
  67. 0 57
      thinkphp/library/think/console/command/make/Controller.php
  68. 0 36
      thinkphp/library/think/console/command/make/Middleware.php
  69. 0 36
      thinkphp/library/think/console/command/make/Model.php
  70. 0 64
      thinkphp/library/think/console/command/make/stubs/controller.api.stub
  71. 0 10
      thinkphp/library/think/console/command/make/stubs/controller.plain.stub
  72. 0 85
      thinkphp/library/think/console/command/make/stubs/controller.stub
  73. 0 10
      thinkphp/library/think/console/command/make/stubs/middleware.stub
  74. 0 10
      thinkphp/library/think/console/command/make/stubs/model.stub
  75. 0 280
      thinkphp/library/think/console/command/optimize/Autoload.php
  76. 0 110
      thinkphp/library/think/console/command/optimize/Config.php
  77. 0 68
      thinkphp/library/think/console/command/optimize/Route.php
  78. 0 121
      thinkphp/library/think/console/command/optimize/Schema.php
  79. 0 115
      thinkphp/library/think/console/input/Argument.php
  80. 0 375
      thinkphp/library/think/console/input/Definition.php
  81. 0 190
      thinkphp/library/think/console/input/Option.php
  82. 0 340
      thinkphp/library/think/console/output/Ask.php
  83. 0 319
      thinkphp/library/think/console/output/Descriptor.php
  84. 0 198
      thinkphp/library/think/console/output/Formatter.php
  85. 0 211
      thinkphp/library/think/console/output/Question.php
  86. 0 149
      thinkphp/library/think/console/output/descriptor/Console.php
  87. 0 52
      thinkphp/library/think/console/output/driver/Buffer.php
  88. 0 368
      thinkphp/library/think/console/output/driver/Console.php
  89. 0 33
      thinkphp/library/think/console/output/driver/Nothing.php
  90. 0 116
      thinkphp/library/think/console/output/formatter/Stack.php
  91. 0 189
      thinkphp/library/think/console/output/formatter/Style.php
  92. 0 163
      thinkphp/library/think/console/output/question/Choice.php
  93. 0 57
      thinkphp/library/think/console/output/question/Confirmation.php
  94. 0 1166
      thinkphp/library/think/db/Builder.php
  95. 0 2152
      thinkphp/library/think/db/Connection.php
  96. 0 48
      thinkphp/library/think/db/Expression.php
  97. 0 3143
      thinkphp/library/think/db/Query.php
  98. 0 188
      thinkphp/library/think/db/builder/Mysql.php
  99. 0 98
      thinkphp/library/think/db/builder/Pgsql.php
  100. 0 89
      thinkphp/library/think/db/builder/Sqlite.php

+ 0 - 8
thinkphp/.gitignore

@@ -1,8 +0,0 @@
-/vendor
-composer.phar
-composer.lock
-.DS_Store
-Thumbs.db
-/phpunit.xml
-/.idea
-/.vscode

+ 0 - 1
thinkphp/.htaccess

@@ -1 +0,0 @@
-deny from all

+ 0 - 119
thinkphp/CONTRIBUTING.md

@@ -1,119 +0,0 @@
-如何贡献我的源代码
-===
-
-此文档介绍了 ThinkPHP 团队的组成以及运转机制,您提交的代码将给 ThinkPHP 项目带来什么好处,以及如何才能加入我们的行列。
-
-## 通过 Github 贡献代码
-
-ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。
-
-参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请并。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。
-
-我们希望你贡献的代码符合:
-
-* ThinkPHP 的编码规范
-* 适当的注释,能让其他人读懂
-* 遵循 Apache2 开源协议
-
-**如果想要了解更多细节或有任何疑问,请继续阅读下面的内容**
-
-### 注意事项
-
-* 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141);
-* 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144);
-* 对于 Issues 的处理,请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。
-* 系统会自动在 PHP 5.4 5.5 5.6 7.0 和 HHVM 上测试修改,其中 HHVM 下的测试容许报错,请确保你的修改符合 PHP 5.4 ~ 5.6 和 PHP 7.0 的语法规范;
-* 管理员不会合并造成 CI faild 的修改,若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests);
-
-## GitHub Issue
-
-GitHub 提供了 Issue 功能,该功能可以用于:
-
-* 提出 bug
-* 提出功能改进
-* 反馈使用体验
-
-该功能不应该用于:
-
- * 提出修改意见(涉及代码署名和修订追溯问题)
- * 不友善的言论
-
-## 快速修改
-
-**GitHub 提供了快速编辑文件的功能**
-
-1. 登录 GitHub 帐号;
-2. 浏览项目文件,找到要进行修改的文件;
-3. 点击右上角铅笔图标进行修改;
-4. 填写 `Commit changes` 相关内容(Title 必填);
-5. 提交修改,等待 CI 验证和管理员合并。
-
-**若您需要一次提交大量修改,请继续阅读下面的内容**
-
-## 完整流程
-
-1. `fork`本项目;
-2. 克隆(`clone`)你 `fork` 的项目到本地;
-3. 新建分支(`branch`)并检出(`checkout`)新分支;
-4. 添加本项目到你的本地 git 仓库作为上游(`upstream`);
-5. 进行修改,若你的修改包含方法或函数的增减,请记得修改[单元测试文件](tests);
-6. 变基(衍合 `rebase`)你的分支到上游 master 分支;
-7. `push` 你的本地仓库到 GitHub;
-8. 提交 `pull request`;
-9. 等待 CI 验证(若不通过则重复 5~7,GitHub 会自动更新你的 `pull request`);
-10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。
-
-*若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`*
-
-*绝对不可以使用 `git push -f` 强行推送修改到上游*
-
-### 注意事项
-
-* 若对上述流程有任何不清楚的地方,请查阅 GIT 教程,如 [这个](http://backlogtool.com/git-guide/cn/);
-* 对于代码**不同方面**的修改,请在自己 `fork` 的项目中**创建不同的分支**(原因参见`完整流程`第9条备注部分);
-* 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/)
-
-## 推荐资源
-
-### 开发环境
-
-* XAMPP for Windows 5.5.x
-* WampServer (for Windows)
-* upupw Apache PHP5.4 ( for Windows)
-
-或自行安装
-
-- Apache / Nginx
-- PHP 5.4 ~ 5.6
-- MySQL / MariaDB
-
-*Windows 用户推荐添加 PHP bin 目录到 PATH,方便使用 composer*
-
-*Linux 用户自行配置环境, Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB*
-
-### 编辑器
-
-Sublime Text 3 + phpfmt 插件
-
-phpfmt 插件参数
-
-```json
-{
-	"autocomplete": true,
-	"enable_auto_align": true,
-	"format_on_save": true,
-	"indent_with_space": true,
-	"psr1_naming": false,
-	"psr2": true,
-	"version": 4
-}
-```
-
-或其他 编辑器 / IDE 配合 PSR2 自动格式化工具
-
-### Git GUI
-
-* SourceTree
-* GitHub Desktop
-
-或其他 Git 图形界面客户端

+ 0 - 32
thinkphp/LICENSE.txt

@@ -1,32 +0,0 @@
-
-ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
-版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
-All rights reserved。
-ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
-
-Apache Licence是著名的非盈利开源组织Apache采用的协议。
-该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
-允许代码修改,再作为开源或商业软件发布。需要满足
-的条件: 
-1. 需要给代码的用户一份Apache Licence ;
-2. 如果你修改了代码,需要在被修改的文件中说明;
-3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
-带有原来代码中的协议,商标,专利声明和其他原来作者规
-定需要包含的说明;
-4. 如果再发布的产品中包含一个Notice文件,则在Notice文
-件中需要带有本协议内容。你可以在Notice中增加自己的
-许可,但不可以表现为对Apache Licence构成更改。 
-具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.

+ 0 - 60
thinkphp/README.md

@@ -1,60 +0,0 @@
-![](http://www.thinkphp.cn/Uploads/editor/2016-06-23/576b4732a6e04.png) 
-
-ThinkPHP 5.1 —— 12载初心,你值得信赖的PHP框架
-===============
-
-[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework)
-[![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)
-[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework)
-
-ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特性包括:
-
- + 采用容器统一管理对象
- + 支持Facade
- + 更易用的路由
- + 注解路由支持
- + 路由跨域请求支持
- + 验证类增强
- + 配置和路由目录独立
- + 取消系统常量
- + 类库别名机制
- + 模型和数据库增强
- + 依赖注入完善
- + 支持PSR-3日志规范
-
-### 废除的功能:
-
- + 聚合模型
- + 内置控制器扩展类
- + 模型自动验证
-
-> ThinkPHP5.1的运行环境要求PHP5.6+。
-
-
-## 在线手册
-
-+ [完全开发手册](https://www.kancloud.cn/manual/thinkphp5_1/content)
-+ [升级指导](https://www.kancloud.cn/manual/thinkphp5_1/354155) 
-
-## 命名规范
-
-`ThinkPHP5`遵循PSR-2命名规范和PSR-4自动加载规范。
-
-## 参与开发
-
-请参阅 [ThinkPHP5 核心框架包](https://github.com/top-think/framework)。
-
-## 版权信息
-
-ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
-
-本项目包含的第三方源码和二进制文件之版权信息另行标注。
-
-版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn)
-
-All rights reserved。
-
-ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
-
-更多细节参阅 [LICENSE.txt](LICENSE.txt)

+ 0 - 105
thinkphp/base.php

@@ -1,105 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-namespace think;
-
-// 载入Loader类
-require __DIR__ . '/library/think/Loader.php';
-
-// 注册自动加载
-Loader::register();
-
-// 注册错误和异常处理机制
-Error::register();
-
-// 实现日志接口
-if (interface_exists('Psr\Log\LoggerInterface')) {
-    interface LoggerInterface extends \Psr\Log\LoggerInterface
-    {}
-} else {
-    interface LoggerInterface
-    {}
-}
-
-// 注册核心类到容器
-Container::getInstance()->bind([
-    'app'                   => App::class,
-    'build'                 => Build::class,
-    'cache'                 => Cache::class,
-    'config'                => Config::class,
-    'cookie'                => Cookie::class,
-    'debug'                 => Debug::class,
-    'env'                   => Env::class,
-    'hook'                  => Hook::class,
-    'lang'                  => Lang::class,
-    'log'                   => Log::class,
-    'middleware'            => Middleware::class,
-    'request'               => Request::class,
-    'response'              => Response::class,
-    'route'                 => Route::class,
-    'session'               => Session::class,
-    'url'                   => Url::class,
-    'validate'              => Validate::class,
-    'view'                  => View::class,
-    'rule_name'             => route\RuleName::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,
-]);
-
-// 注册类库别名
-Loader::addClassAlias([
-    'App'      => facade\App::class,
-    'Build'    => facade\Build::class,
-    'Cache'    => facade\Cache::class,
-    'Config'   => facade\Config::class,
-    'Cookie'   => facade\Cookie::class,
-    'Db'       => Db::class,
-    'Debug'    => facade\Debug::class,
-    'Env'      => facade\Env::class,
-    'Facade'   => Facade::class,
-    'Hook'     => facade\Hook::class,
-    'Lang'     => facade\Lang::class,
-    'Log'      => facade\Log::class,
-    'Request'  => facade\Request::class,
-    'Response' => facade\Response::class,
-    'Route'    => facade\Route::class,
-    'Session'  => facade\Session::class,
-    'Url'      => facade\Url::class,
-    'Validate' => facade\Validate::class,
-    'View'     => facade\View::class,
-]);
-
-// 加载惯例配置文件
-facade\Config::set(include __DIR__ . '/convention.php');
-
-// 加载composer autofile文件
-Loader::loadComposerAutoloadFiles();

+ 0 - 35
thinkphp/composer.json

@@ -1,35 +0,0 @@
-{
-    "name": "topthink/framework",
-    "description": "the new thinkphp framework",
-    "type": "think-framework",
-    "keywords": [
-        "framework",
-        "thinkphp",
-        "ORM"
-    ],
-    "homepage": "http://thinkphp.cn/",
-    "license": "Apache-2.0",
-    "authors": [
-        {
-            "name": "liu21st",
-            "email": "liu21st@gmail.com"
-        },
-        {
-            "name": "yunwuxin",
-            "email": "448901948@qq.com"
-        }
-    ],
-    "require": {
-        "php": ">=5.6.0",
-        "topthink/think-installer": "~1.0"
-    },
-    "require-dev": {
-        "phpunit/phpunit": "^5.0|^6.0",
-        "johnkary/phpunit-speedtrap": "^1.0",
-        "mikey179/vfsStream": "~1.6",
-        "phploc/phploc": "2.*",
-        "sebastian/phpcpd": "2.*",
-        "squizlabs/php_codesniffer": "2.*",
-        "phpdocumentor/reflection-docblock": "^2.0"
-    }
-}

+ 0 - 302
thinkphp/convention.php

@@ -1,302 +0,0 @@
-<?php
-
-return [
-    // +----------------------------------------------------------------------
-    // | 应用设置
-    // +----------------------------------------------------------------------
-    'app'      => [
-        // 应用名称
-        'app_name'               => '',
-        // 应用地址
-        'app_host'               => '',
-        // 应用调试模式
-        'app_debug'              => false,
-        // 应用Trace
-        'app_trace'              => false,
-        // 应用模式状态
-        'app_status'             => '',
-        // 是否支持多模块
-        'app_multi_module'       => true,
-        // 入口自动绑定模块
-        'auto_bind_module'       => false,
-        // 注册的根命名空间
-        'root_namespace'         => [],
-        // 默认输出类型
-        'default_return_type'    => 'html',
-        // 默认AJAX 数据返回格式,可选json xml ...
-        'default_ajax_return'    => 'json',
-        // 默认JSONP格式返回的处理方法
-        'default_jsonp_handler'  => 'jsonpReturn',
-        // 默认JSONP处理方法
-        'var_jsonp_handler'      => 'callback',
-        // 默认时区
-        'default_timezone'       => 'Asia/Shanghai',
-        // 是否开启多语言
-        'lang_switch_on'         => false,
-        // 默认全局过滤方法 用逗号分隔多个
-        'default_filter'         => '',
-        // 默认语言
-        'default_lang'           => 'zh-cn',
-        // 应用类库后缀
-        'class_suffix'           => false,
-        // 控制器类后缀
-        'controller_suffix'      => false,
-
-        // +----------------------------------------------------------------------
-        // | 模块设置
-        // +----------------------------------------------------------------------
-
-        // 默认模块名
-        'default_module'         => 'index',
-        // 禁止访问模块
-        'deny_module_list'       => ['common'],
-        // 默认控制器名
-        'default_controller'     => 'Index',
-        // 默认操作名
-        'default_action'         => 'index',
-        // 默认验证器
-        'default_validate'       => '',
-        // 默认的空模块名
-        'empty_module'           => '',
-        // 默认的空控制器名
-        'empty_controller'       => 'Error',
-        // 操作方法前缀
-        'use_action_prefix'      => false,
-        // 操作方法后缀
-        'action_suffix'          => '',
-        // 自动搜索控制器
-        'controller_auto_search' => false,
-
-        // +----------------------------------------------------------------------
-        // | URL设置
-        // +----------------------------------------------------------------------
-
-        // PATHINFO变量名 用于兼容模式
-        'var_pathinfo'           => 's',
-        // 兼容PATH_INFO获取
-        'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
-        // pathinfo分隔符
-        'pathinfo_depr'          => '/',
-        // HTTPS代理标识
-        'https_agent_name'       => '',
-        // URL伪静态后缀
-        'url_html_suffix'        => 'html',
-        // URL普通方式参数 用于自动生成
-        'url_common_param'       => false,
-        // URL参数方式 0 按名称成对解析 1 按顺序解析
-        'url_param_type'         => 0,
-        // 是否开启路由延迟解析
-        'url_lazy_route'         => false,
-        // 是否强制使用路由
-        'url_route_must'         => false,
-        // 合并路由规则
-        'route_rule_merge'       => false,
-        // 路由是否完全匹配
-        'route_complete_match'   => false,
-        // 使用注解路由
-        'route_annotation'       => false,
-        // 域名根,如thinkphp.cn
-        'url_domain_root'        => '',
-        // 是否自动转换URL中的控制器和操作名
-        'url_convert'            => true,
-        // 默认的访问控制器层
-        'url_controller_layer'   => 'controller',
-        // 表单请求类型伪装变量
-        'var_method'             => '_method',
-        // 表单ajax伪装变量
-        'var_ajax'               => '_ajax',
-        // 表单pjax伪装变量
-        'var_pjax'               => '_pjax',
-        // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
-        'request_cache'          => false,
-        // 请求缓存有效期
-        'request_cache_expire'   => null,
-        // 全局请求缓存排除规则
-        'request_cache_except'   => [],
-
-        // 默认跳转页面对应的模板文件
-        'dispatch_success_tmpl'  => __DIR__ . '/tpl/dispatch_jump.tpl',
-        'dispatch_error_tmpl'    => __DIR__ . '/tpl/dispatch_jump.tpl',
-
-        // +----------------------------------------------------------------------
-        // | 异常及错误设置
-        // +----------------------------------------------------------------------
-
-        // 异常页面的模板文件
-        'exception_tmpl'         => __DIR__ . '/tpl/think_exception.tpl',
-
-        // 错误显示信息,非调试模式有效
-        'error_message'          => '页面错误!请稍后再试~',
-        // 显示错误信息
-        'show_error_msg'         => false,
-        // 异常处理handle类 留空使用 \think\exception\Handle
-        'exception_handle'       => '',
-    ],
-
-    // +----------------------------------------------------------------------
-    // | 模板设置
-    // +----------------------------------------------------------------------
-
-    'template' => [
-        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
-        'auto_rule'    => 1,
-        // 模板引擎类型 支持 php think 支持扩展
-        'type'         => 'Think',
-        // 视图基础目录,配置目录为所有模块的视图起始目录
-        'view_base'    => '',
-        // 当前模板的视图目录 留空为自动获取
-        'view_path'    => '',
-        // 模板后缀
-        'view_suffix'  => 'html',
-        // 模板文件名分隔符
-        'view_depr'    => DIRECTORY_SEPARATOR,
-        // 模板引擎普通标签开始标记
-        'tpl_begin'    => '{',
-        // 模板引擎普通标签结束标记
-        'tpl_end'      => '}',
-        // 标签库标签开始标记
-        'taglib_begin' => '{',
-        // 标签库标签结束标记
-        'taglib_end'   => '}',
-    ],
-
-    // +----------------------------------------------------------------------
-    // | 日志设置
-    // +----------------------------------------------------------------------
-
-    'log'      => [
-        // 日志记录方式,内置 file socket 支持扩展
-        'type'         => 'File',
-        // 日志保存目录
-        //'path'  => LOG_PATH,
-        // 日志记录级别
-        'level'        => [],
-        // 是否记录trace信息到日志
-        'record_trace' => false,
-    ],
-
-    // +----------------------------------------------------------------------
-    // | Trace设置 开启 app_trace 后 有效
-    // +----------------------------------------------------------------------
-    'trace'    => [
-        // 内置Html Console 支持扩展
-        'type' => 'Html',
-        'file' => __DIR__ . '/tpl/page_trace.tpl',
-    ],
-
-    // +----------------------------------------------------------------------
-    // | 缓存设置
-    // +----------------------------------------------------------------------
-
-    'cache'    => [
-        // 驱动方式
-        'type'   => 'File',
-        // 缓存保存目录
-        //'path'   => CACHE_PATH,
-        // 缓存前缀
-        'prefix' => '',
-        // 缓存有效期 0表示永久缓存
-        'expire' => 0,
-    ],
-
-    // +----------------------------------------------------------------------
-    // | 会话设置
-    // +----------------------------------------------------------------------
-
-    'session'  => [
-        'id'             => '',
-        // SESSION_ID的提交变量,解决flash上传跨域
-        'var_session_id' => '',
-        // SESSION 前缀
-        'prefix'         => 'think',
-        // 驱动方式 支持redis memcache memcached
-        'type'           => '',
-        // 是否自动开启 SESSION
-        'auto_start'     => true,
-        'httponly'       => true,
-        'secure'         => false,
-    ],
-
-    // +----------------------------------------------------------------------
-    // | Cookie设置
-    // +----------------------------------------------------------------------
-    'cookie'   => [
-        // cookie 名称前缀
-        'prefix'    => '',
-        // cookie 保存时间
-        'expire'    => 0,
-        // cookie 保存路径
-        'path'      => '/',
-        // cookie 有效域名
-        'domain'    => '',
-        //  cookie 启用安全传输
-        'secure'    => false,
-        // httponly设置
-        'httponly'  => '',
-        // 是否使用 setcookie
-        'setcookie' => true,
-    ],
-
-    // +----------------------------------------------------------------------
-    // | 数据库设置
-    // +----------------------------------------------------------------------
-
-    'database' => [
-        // 数据库类型
-        'type'            => 'mysql',
-        // 数据库连接DSN配置
-        'dsn'             => '',
-        // 服务器地址
-        'hostname'        => '127.0.0.1',
-        // 数据库名
-        'database'        => '',
-        // 数据库用户名
-        'username'        => 'root',
-        // 数据库密码
-        'password'        => '',
-        // 数据库连接端口
-        'hostport'        => '',
-        // 数据库连接参数
-        'params'          => [],
-        // 数据库编码默认采用utf8
-        'charset'         => 'utf8',
-        // 数据库表前缀
-        'prefix'          => '',
-        // 数据库调试模式
-        'debug'           => false,
-        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
-        'deploy'          => 0,
-        // 数据库读写是否分离 主从式有效
-        'rw_separate'     => false,
-        // 读写分离后 主服务器数量
-        'master_num'      => 1,
-        // 指定从服务器序号
-        'slave_no'        => '',
-        // 是否严格检查字段是否存在
-        'fields_strict'   => true,
-        // 数据集返回类型
-        'resultset_type'  => 'array',
-        // 自动写入时间戳字段
-        'auto_timestamp'  => false,
-        // 时间字段取出后的默认时间格式
-        'datetime_format' => 'Y-m-d H:i:s',
-        // 是否需要进行SQL性能分析
-        'sql_explain'     => false,
-        // 查询对象
-        'query'           => '\\think\\db\\Query',
-    ],
-
-    //分页配置
-    'paginate' => [
-        'type'      => 'bootstrap',
-        'var_page'  => 'page',
-        'list_rows' => 15,
-    ],
-
-    //控制台配置
-    'console'  => [
-        'name'    => 'Think Console',
-        'version' => '0.1',
-        'user'    => null,
-    ],
-];

+ 0 - 691
thinkphp/helper.php

@@ -1,691 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-//------------------------
-// ThinkPHP 助手函数
-//-------------------------
-
-use think\Container;
-use think\Db;
-use think\exception\HttpException;
-use think\exception\HttpResponseException;
-use think\facade\Cache;
-use think\facade\Config;
-use think\facade\Cookie;
-use think\facade\Debug;
-use think\facade\Env;
-use think\facade\Hook;
-use think\facade\Lang;
-use think\facade\Log;
-use think\facade\Request;
-use think\facade\Route;
-use think\facade\Session;
-use think\facade\Url;
-use think\Response;
-use think\route\RuleItem;
-
-if (!function_exists('abort')) {
-    /**
-     * 抛出HTTP异常
-     * @param integer|Response      $code 状态码 或者 Response对象实例
-     * @param string                $message 错误信息
-     * @param array                 $header 参数
-     */
-    function abort($code, $message = null, $header = [])
-    {
-        if ($code instanceof Response) {
-            throw new HttpResponseException($code);
-        } else {
-            throw new HttpException($code, $message, null, $header);
-        }
-    }
-}
-
-if (!function_exists('action')) {
-    /**
-     * 调用模块的操作方法 参数格式 [模块/控制器/]操作
-     * @param string        $url 调用地址
-     * @param string|array  $vars 调用参数 支持字符串和数组
-     * @param string        $layer 要调用的控制层名称
-     * @param bool          $appendSuffix 是否添加类名后缀
-     * @return mixed
-     */
-    function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
-    {
-        return app()->action($url, $vars, $layer, $appendSuffix);
-    }
-}
-
-if (!function_exists('app')) {
-    /**
-     * 快速获取容器中的实例 支持依赖注入
-     * @param string    $name 类名或标识 默认获取当前应用实例
-     * @param array     $args 参数
-     * @param bool      $newInstance    是否每次创建新的实例
-     * @return object
-     */
-    function app($name = 'think\App', $args = [], $newInstance = false)
-    {
-        return Container::get($name, $args, $newInstance);
-    }
-}
-
-if (!function_exists('behavior')) {
-    /**
-     * 执行某个行为(run方法) 支持依赖注入
-     * @param mixed $behavior   行为类名或者别名
-     * @param mixed $args       参数
-     * @return mixed
-     */
-    function behavior($behavior, $args = null)
-    {
-        return Hook::exec($behavior, $args);
-    }
-}
-
-if (!function_exists('bind')) {
-    /**
-     * 绑定一个类到容器
-     * @access public
-     * @param string  $abstract    类标识、接口
-     * @param mixed   $concrete    要绑定的类、闭包或者实例
-     * @return Container
-     */
-    function bind($abstract, $concrete = null)
-    {
-        return Container::getInstance()->bind($abstract, $concrete);
-    }
-}
-
-if (!function_exists('cache')) {
-    /**
-     * 缓存管理
-     * @param mixed     $name 缓存名称,如果为数组表示进行缓存设置
-     * @param mixed     $value 缓存值
-     * @param mixed     $options 缓存参数
-     * @param string    $tag 缓存标签
-     * @return mixed
-     */
-    function cache($name, $value = '', $options = null, $tag = null)
-    {
-        if (is_array($options)) {
-            // 缓存操作的同时初始化
-            Cache::connect($options);
-        } elseif (is_array($name)) {
-            // 缓存初始化
-            return Cache::connect($name);
-        }
-
-        if ('' === $value) {
-            // 获取缓存
-            return 0 === strpos($name, '?') ? Cache::has(substr($name, 1)) : Cache::get($name);
-        } elseif (is_null($value)) {
-            // 删除缓存
-            return Cache::rm($name);
-        } else {
-            // 缓存数据
-            if (is_array($options)) {
-                $expire = isset($options['expire']) ? $options['expire'] : null; //修复查询缓存无法设置过期时间
-            } else {
-                $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间
-            }
-
-            if (is_null($tag)) {
-                return Cache::set($name, $value, $expire);
-            } else {
-                return Cache::tag($tag)->set($name, $value, $expire);
-            }
-        }
-    }
-}
-
-if (!function_exists('call')) {
-    /**
-     * 调用反射执行callable 支持依赖注入
-     * @param mixed $callable   支持闭包等callable写法
-     * @param array $args       参数
-     * @return mixed
-     */
-    function call($callable, $args = [])
-    {
-        return Container::getInstance()->invoke($callable, $args);
-    }
-}
-
-if (!function_exists('class_basename')) {
-    /**
-     * 获取类名(不包含命名空间)
-     *
-     * @param  string|object $class
-     * @return string
-     */
-    function class_basename($class)
-    {
-        $class = is_object($class) ? get_class($class) : $class;
-        return basename(str_replace('\\', '/', $class));
-    }
-}
-
-if (!function_exists('class_uses_recursive')) {
-    /**
-     *获取一个类里所有用到的trait,包括父类的
-     *
-     * @param $class
-     * @return array
-     */
-    function class_uses_recursive($class)
-    {
-        if (is_object($class)) {
-            $class = get_class($class);
-        }
-
-        $results = [];
-        $classes = array_merge([$class => $class], class_parents($class));
-        foreach ($classes as $class) {
-            $results += trait_uses_recursive($class);
-        }
-
-        return array_unique($results);
-    }
-}
-
-if (!function_exists('config')) {
-    /**
-     * 获取和设置配置参数
-     * @param string|array  $name 参数名
-     * @param mixed         $value 参数值
-     * @return mixed
-     */
-    function config($name = '', $value = null)
-    {
-        if (is_null($value) && is_string($name)) {
-            if ('.' == substr($name, -1)) {
-                return Config::pull(substr($name, 0, -1));
-            }
-
-            return 0 === strpos($name, '?') ? Config::has(substr($name, 1)) : Config::get($name);
-        } else {
-            return Config::set($name, $value);
-        }
-    }
-}
-
-if (!function_exists('container')) {
-    /**
-     * 获取容器对象实例
-     * @return Container
-     */
-    function container()
-    {
-        return Container::getInstance();
-    }
-}
-
-if (!function_exists('controller')) {
-    /**
-     * 实例化控制器 格式:[模块/]控制器
-     * @param string    $name 资源地址
-     * @param string    $layer 控制层名称
-     * @param bool      $appendSuffix 是否添加类名后缀
-     * @return \think\Controller
-     */
-    function controller($name, $layer = 'controller', $appendSuffix = false)
-    {
-        return app()->controller($name, $layer, $appendSuffix);
-    }
-}
-
-if (!function_exists('cookie')) {
-    /**
-     * Cookie管理
-     * @param string|array  $name cookie名称,如果为数组表示进行cookie设置
-     * @param mixed         $value cookie值
-     * @param mixed         $option 参数
-     * @return mixed
-     */
-    function cookie($name, $value = '', $option = null)
-    {
-        if (is_array($name)) {
-            // 初始化
-            Cookie::init($name);
-        } elseif (is_null($name)) {
-            // 清除
-            Cookie::clear($value);
-        } elseif ('' === $value) {
-            // 获取
-            return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1), $option) : Cookie::get($name);
-        } elseif (is_null($value)) {
-            // 删除
-            return Cookie::delete($name);
-        } else {
-            // 设置
-            return Cookie::set($name, $value, $option);
-        }
-    }
-}
-
-if (!function_exists('db')) {
-    /**
-     * 实例化数据库类
-     * @param string        $name 操作的数据表名称(不含前缀)
-     * @param array|string  $config 数据库配置参数
-     * @param bool          $force 是否强制重新连接
-     * @return \think\db\Query
-     */
-    function db($name = '', $config = [], $force = true)
-    {
-        return Db::connect($config, $force)->name($name);
-    }
-}
-
-if (!function_exists('debug')) {
-    /**
-     * 记录时间(微秒)和内存使用情况
-     * @param string            $start 开始标签
-     * @param string            $end 结束标签
-     * @param integer|string    $dec 小数位 如果是m 表示统计内存占用
-     * @return mixed
-     */
-    function debug($start, $end = '', $dec = 6)
-    {
-        if ('' == $end) {
-            Debug::remark($start);
-        } else {
-            return 'm' == $dec ? Debug::getRangeMem($start, $end) : Debug::getRangeTime($start, $end, $dec);
-        }
-    }
-}
-
-if (!function_exists('dump')) {
-    /**
-     * 浏览器友好的变量输出
-     * @param mixed     $var 变量
-     * @param boolean   $echo 是否输出 默认为true 如果为false 则返回输出字符串
-     * @param string    $label 标签 默认为空
-     * @return void|string
-     */
-    function dump($var, $echo = true, $label = null)
-    {
-        return Debug::dump($var, $echo, $label);
-    }
-}
-
-if (!function_exists('env')) {
-    /**
-     * 获取环境变量值
-     * @access public
-     * @param  string    $name 环境变量名(支持二级 .号分割)
-     * @param  string    $default  默认值
-     * @return mixed
-     */
-    function env($name = null, $default = null)
-    {
-        return Env::get($name, $default);
-    }
-}
-
-if (!function_exists('exception')) {
-    /**
-     * 抛出异常处理
-     *
-     * @param string    $msg  异常消息
-     * @param integer   $code 异常代码 默认为0
-     * @param string    $exception 异常类
-     *
-     * @throws Exception
-     */
-    function exception($msg, $code = 0, $exception = '')
-    {
-        $e = $exception ?: '\think\Exception';
-        throw new $e($msg, $code);
-    }
-}
-
-if (!function_exists('halt')) {
-    /**
-     * 调试变量并且中断输出
-     * @param mixed      $var 调试变量或者信息
-     */
-    function halt($var)
-    {
-        dump($var);
-
-        throw new HttpResponseException(new Response);
-    }
-}
-
-if (!function_exists('input')) {
-    /**
-     * 获取输入数据 支持默认值和过滤
-     * @param string    $key 获取的变量名
-     * @param mixed     $default 默认值
-     * @param string    $filter 过滤方法
-     * @return mixed
-     */
-    function input($key = '', $default = null, $filter = '')
-    {
-        if (0 === strpos($key, '?')) {
-            $key = substr($key, 1);
-            $has = true;
-        }
-
-        if ($pos = strpos($key, '.')) {
-            // 指定参数来源
-            $method = substr($key, 0, $pos);
-            if (in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
-                $key = substr($key, $pos + 1);
-            } else {
-                $method = 'param';
-            }
-        } else {
-            // 默认为自动判断
-            $method = 'param';
-        }
-
-        if (isset($has)) {
-            return request()->has($key, $method, $default);
-        } else {
-            return request()->$method($key, $default, $filter);
-        }
-    }
-}
-
-if (!function_exists('json')) {
-    /**
-     * 获取\think\response\Json对象实例
-     * @param mixed   $data 返回的数据
-     * @param integer $code 状态码
-     * @param array   $header 头部
-     * @param array   $options 参数
-     * @return \think\response\Json
-     */
-    function json($data = [], $code = 200, $header = [], $options = [])
-    {
-        return Response::create($data, 'json', $code, $header, $options);
-    }
-}
-
-if (!function_exists('jsonp')) {
-    /**
-     * 获取\think\response\Jsonp对象实例
-     * @param mixed   $data    返回的数据
-     * @param integer $code    状态码
-     * @param array   $header 头部
-     * @param array   $options 参数
-     * @return \think\response\Jsonp
-     */
-    function jsonp($data = [], $code = 200, $header = [], $options = [])
-    {
-        return Response::create($data, 'jsonp', $code, $header, $options);
-    }
-}
-
-if (!function_exists('lang')) {
-    /**
-     * 获取语言变量值
-     * @param string    $name 语言变量名
-     * @param array     $vars 动态变量值
-     * @param string    $lang 语言
-     * @return mixed
-     */
-    function lang($name, $vars = [], $lang = '')
-    {
-        return Lang::get($name, $vars, $lang);
-    }
-}
-
-if (!function_exists('model')) {
-    /**
-     * 实例化Model
-     * @param string    $name Model名称
-     * @param string    $layer 业务层名称
-     * @param bool      $appendSuffix 是否添加类名后缀
-     * @return \think\Model
-     */
-    function model($name = '', $layer = 'model', $appendSuffix = false)
-    {
-        return app()->model($name, $layer, $appendSuffix);
-    }
-}
-
-if (!function_exists('parse_name')) {
-    /**
-     * 字符串命名风格转换
-     * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
-     * @param string  $name 字符串
-     * @param integer $type 转换类型
-     * @param bool    $ucfirst 首字母是否大写(驼峰规则)
-     * @return string
-     */
-    function parse_name($name, $type = 0, $ucfirst = true)
-    {
-        if ($type) {
-            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
-                return strtoupper($match[1]);
-            }, $name);
-
-            return $ucfirst ? ucfirst($name) : lcfirst($name);
-        } else {
-            return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
-        }
-    }
-}
-
-if (!function_exists('redirect')) {
-    /**
-     * 获取\think\response\Redirect对象实例
-     * @param mixed         $url 重定向地址 支持Url::build方法的地址
-     * @param array|integer $params 额外参数
-     * @param integer       $code 状态码
-     * @return \think\response\Redirect
-     */
-    function redirect($url = [], $params = [], $code = 302)
-    {
-        if (is_integer($params)) {
-            $code   = $params;
-            $params = [];
-        }
-
-        return Response::create($url, 'redirect', $code)->params($params);
-    }
-}
-
-if (!function_exists('request')) {
-    /**
-     * 获取当前Request对象实例
-     * @return Request
-     */
-    function request()
-    {
-        return app('request');
-    }
-}
-
-if (!function_exists('response')) {
-    /**
-     * 创建普通 Response 对象实例
-     * @param mixed      $data   输出数据
-     * @param int|string $code   状态码
-     * @param array      $header 头信息
-     * @param string     $type
-     * @return Response
-     */
-    function response($data = [], $code = 200, $header = [], $type = 'html')
-    {
-        return Response::create($data, $type, $code, $header);
-    }
-}
-
-if (!function_exists('route')) {
-    /**
-     * 路由注册
-     * @param  string    $rule       路由规则
-     * @param  mixed     $route      路由地址
-     * @param  array     $option     路由参数
-     * @param  array     $pattern    变量规则
-     * @return RuleItem
-     */
-    function route($rule, $route, $option = [], $pattern = [])
-    {
-        return Route::rule($rule, $route, '*', $option, $pattern);
-    }
-}
-
-if (!function_exists('session')) {
-    /**
-     * Session管理
-     * @param string|array  $name session名称,如果为数组表示进行session设置
-     * @param mixed         $value session值
-     * @param string        $prefix 前缀
-     * @return mixed
-     */
-    function session($name, $value = '', $prefix = null)
-    {
-        if (is_array($name)) {
-            // 初始化
-            Session::init($name);
-        } elseif (is_null($name)) {
-            // 清除
-            Session::clear($value);
-        } elseif ('' === $value) {
-            // 判断或获取
-            return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix);
-        } elseif (is_null($value)) {
-            // 删除
-            return Session::delete($name, $prefix);
-        } else {
-            // 设置
-            return Session::set($name, $value, $prefix);
-        }
-    }
-}
-
-if (!function_exists('token')) {
-    /**
-     * 生成表单令牌
-     * @param string $name 令牌名称
-     * @param mixed  $type 令牌生成方法
-     * @return string
-     */
-    function token($name = '__token__', $type = 'md5')
-    {
-        $token = Request::token($name, $type);
-
-        return '<input type="hidden" name="' . $name . '" value="' . $token . '" />';
-    }
-}
-
-if (!function_exists('trace')) {
-    /**
-     * 记录日志信息
-     * @param mixed     $log log信息 支持字符串和数组
-     * @param string    $level 日志级别
-     * @return array|void
-     */
-    function trace($log = '[think]', $level = 'log')
-    {
-        if ('[think]' === $log) {
-            return Log::getLog();
-        } else {
-            Log::record($log, $level);
-        }
-    }
-}
-
-if (!function_exists('trait_uses_recursive')) {
-    /**
-     * 获取一个trait里所有引用到的trait
-     *
-     * @param  string $trait
-     * @return array
-     */
-    function trait_uses_recursive($trait)
-    {
-        $traits = class_uses($trait);
-        foreach ($traits as $trait) {
-            $traits += trait_uses_recursive($trait);
-        }
-
-        return $traits;
-    }
-}
-
-if (!function_exists('url')) {
-    /**
-     * Url生成
-     * @param string        $url 路由地址
-     * @param string|array  $vars 变量
-     * @param bool|string   $suffix 生成的URL后缀
-     * @param bool|string   $domain 域名
-     * @return string
-     */
-    function url($url = '', $vars = '', $suffix = true, $domain = false)
-    {
-        return Url::build($url, $vars, $suffix, $domain);
-    }
-}
-
-if (!function_exists('validate')) {
-    /**
-     * 实例化验证器
-     * @param string    $name 验证器名称
-     * @param string    $layer 业务层名称
-     * @param bool      $appendSuffix 是否添加类名后缀
-     * @return \think\Validate
-     */
-    function validate($name = '', $layer = 'validate', $appendSuffix = false)
-    {
-        return app()->validate($name, $layer, $appendSuffix);
-    }
-}
-
-if (!function_exists('view')) {
-    /**
-     * 渲染模板输出
-     * @param string    $template 模板文件
-     * @param array     $vars 模板变量
-     * @param integer   $code 状态码
-     * @param callable  $filter 内容过滤
-     * @return \think\response\View
-     */
-    function view($template = '', $vars = [], $code = 200, $filter = null)
-    {
-        return Response::create($template, 'view', $code)->assign($vars)->filter($filter);
-    }
-}
-
-if (!function_exists('widget')) {
-    /**
-     * 渲染输出Widget
-     * @param string    $name Widget名称
-     * @param array     $data 传入的参数
-     * @return mixed
-     */
-    function widget($name, $data = [])
-    {
-        return app()->action($name, $data, 'widget');
-    }
-}
-
-if (!function_exists('xml')) {
-    /**
-     * 获取\think\response\Xml对象实例
-     * @param mixed   $data    返回的数据
-     * @param integer $code    状态码
-     * @param array   $header  头部
-     * @param array   $options 参数
-     * @return \think\response\Xml
-     */
-    function xml($data = [], $code = 200, $header = [], $options = [])
-    {
-        return Response::create($data, 'xml', $code, $header, $options);
-    }
-}

+ 0 - 141
thinkphp/lang/zh-cn.php

@@ -1,141 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-// 核心中文语言包
-return [
-    // 系统错误提示
-    'Undefined variable'                                        => '未定义变量',
-    'Undefined index'                                           => '未定义数组索引',
-    'Undefined offset'                                          => '未定义数组下标',
-    'Parse error'                                               => '语法解析错误',
-    'Type error'                                                => '类型错误',
-    'Fatal error'                                               => '致命错误',
-    'syntax error'                                              => '语法错误',
-
-    // 框架核心错误提示
-    'dispatch type not support'                                 => '不支持的调度类型',
-    'method param miss'                                         => '方法参数错误',
-    'method not exists'                                         => '方法不存在',
-    'function not exists'                                       => '函数不存在',
-    'module not exists'                                         => '模块不存在',
-    'controller not exists'                                     => '控制器不存在',
-    'class not exists'                                          => '类不存在',
-    'property not exists'                                       => '类的属性不存在',
-    'template not exists'                                       => '模板文件不存在',
-    'illegal controller name'                                   => '非法的控制器名称',
-    'illegal action name'                                       => '非法的操作名称',
-    'url suffix deny'                                           => '禁止的URL后缀访问',
-    'Route Not Found'                                           => '当前访问路由未定义或不匹配',
-    'Undefined db type'                                         => '未定义数据库类型',
-    'variable type error'                                       => '变量类型错误',
-    'PSR-4 error'                                               => 'PSR-4 规范错误',
-    'not support total'                                         => '简洁模式下不能获取数据总数',
-    'not support last'                                          => '简洁模式下不能获取最后一页',
-    'error session handler'                                     => '错误的SESSION处理器类',
-    'not allow php tag'                                         => '模板不允许使用PHP语法',
-    'not support'                                               => '不支持',
-    'redisd master'                                             => 'Redisd 主服务器错误',
-    'redisd slave'                                              => 'Redisd 从服务器错误',
-    'must run at sae'                                           => '必须在SAE运行',
-    'memcache init error'                                       => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务',
-    'KVDB init error'                                           => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务',
-    'fields not exists'                                         => '数据表字段不存在',
-    'where express error'                                       => '查询表达式错误',
-    'no data to update'                                         => '没有任何数据需要更新',
-    'miss data to insert'                                       => '缺少需要写入的数据',
-    'miss complex primary data'                                 => '缺少复合主键数据',
-    'miss update condition'                                     => '缺少更新条件',
-    'model data Not Found'                                      => '模型数据不存在',
-    'table data not Found'                                      => '表数据不存在',
-    'delete without condition'                                  => '没有条件不会执行删除操作',
-    'miss relation data'                                        => '缺少关联表数据',
-    'tag attr must'                                             => '模板标签属性必须',
-    'tag error'                                                 => '模板标签错误',
-    'cache write error'                                         => '缓存写入失败',
-    'sae mc write error'                                        => 'SAE mc 写入错误',
-    'route name not exists'                                     => '路由标识不存在(或参数不够)',
-    'invalid request'                                           => '非法请求',
-    'bind attr has exists'                                      => '模型的属性已经存在',
-    'relation data not exists'                                  => '关联数据不存在',
-    'relation not support'                                      => '关联不支持',
-    'chunk not support order'                                   => 'Chunk不支持调用order方法',
-    'route pattern error'                                       => '路由变量规则定义错误',
-    'route behavior will not support'                           => '路由行为废弃(使用中间件替代)',
-    'closure not support cache(true)'                           => '使用闭包查询不支持cache(true),请指定缓存Key',
-
-    // 上传错误信息
-    'unknown upload error'                                      => '未知上传错误!',
-    'file write error'                                          => '文件写入失败!',
-    'upload temp dir not found'                                 => '找不到临时文件夹!',
-    'no file to uploaded'                                       => '没有文件被上传!',
-    'only the portion of file is uploaded'                      => '文件只有部分被上传!',
-    'upload File size exceeds the maximum value'                => '上传文件大小超过了最大值!',
-    'upload write error'                                        => '文件上传保存错误!',
-    'has the same filename: {:filename}'                        => '存在同名文件:{:filename}',
-    'upload illegal files'                                      => '非法上传文件',
-    'illegal image files'                                       => '非法图片文件',
-    'extensions to upload is not allowed'                       => '上传文件后缀不允许',
-    'mimetype to upload is not allowed'                         => '上传文件MIME类型不允许!',
-    '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必须',
-    ':attribute must be numeric'                                => ':attribute必须是数字',
-    ':attribute must be integer'                                => ':attribute必须是整数',
-    ':attribute must be float'                                  => ':attribute必须是浮点数',
-    ':attribute must be bool'                                   => ':attribute必须是布尔值',
-    ':attribute not a valid email address'                      => ':attribute格式不符',
-    ':attribute not a valid mobile'                             => ':attribute格式不符',
-    ':attribute must be a array'                                => ':attribute必须是数组',
-    ':attribute must be yes,on or 1'                            => ':attribute必须是yes、on或者1',
-    ':attribute not a valid datetime'                           => ':attribute不是一个有效的日期或时间格式',
-    ':attribute not a valid file'                               => ':attribute不是有效的上传文件',
-    ':attribute not a valid image'                              => ':attribute不是有效的图像文件',
-    ':attribute must be alpha'                                  => ':attribute只能是字母',
-    ':attribute must be alpha-numeric'                          => ':attribute只能是字母和数字',
-    ':attribute must be alpha-numeric, dash, underscore'        => ':attribute只能是字母、数字和下划线_及破折号-',
-    ':attribute not a valid domain or ip'                       => ':attribute不是有效的域名或者IP',
-    ':attribute must be chinese'                                => ':attribute只能是汉字',
-    ':attribute must be chinese or alpha'                       => ':attribute只能是汉字、字母',
-    ':attribute must be chinese,alpha-numeric'                  => ':attribute只能是汉字、字母和数字',
-    ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-',
-    ':attribute not a valid url'                                => ':attribute不是有效的URL地址',
-    ':attribute not a valid ip'                                 => ':attribute不是有效的IP地址',
-    ':attribute must be dateFormat of :rule'                    => ':attribute必须使用日期格式 :rule',
-    ':attribute must be in :rule'                               => ':attribute必须在 :rule 范围内',
-    ':attribute be notin :rule'                                 => ':attribute不能在 :rule 范围内',
-    ':attribute must between :1 - :2'                           => ':attribute只能在 :1 - :2 之间',
-    ':attribute not between :1 - :2'                            => ':attribute不能在 :1 - :2 之间',
-    'size of :attribute must be :rule'                          => ':attribute长度不符合要求 :rule',
-    'max size of :attribute must be :rule'                      => ':attribute长度不能超过 :rule',
-    'min size of :attribute must be :rule'                      => ':attribute长度不能小于 :rule',
-    ':attribute cannot be less than :rule'                      => ':attribute日期不能小于 :rule',
-    ':attribute cannot exceed :rule'                            => ':attribute日期不能超过 :rule',
-    ':attribute not within :rule'                               => '不在有效期内 :rule',
-    'access IP is not allowed'                                  => '不允许的IP访问',
-    'access IP denied'                                          => '禁止的IP访问',
-    ':attribute out of accord with :2'                          => ':attribute和确认字段:2不一致',
-    ':attribute cannot be same with :2'                         => ':attribute和比较字段:2不能相同',
-    ':attribute must greater than or equal :rule'               => ':attribute必须大于等于 :rule',
-    ':attribute must greater than :rule'                        => ':attribute必须大于 :rule',
-    ':attribute must less than or equal :rule'                  => ':attribute必须小于等于 :rule',
-    ':attribute must less than :rule'                           => ':attribute必须小于 :rule',
-    ':attribute must equal :rule'                               => ':attribute必须等于 :rule',
-    ':attribute has exists'                                     => ':attribute已存在',
-    ':attribute not conform to the rules'                       => ':attribute不符合指定规则',
-    'invalid Request method'                                    => '无效的请求类型',
-    'invalid token'                                             => '令牌数据无效',
-    'not conform to the rules'                                  => '规则错误',
-];

+ 0 - 916
thinkphp/library/think/App.php

@@ -1,916 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ClassNotFoundException;
-use think\exception\HttpResponseException;
-use think\route\Dispatch;
-
-/**
- * App 应用管理
- */
-class App implements \ArrayAccess
-{
-    const VERSION = '5.1.9';
-
-    /**
-     * 当前模块路径
-     * @var string
-     */
-    protected $modulePath;
-
-    /**
-     * 应用调试模式
-     * @var bool
-     */
-    protected $debug = true;
-
-    /**
-     * 应用开始时间
-     * @var float
-     */
-    protected $beginTime;
-
-    /**
-     * 应用内存初始占用
-     * @var integer
-     */
-    protected $beginMem;
-
-    /**
-     * 应用类库命名空间
-     * @var string
-     */
-    protected $namespace = 'app';
-
-    /**
-     * 应用类库后缀
-     * @var bool
-     */
-    protected $suffix = false;
-
-    /**
-     * 严格路由检测
-     * @var bool
-     */
-    protected $routeMust;
-
-    /**
-     * 应用类库目录
-     * @var string
-     */
-    protected $appPath;
-
-    /**
-     * 框架目录
-     * @var string
-     */
-    protected $thinkPath;
-
-    /**
-     * 应用根目录
-     * @var string
-     */
-    protected $rootPath;
-
-    /**
-     * 运行时目录
-     * @var string
-     */
-    protected $runtimePath;
-
-    /**
-     * 配置目录
-     * @var string
-     */
-    protected $configPath;
-
-    /**
-     * 路由目录
-     * @var string
-     */
-    protected $routePath;
-
-    /**
-     * 配置后缀
-     * @var string
-     */
-    protected $configExt;
-
-    /**
-     * 应用调度实例
-     * @var Dispatch
-     */
-    protected $dispatch;
-
-    /**
-     * 容器对象实例
-     * @var Container
-     */
-    protected $container;
-
-    /**
-     * 绑定模块(控制器)
-     * @var string
-     */
-    protected $bind;
-
-    public function __construct($appPath = '')
-    {
-        $this->appPath   = $appPath ? realpath($appPath) . DIRECTORY_SEPARATOR : $this->getAppPath();
-        $this->container = Container::getInstance();
-    }
-
-    /**
-     * 绑定模块或者控制器
-     * @access public
-     * @param  string $bind
-     * @return $this
-     */
-    public function bind($bind)
-    {
-        $this->bind = $bind;
-        return $this;
-    }
-
-    /**
-     * 设置应用类库目录
-     * @access public
-     * @param  string $path 路径
-     * @return $this
-     */
-    public function path($path)
-    {
-        $this->appPath = $path;
-        return $this;
-    }
-
-    /**
-     * 初始化应用
-     * @access public
-     * @return void
-     */
-    public function initialize()
-    {
-        $this->beginTime   = microtime(true);
-        $this->beginMem    = memory_get_usage();
-        $this->thinkPath   = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR;
-        $this->rootPath    = dirname($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->env->set([
-            'think_path'   => $this->thinkPath,
-            'root_path'    => $this->rootPath,
-            'app_path'     => $this->appPath,
-            '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,
-        ]);
-
-        // 加载环境变量配置文件
-        if (is_file($this->rootPath . '.env')) {
-            $this->env->load($this->rootPath . '.env');
-        }
-
-        $this->namespace = $this->env->get('app_namespace', $this->namespace);
-        $this->env->set('app_namespace', $this->namespace);
-
-        // 注册应用命名空间
-        Loader::addNamespace($this->namespace, $this->appPath);
-
-        $this->configExt = $this->env->get('config_ext', '.php');
-
-        // 初始化应用
-        $this->init();
-
-        // 开启类名后缀
-        $this->suffix = $this->config('app.class_suffix');
-
-        // 应用调试模式
-        $this->debug = $this->env->get('app_debug', $this->config('app.app_debug'));
-        $this->env->set('app_debug', $this->debug);
-
-        if (!$this->debug) {
-            ini_set('display_errors', 'Off');
-        } elseif (PHP_SAPI != 'cli') {
-            //重新申请一块比较大的buffer
-            if (ob_get_level() > 0) {
-                $output = ob_get_clean();
-            }
-            ob_start();
-            if (!empty($output)) {
-                echo $output;
-            }
-        }
-
-        // 注册根命名空间
-        if (!empty($this->config('app.root_namespace'))) {
-            Loader::addNamespace($this->config('app.root_namespace'));
-        }
-
-        // 注册类库别名
-        Loader::addClassAlias($this->config->pull('alias'));
-
-        // 设置系统时区
-        date_default_timezone_set($this->config('app.default_timezone'));
-
-        // 读取语言包
-        $this->loadLangPack();
-
-        // 监听app_init
-        $this->hook->listen('app_init');
-    }
-
-    /**
-     * 初始化应用或模块
-     * @access public
-     * @param  string $module 模块名
-     * @return void
-     */
-    public function init($module = '')
-    {
-        // 定位模块目录
-        $module = $module ? $module . DIRECTORY_SEPARATOR : '';
-        $path   = $this->appPath . $module;
-
-        // 加载初始化文件
-        if (is_file($path . 'init.php')) {
-            include $path . 'init.php';
-        } elseif (is_file($this->runtimePath . $module . 'init.php')) {
-            include $this->runtimePath . $module . 'init.php';
-        } else {
-            // 加载行为扩展文件
-            if (is_file($path . 'tags.php')) {
-                $tags = include $path . 'tags.php';
-                if (is_array($tags)) {
-                    $this->hook->import($tags);
-                }
-            }
-
-            // 加载公共文件
-            if (is_file($path . 'common.php')) {
-                include $path . 'common.php';
-            }
-
-            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);
-                }
-            }
-
-            // 自动读取配置文件
-            if (is_dir($path . 'config')) {
-                $dir = $path . 'config';
-            } elseif (is_dir($this->configPath . $module)) {
-                $dir = $this->configPath . $module;
-            }
-
-            $files = isset($dir) ? scandir($dir) : [];
-
-            foreach ($files as $file) {
-                if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $this->configExt) {
-                    $filename = $dir . DIRECTORY_SEPARATOR . $file;
-                    $this->config->load($filename, pathinfo($file, PATHINFO_FILENAME));
-                }
-            }
-        }
-
-        $this->request->filter($this->config('app.default_filter'));
-    }
-
-    /**
-     * 执行应用程序
-     * @access public
-     * @return Response
-     * @throws Exception
-     */
-    public function run()
-    {
-        try {
-            // 初始化应用
-            $this->initialize();
-
-            if ($this->bind) {
-                // 模块/控制器绑定
-                $this->route->bind($this->bind);
-            } elseif ($this->config('app.auto_bind_module')) {
-                // 入口自动绑定
-                $name = pathinfo($this->request->baseFile(), PATHINFO_FILENAME);
-                if ($name && 'index' != $name && is_dir($this->appPath . $name)) {
-                    $this->route->bind($name);
-                }
-            }
-
-            // 监听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'));
-
-                $dispatch = $this->routeCheck();
-            }
-
-            // 记录当前调度信息
-            $this->request->dispatch($dispatch);
-
-            // 记录路由和请求信息
-            if ($this->debug) {
-                $this->log('[ ROUTE ] ' . var_export($this->request->routeInfo(), true));
-                $this->log('[ HEADER ] ' . var_export($this->request->header(), true));
-                $this->log('[ PARAM ] ' . var_export($this->request->param(), true));
-            }
-
-            // 监听app_begin
-            $this->hook->listen('app_begin');
-
-            // 请求缓存检查
-            $this->request->cache(
-                $this->config('app.request_cache'),
-                $this->config('app.request_cache_expire'),
-                $this->config('app.request_cache_except')
-            );
-
-            $data = null;
-        } catch (HttpResponseException $exception) {
-            $dispatch = null;
-            $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();
-                }
-            }
-
-            // 输出数据到客户端
-            if ($data instanceof Response) {
-                $response = $data;
-            } elseif (!is_null($data)) {
-                // 默认自动识别响应输出类型
-                $isAjax = $request->isAjax();
-                $type   = $isAjax ? $this->config('app.default_ajax_return') : $this->config('app.default_return_type');
-
-                $response = Response::create($data, $type);
-            } else {
-                $response = Response::create();
-            }
-            return $response;
-        });
-
-        $response = $this->middleware->dispatch($this->request);
-
-        // 监听app_end
-        $this->hook->listen('app_end', $response);
-
-        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
-     * @param  Dispatch  $dispatch 调度信息
-     * @return $this
-     */
-    public function dispatch(Dispatch $dispatch)
-    {
-        $this->dispatch = $dispatch;
-        return $this;
-    }
-
-    /**
-     * 记录调试信息
-     * @access public
-     * @param  mixed  $msg  调试信息
-     * @param  string $type 信息类型
-     * @return void
-     */
-    public function log($msg, $type = 'info')
-    {
-        $this->debug && $this->log->record($msg, $type);
-    }
-
-    /**
-     * 获取配置参数 为空则获取所有配置
-     * @access public
-     * @param  string    $name 配置参数名(支持二级配置 .号分割)
-     * @return mixed
-     */
-    public function config($name = '')
-    {
-        return $this->config->get($name);
-    }
-
-    /**
-     * URL路由检测(根据PATH_INFO)
-     * @access public
-     * @return Dispatch
-     */
-    public function routeCheck()
-    {
-        $path = $this->request->path();
-        $depr = $this->config('app.pathinfo_depr');
-
-        // 路由检测
-        $files = scandir($this->routePath);
-        foreach ($files as $file) {
-            if (strpos($file, '.php')) {
-                $filename = $this->routePath . $file;
-                // 导入路由配置
-                $rules = include $filename;
-                if (is_array($rules)) {
-                    $this->route->import($rules);
-                }
-            }
-        }
-
-        if ($this->config('app.route_annotation')) {
-            // 自动生成路由定义
-            if ($this->debug) {
-                $this->build->buildRoute($this->config('app.controller_suffix'));
-            }
-
-            $filename = $this->runtimePath . 'build_route.php';
-
-            if (is_file($filename)) {
-                include $filename;
-            }
-        }
-
-        if (is_file($this->runtimePath . 'rule_regex.php')) {
-            $this->route->setRuleRegexs(include $this->runtimePath . 'rule_regex.php');
-        }
-
-        // 是否强制路由模式
-        $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');
-
-        // 路由检测 返回一个Dispatch对象
-        return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match'));
-    }
-
-    /**
-     * 设置应用的路由检测机制
-     * @access public
-     * @param  bool $must  是否强制检测路由
-     * @return $this
-     */
-    public function routeMust($must = false)
-    {
-        $this->routeMust = $must;
-        return $this;
-    }
-
-    /**
-     * 解析模块和类名
-     * @access protected
-     * @param  string $name         资源地址
-     * @param  string $layer        验证层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @return array
-     */
-    protected function parseModuleAndClass($name, $layer, $appendSuffix)
-    {
-        if (false !== strpos($name, '\\')) {
-            $class  = $name;
-            $module = $this->request->module();
-        } else {
-            if (strpos($name, '/')) {
-                list($module, $name) = explode('/', $name, 2);
-            } else {
-                $module = $this->request->module();
-            }
-
-            $class = $this->parseClass($module, $layer, $name, $appendSuffix);
-        }
-
-        return [$module, $class];
-    }
-
-    /**
-     * 实例化应用类库
-     * @access public
-     * @param  string $name         类名称
-     * @param  string $layer        业务层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $common       公共模块名
-     * @return object
-     * @throws ClassNotFoundException
-     */
-    public function create($name, $layer, $appendSuffix = false, $common = 'common')
-    {
-        $guid = $name . $layer;
-
-        if ($this->__isset($guid)) {
-            return $this->__get($guid);
-        }
-
-        list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix);
-
-        if (class_exists($class)) {
-            $object = $this->__get($class);
-        } else {
-            $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
-            if (class_exists($class)) {
-                $object = $this->__get($class);
-            } else {
-                throw new ClassNotFoundException('class not exists:' . $class, $class);
-            }
-        }
-
-        $this->__set($guid, $class);
-
-        return $object;
-    }
-
-    /**
-     * 实例化(分层)模型
-     * @access public
-     * @param  string $name         Model名称
-     * @param  string $layer        业务层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $common       公共模块名
-     * @return Model
-     * @throws ClassNotFoundException
-     */
-    public function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
-    {
-        return $this->create($name, $layer, $appendSuffix, $common);
-    }
-
-    /**
-     * 实例化(分层)控制器 格式:[模块名/]控制器名
-     * @access public
-     * @param  string $name              资源地址
-     * @param  string $layer             控制层名称
-     * @param  bool   $appendSuffix      是否添加类名后缀
-     * @param  string $empty             空控制器名称
-     * @return object
-     * @throws ClassNotFoundException
-     */
-    public function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
-    {
-        list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix);
-
-        if (class_exists($class)) {
-            return $this->__get($class);
-        } elseif ($empty && class_exists($emptyClass = $this->parseClass($module, $layer, $empty, $appendSuffix))) {
-            return $this->__get($emptyClass);
-        }
-
-        throw new ClassNotFoundException('class not exists:' . $class, $class);
-    }
-
-    /**
-     * 实例化验证类 格式:[模块名/]验证器名
-     * @access public
-     * @param  string $name         资源地址
-     * @param  string $layer        验证层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $common       公共模块名
-     * @return Validate
-     * @throws ClassNotFoundException
-     */
-    public function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')
-    {
-        $name = $name ?: $this->config('default_validate');
-
-        if (empty($name)) {
-            return new Validate;
-        }
-
-        return $this->create($name, $layer, $appendSuffix, $common);
-    }
-
-    /**
-     * 数据库初始化
-     * @access public
-     * @param  mixed         $config 数据库配置
-     * @param  bool|string   $name 连接标识 true 强制重新连接
-     * @return \think\db\Query
-     */
-    public function db($config = [], $name = false)
-    {
-        return Db::connect($config, $name);
-    }
-
-    /**
-     * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
-     * @access public
-     * @param  string       $url          调用地址
-     * @param  string|array $vars         调用参数 支持字符串和数组
-     * @param  string       $layer        要调用的控制层名称
-     * @param  bool         $appendSuffix 是否添加类名后缀
-     * @return mixed
-     * @throws ClassNotFoundException
-     */
-    public function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
-    {
-        $info   = pathinfo($url);
-        $action = $info['basename'];
-        $module = '.' != $info['dirname'] ? $info['dirname'] : $this->request->controller();
-        $class  = $this->controller($module, $layer, $appendSuffix);
-
-        if (is_scalar($vars)) {
-            if (strpos($vars, '=')) {
-                parse_str($vars, $vars);
-            } else {
-                $vars = [$vars];
-            }
-        }
-
-        return $this->container->invokeMethod([$class, $action . $this->config('action_suffix')], $vars);
-    }
-
-    /**
-     * 解析应用类的类名
-     * @access public
-     * @param  string $module 模块名
-     * @param  string $layer  层名 controller model ...
-     * @param  string $name   类名
-     * @param  bool   $appendSuffix
-     * @return string
-     */
-    public function parseClass($module, $layer, $name, $appendSuffix = false)
-    {
-        $name  = str_replace(['/', '.'], '\\', $name);
-        $array = explode('\\', $name);
-        $class = Loader::parseName(array_pop($array), 1) . ($this->suffix || $appendSuffix ? ucfirst($layer) : '');
-        $path  = $array ? implode('\\', $array) . '\\' : '';
-
-        return $this->namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class;
-    }
-
-    /**
-     * 获取框架版本
-     * @access public
-     * @return string
-     */
-    public function version()
-    {
-        return static::VERSION;
-    }
-
-    /**
-     * 是否为调试模式
-     * @access public
-     * @return bool
-     */
-    public function isDebug()
-    {
-        return $this->debug;
-    }
-
-    /**
-     * 获取模块路径
-     * @access public
-     * @return string
-     */
-    public function getModulePath()
-    {
-        return $this->modulePath;
-    }
-
-    /**
-     * 设置模块路径
-     * @access public
-     * @param  string $path 路径
-     * @return void
-     */
-    public function setModulePath($path)
-    {
-        $this->modulePath = $path;
-        $this->env->set('module_path', $path);
-    }
-
-    /**
-     * 获取应用根目录
-     * @access public
-     * @return string
-     */
-    public function getRootPath()
-    {
-        return $this->rootPath;
-    }
-
-    /**
-     * 获取应用类库目录
-     * @access public
-     * @return string
-     */
-    public function getAppPath()
-    {
-        if (is_null($this->appPath)) {
-            $this->appPath = Loader::getRootPath() . 'application' . DIRECTORY_SEPARATOR;
-        }
-
-        return $this->appPath;
-    }
-
-    /**
-     * 获取应用运行时目录
-     * @access public
-     * @return string
-     */
-    public function getRuntimePath()
-    {
-        return $this->runtimePath;
-    }
-
-    /**
-     * 获取核心框架目录
-     * @access public
-     * @return string
-     */
-    public function getThinkPath()
-    {
-        return $this->thinkPath;
-    }
-
-    /**
-     * 获取路由目录
-     * @access public
-     * @return string
-     */
-    public function getRoutePath()
-    {
-        return $this->routePath;
-    }
-
-    /**
-     * 获取应用配置目录
-     * @access public
-     * @return string
-     */
-    public function getConfigPath()
-    {
-        return $this->configPath;
-    }
-
-    /**
-     * 获取配置后缀
-     * @access public
-     * @return string
-     */
-    public function getConfigExt()
-    {
-        return $this->configExt;
-    }
-
-    /**
-     * 获取应用类库命名空间
-     * @access public
-     * @return string
-     */
-    public function getNamespace()
-    {
-        return $this->namespace;
-    }
-
-    /**
-     * 设置应用类库命名空间
-     * @access public
-     * @param  string $namespace 命名空间名称
-     * @return $this
-     */
-    public function setNamespace($namespace)
-    {
-        $this->namespace = $namespace;
-        return $this;
-    }
-
-    /**
-     * 是否启用类库后缀
-     * @access public
-     * @return bool
-     */
-    public function getSuffix()
-    {
-        return $this->suffix;
-    }
-
-    /**
-     * 获取应用开启时间
-     * @access public
-     * @return float
-     */
-    public function getBeginTime()
-    {
-        return $this->beginTime;
-    }
-
-    /**
-     * 获取应用初始内存占用
-     * @access public
-     * @return integer
-     */
-    public function getBeginMem()
-    {
-        return $this->beginMem;
-    }
-
-    /**
-     * 获取容器实例
-     * @access public
-     * @return Container
-     */
-    public function container()
-    {
-        return $this->container;
-    }
-
-    public function __set($name, $value)
-    {
-        $this->container->bind($name, $value);
-    }
-
-    public function __get($name)
-    {
-        return $this->container->make($name);
-    }
-
-    public function __isset($name)
-    {
-        return $this->container->bound($name);
-    }
-
-    public function __unset($name)
-    {
-        $this->container->__unset($name);
-    }
-
-    public function offsetExists($key)
-    {
-        return $this->__isset($key);
-    }
-
-    public function offsetGet($key)
-    {
-        return $this->__get($key);
-    }
-
-    public function offsetSet($key, $value)
-    {
-        $this->__set($key, $value);
-    }
-
-    public function offsetUnset($key)
-    {
-        $this->__unset($key);
-    }
-}

+ 0 - 407
thinkphp/library/think/Build.php

@@ -1,407 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Build
-{
-    /**
-     * 应用对象
-     * @var App
-     */
-    protected $app;
-
-    /**
-     * 应用目录
-     * @var string
-     */
-    protected $basePath;
-
-    public function __construct(App $app)
-    {
-        $this->app      = $app;
-        $this->basePath = $this->app->getAppPath();
-    }
-
-    /**
-     * 根据传入的build资料创建目录和文件
-     * @access public
-     * @param  array  $build build列表
-     * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix 类库后缀
-     * @return void
-     */
-    public function run(array $build = [], $namespace = 'app', $suffix = false)
-    {
-        // 锁定
-        $lockfile = $this->basePath . 'build.lock';
-
-        if (is_writable($lockfile)) {
-            return;
-        } elseif (!touch($lockfile)) {
-            throw new Exception('应用目录[' . $this->basePath . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~', 10006);
-        }
-
-        foreach ($build as $module => $list) {
-            if ('__dir__' == $module) {
-                // 创建目录列表
-                $this->buildDir($list);
-            } elseif ('__file__' == $module) {
-                // 创建文件列表
-                $this->buildFile($list);
-            } else {
-                // 创建模块
-                $this->module($module, $list, $namespace, $suffix);
-            }
-        }
-
-        // 解除锁定
-        unlink($lockfile);
-    }
-
-    /**
-     * 创建目录
-     * @access protected
-     * @param  array $list 目录列表
-     * @return void
-     */
-    protected function buildDir($list)
-    {
-        foreach ($list as $dir) {
-            $this->checkDirBuild($this->basePath . $dir);
-        }
-    }
-
-    /**
-     * 创建文件
-     * @access protected
-     * @param  array $list 文件列表
-     * @return void
-     */
-    protected function buildFile($list)
-    {
-        foreach ($list as $file) {
-            if (!is_dir($this->basePath . dirname($file))) {
-                // 创建目录
-                mkdir($this->basePath . dirname($file), 0755, true);
-            }
-
-            if (!is_file($this->basePath . $file)) {
-                file_put_contents($this->basePath . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : '');
-            }
-        }
-    }
-
-    /**
-     * 创建模块
-     * @access public
-     * @param  string $module 模块名
-     * @param  array  $list build列表
-     * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix 类库后缀
-     * @return void
-     */
-    public function module($module = '', $list = [], $namespace = 'app', $suffix = false)
-    {
-        $module = $module ? $module : '';
-
-        if (!is_dir($this->basePath . $module)) {
-            // 创建模块目录
-            mkdir($this->basePath . $module);
-        }
-
-        if (basename($this->app->getRuntimePath()) != $module) {
-            // 创建配置文件和公共文件
-            $this->buildCommon($module);
-            // 创建模块的默认页面
-            $this->buildHello($module, $namespace, $suffix);
-        }
-
-        if (empty($list)) {
-            // 创建默认的模块目录和文件
-            $list = [
-                '__file__' => ['common.php'],
-                '__dir__'  => ['controller', 'model', 'view', 'config'],
-            ];
-        }
-
-        // 创建子目录和文件
-        foreach ($list as $path => $file) {
-            $modulePath = $this->basePath . $module . DIRECTORY_SEPARATOR;
-            if ('__dir__' == $path) {
-                // 生成子目录
-                foreach ($file as $dir) {
-                    $this->checkDirBuild($modulePath . $dir);
-                }
-            } elseif ('__file__' == $path) {
-                // 生成(空白)文件
-                foreach ($file as $name) {
-                    if (!is_file($modulePath . $name)) {
-                        file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : '');
-                    }
-                }
-            } else {
-                // 生成相关MVC文件
-                foreach ($file as $val) {
-                    $val      = trim($val);
-                    $filename = $modulePath . $path . DIRECTORY_SEPARATOR . $val . ($suffix ? ucfirst($path) : '') . '.php';
-                    $space    = $namespace . '\\' . ($module ? $module . '\\' : '') . $path;
-                    $class    = $val . ($suffix ? ucfirst($path) : '');
-                    switch ($path) {
-                        case 'controller': // 控制器
-                            $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}";
-                            break;
-                        case 'model': // 模型
-                            $content = "<?php\nnamespace {$space};\n\nuse think\Model;\n\nclass {$class} extends Model\n{\n\n}";
-                            break;
-                        case 'view': // 视图
-                            $filename = $modulePath . $path . DIRECTORY_SEPARATOR . $val . '.html';
-                            $this->checkDirBuild(dirname($filename));
-                            $content = '';
-                            break;
-                        default:
-                            // 其他文件
-                            $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}";
-                    }
-
-                    if (!is_file($filename)) {
-                        file_put_contents($filename, $content);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * 根据注释自动生成路由规则
-     * @access public
-     * @param  bool   $suffix 类库后缀
-     * @param  string $layer  控制器层目录名
-     * @return string
-     */
-    public function buildRoute($suffix = false, $layer = '')
-    {
-        $namespace = $this->app->getNameSpace();
-        $modules   = glob($this->basePath . '*', GLOB_ONLYDIR);
-        $content   = '<?php ' . PHP_EOL . '//根据 Annotation 自动生成的路由规则';
-
-        if (!$layer) {
-            $layer = $this->app->config('app.url_controller_layer');
-        }
-
-        foreach ($modules as $module) {
-            $module = basename($module);
-
-            if (in_array($module, $this->app->config('app.deny_module_list'))) {
-                continue;
-            }
-
-            $path = $this->basePath . $module . DIRECTORY_SEPARATOR . $layer . DIRECTORY_SEPARATOR;
-            $content .= $this->buildDirRoute($path, $namespace, $module, $suffix, $layer);
-        }
-
-        $filename = $this->app->getRuntimePath() . 'build_route.php';
-        file_put_contents($filename, $content);
-
-        return $filename;
-    }
-
-    /**
-     * 生成子目录控制器类的路由规则
-     * @access protected
-     * @param  string $path  控制器目录
-     * @param  string $namespace 应用命名空间
-     * @param  string $module 模块
-     * @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)
-    {
-        $content = '';
-        $comment = $class->getDocComment();
-
-        if (false !== strpos($comment, '@route(')) {
-            $comment = $this->parseRouteComment($comment);
-            $route   = $module . '/' . $controller;
-            $comment = preg_replace('/route\(\s?([\'\"][\-\_\/\:\<\>\?\$\[\]\w]+[\'\"])\s?\)/is', 'Route::resourece(\1,\'' . $route . '\')', $comment);
-            $content .= PHP_EOL . $comment;
-        } elseif (false !== strpos($comment, '@alias(')) {
-            $comment = $this->parseRouteComment($comment, '@alias(');
-            $route   = $module . '/' . $controller;
-            $comment = preg_replace('/alias\(\s?([\'\"][\-\_\/\w]+[\'\"])\s?\)/is', 'Route::alias(\1,\'' . $route . '\')', $comment);
-            $content .= PHP_EOL . $comment;
-        }
-
-        $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
-
-        foreach ($methods as $method) {
-            $comment = $this->getMethodRouteComment($module, $controller, $method);
-            if ($comment) {
-                $content .= PHP_EOL . $comment;
-            }
-        }
-
-        return $content;
-    }
-
-    /**
-     * 解析路由注释
-     * @access protected
-     * @param  string $comment
-     * @param  string $tag
-     * @return string
-     */
-    protected function parseRouteComment($comment, $tag = '@route(')
-    {
-        $comment = substr($comment, 3, -2);
-        $comment = explode(PHP_EOL, substr(strstr(trim($comment), $tag), 1));
-        $comment = array_map(function ($item) {return trim(trim($item), ' \t*');}, $comment);
-
-        if (count($comment) > 1) {
-            $key     = array_search('', $comment);
-            $comment = array_slice($comment, 0, false === $key ? 1 : $key);
-        }
-
-        $comment = implode(PHP_EOL . "\t", $comment) . ';';
-
-        if (strpos($comment, '{')) {
-            $comment = preg_replace_callback('/\{\s?.*?\s?\}/s', function ($matches) {
-                return false !== strpos($matches[0], '"') ? '[' . substr(var_export(json_decode($matches[0], true), true), 7, -1) . ']' : $matches[0];
-            }, $comment);
-        }
-        return $comment;
-    }
-
-    /**
-     * 获取方法的路由注释
-     * @access protected
-     * @param  string           $module 模块
-     * @param  string           $controller 控制器名
-     * @param  \ReflectMethod   $reflectMethod
-     * @return string|void
-     */
-    protected function getMethodRouteComment($module, $controller, $reflectMethod)
-    {
-        $comment = $reflectMethod->getDocComment();
-
-        if (false !== strpos($comment, '@route(')) {
-            $comment = $this->parseRouteComment($comment);
-            $action  = $reflectMethod->getName();
-
-            if ($suffix = $this->app->config('app.action_suffix')) {
-                $action = substr($action, 0, -strlen($suffix));
-            }
-
-            $route   = $module . '/' . $controller . '/' . $action;
-            $comment = preg_replace('/route\s?\(\s?([\'\"][\-\_\/\:\<\>\?\$\[\]\w]+[\'\"])\s?\,?\s?[\'\"]?(\w+?)[\'\"]?\s?\)/is', 'Route::\2(\1,\'' . $route . '\')', $comment);
-            $comment = preg_replace('/route\s?\(\s?([\'\"][\-\_\/\:\<\>\?\$\[\]\w]+[\'\"])\s?\)/is', 'Route::rule(\1,\'' . $route . '\')', $comment);
-
-            return $comment;
-        }
-    }
-
-    /**
-     * 创建模块的欢迎页面
-     * @access protected
-     * @param  string $module 模块名
-     * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix 类库后缀
-     * @return void
-     */
-    protected function buildHello($module, $namespace, $suffix = false)
-    {
-        $filename = $this->basePath . ($module ? $module . DIRECTORY_SEPARATOR : '') . 'controller' . DIRECTORY_SEPARATOR . 'Index' . ($suffix ? 'Controller' : '') . '.php';
-        if (!is_file($filename)) {
-            $content = file_get_contents($this->app->getThinkPath() . 'tpl' . DIRECTORY_SEPARATOR . 'default_index.tpl');
-            $content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [$namespace, $module ? $module . '\\' : '', 'controller', $suffix ? 'Controller' : ''], $content);
-            $this->checkDirBuild(dirname($filename));
-
-            file_put_contents($filename, $content);
-        }
-    }
-
-    /**
-     * 创建模块的公共文件
-     * @access protected
-     * @param  string $module 模块名
-     * @return void
-     */
-    protected function buildCommon($module)
-    {
-        $filename = $this->app->getConfigPath() . ($module ? $module . DIRECTORY_SEPARATOR : '') . 'app.php';
-        $this->checkDirBuild(dirname($filename));
-
-        if (!is_file($filename)) {
-            file_put_contents($filename, "<?php\n//配置文件\nreturn [\n\n];");
-        }
-
-        $filename = $this->basePath . ($module ? $module . DIRECTORY_SEPARATOR : '') . 'common.php';
-
-        if (!is_file($filename)) {
-            file_put_contents($filename, "<?php\n");
-        }
-    }
-
-    /**
-     * 创建目录
-     * @access protected
-     * @param  string $dirname 目录名称
-     * @return void
-     */
-    protected function checkDirBuild($dirname)
-    {
-        if (!is_dir($dirname)) {
-            mkdir($dirname, 0755, true);
-        }
-    }
-}

+ 0 - 117
thinkphp/library/think/Cache.php

@@ -1,117 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\cache\Driver;
-
-class Cache
-{
-    /**
-     * 缓存实例
-     * @var array
-     */
-    protected $instance = [];
-
-    /**
-     * 应用对象
-     * @var App
-     */
-    protected $app;
-
-    /**
-     * 操作句柄
-     * @var object
-     */
-    protected $handler;
-
-    public function __construct(App $app)
-    {
-        $this->app = $app;
-    }
-
-    /**
-     * 连接缓存
-     * @access public
-     * @param  array         $options  配置数组
-     * @param  bool|string   $name 缓存连接标识 true 强制重新连接
-     * @return Driver
-     */
-    public function connect(array $options = [], $name = false)
-    {
-        $type = !empty($options['type']) ? $options['type'] : 'File';
-
-        if (false === $name) {
-            $name = md5(serialize($options));
-        }
-
-        if (true === $name || !isset($this->instance[$name])) {
-            $class = false !== strpos($type, '\\') ? $type : '\\think\\cache\\driver\\' . ucwords($type);
-
-            // 记录初始化信息
-            $this->app->log('[ CACHE ] INIT ' . $type);
-
-            if (true === $name) {
-                $name = md5(serialize($options));
-            }
-
-            $this->instance[$name] = new $class($options);
-        }
-
-        return $this->instance[$name];
-    }
-
-    /**
-     * 自动初始化缓存
-     * @access public
-     * @param  array         $options  配置数组
-     * @return Driver
-     */
-    public function init(array $options = [])
-    {
-        if (is_null($this->handler)) {
-            // 自动初始化缓存
-            $config = $this->app['config'];
-
-            if (empty($options) && 'complex' == $config->get('cache.type')) {
-                $default = $config->get('cache.default');
-                $options = $config->get('cache.' . $default['type']) ?: $default;
-            } elseif (empty($options)) {
-                $options = $config->pull('cache');
-            }
-
-            $this->handler = $this->connect($options);
-        }
-
-        return $this->handler;
-    }
-
-    /**
-     * 切换缓存类型 需要配置 cache.type 为 complex
-     * @access public
-     * @param  string $name 缓存标识
-     * @return Driver
-     */
-    public function store($name = '')
-    {
-        if ('' !== $name && 'complex' == $this->app['config']->get('cache.type')) {
-            return $this->connect($this->app['config']->get('cache.' . $name), strtolower($name));
-        }
-
-        return $this->init();
-    }
-
-    public function __call($method, $args)
-    {
-        return call_user_func_array([$this->init(), $method], $args);
-    }
-
-}

+ 0 - 388
thinkphp/library/think/Collection.php

@@ -1,388 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: zhangyajun <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use ArrayAccess;
-use ArrayIterator;
-use Countable;
-use IteratorAggregate;
-use JsonSerializable;
-
-class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
-{
-    /**
-     * 数据集数据
-     * @var array
-     */
-    protected $items = [];
-
-    public function __construct($items = [])
-    {
-        $this->items = $this->convertToArray($items);
-    }
-
-    public static function make($items = [])
-    {
-        return new static($items);
-    }
-
-    /**
-     * 是否为空
-     * @access public
-     * @return bool
-     */
-    public function isEmpty()
-    {
-        return empty($this->items);
-    }
-
-    public function toArray()
-    {
-        return array_map(function ($value) {
-            return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value;
-        }, $this->items);
-    }
-
-    public function all()
-    {
-        return $this->items;
-    }
-
-    /**
-     * 合并数组
-     *
-     * @access public
-     * @param  mixed $items
-     * @return static
-     */
-    public function merge($items)
-    {
-        return new static(array_merge($this->items, $this->convertToArray($items)));
-    }
-
-    /**
-     * 比较数组,返回差集
-     *
-     * @access public
-     * @param  mixed $items
-     * @return static
-     */
-    public function diff($items)
-    {
-        return new static(array_diff($this->items, $this->convertToArray($items)));
-    }
-
-    /**
-     * 交换数组中的键和值
-     *
-     * @access public
-     * @return static
-     */
-    public function flip()
-    {
-        return new static(array_flip($this->items));
-    }
-
-    /**
-     * 比较数组,返回交集
-     *
-     * @access public
-     * @param  mixed $items
-     * @return static
-     */
-    public function intersect($items)
-    {
-        return new static(array_intersect($this->items, $this->convertToArray($items)));
-    }
-
-    /**
-     * 返回数组中所有的键名
-     *
-     * @access public
-     * @return static
-     */
-    public function keys()
-    {
-        return new static(array_keys($this->items));
-    }
-
-    /**
-     * 删除数组的最后一个元素(出栈)
-     *
-     * @access public
-     * @return mixed
-     */
-    public function pop()
-    {
-        return array_pop($this->items);
-    }
-
-    /**
-     * 通过使用用户自定义函数,以字符串返回数组
-     *
-     * @access public
-     * @param  callable $callback
-     * @param  mixed    $initial
-     * @return mixed
-     */
-    public function reduce(callable $callback, $initial = null)
-    {
-        return array_reduce($this->items, $callback, $initial);
-    }
-
-    /**
-     * 以相反的顺序返回数组。
-     *
-     * @access public
-     * @return static
-     */
-    public function reverse()
-    {
-        return new static(array_reverse($this->items));
-    }
-
-    /**
-     * 删除数组中首个元素,并返回被删除元素的值
-     *
-     * @access public
-     * @return mixed
-     */
-    public function shift()
-    {
-        return array_shift($this->items);
-    }
-
-    /**
-     * 在数组结尾插入一个元素
-     * @access public
-     * @param  mixed  $value
-     * @param  mixed  $key
-     * @return void
-     */
-    public function push($value, $key = null)
-    {
-        if (is_null($key)) {
-            $this->items[] = $value;
-        } else {
-            $this->items[$key] = $value;
-        }
-    }
-
-    /**
-     * 把一个数组分割为新的数组块.
-     *
-     * @access public
-     * @param  int  $size
-     * @param  bool $preserveKeys
-     * @return static
-     */
-    public function chunk($size, $preserveKeys = false)
-    {
-        $chunks = [];
-
-        foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {
-            $chunks[] = new static($chunk);
-        }
-
-        return new static($chunks);
-    }
-
-    /**
-     * 在数组开头插入一个元素
-     * @access public
-     * @param mixed  $value
-     * @param mixed  $key
-     * @return void
-     */
-    public function unshift($value, $key = null)
-    {
-        if (is_null($key)) {
-            array_unshift($this->items, $value);
-        } else {
-            $this->items = [$key => $value] + $this->items;
-        }
-    }
-
-    /**
-     * 给每个元素执行个回调
-     *
-     * @access public
-     * @param  callable $callback
-     * @return $this
-     */
-    public function each(callable $callback)
-    {
-        foreach ($this->items as $key => $item) {
-            $result = $callback($item, $key);
-
-            if (false === $result) {
-                break;
-            } elseif (!is_object($item)) {
-                $this->items[$key] = $result;
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 用回调函数过滤数组中的元素
-     * @access public
-     * @param  callable|null $callback
-     * @return static
-     */
-    public function filter(callable $callback = null)
-    {
-        if ($callback) {
-            return new static(array_filter($this->items, $callback));
-        }
-
-        return new static(array_filter($this->items));
-    }
-
-    /**
-     * 返回数据中指定的一列
-     * @access public
-     * @param mixed $columnKey 键名
-     * @param mixed $indexKey  作为索引值的列
-     * @return array
-     */
-    public function column($columnKey, $indexKey = null)
-    {
-        return array_column($this->items, $columnKey, $indexKey);
-    }
-
-    /**
-     * 对数组排序
-     *
-     * @access public
-     * @param  callable|null $callback
-     * @return static
-     */
-    public function sort(callable $callback = null)
-    {
-        $items = $this->items;
-
-        $callback = $callback ?: function ($a, $b) {
-            return $a == $b ? 0 : (($a < $b) ? -1 : 1);
-
-        };
-
-        uasort($items, $callback);
-
-        return new static($items);
-    }
-
-    /**
-     * 将数组打乱
-     *
-     * @access public
-     * @return static
-     */
-    public function shuffle()
-    {
-        $items = $this->items;
-
-        shuffle($items);
-
-        return new static($items);
-    }
-
-    /**
-     * 截取数组
-     *
-     * @access public
-     * @param  int  $offset
-     * @param  int  $length
-     * @param  bool $preserveKeys
-     * @return static
-     */
-    public function slice($offset, $length = null, $preserveKeys = false)
-    {
-        return new static(array_slice($this->items, $offset, $length, $preserveKeys));
-    }
-
-    // ArrayAccess
-    public function offsetExists($offset)
-    {
-        return array_key_exists($offset, $this->items);
-    }
-
-    public function offsetGet($offset)
-    {
-        return $this->items[$offset];
-    }
-
-    public function offsetSet($offset, $value)
-    {
-        if (is_null($offset)) {
-            $this->items[] = $value;
-        } else {
-            $this->items[$offset] = $value;
-        }
-    }
-
-    public function offsetUnset($offset)
-    {
-        unset($this->items[$offset]);
-    }
-
-    //Countable
-    public function count()
-    {
-        return count($this->items);
-    }
-
-    //IteratorAggregate
-    public function getIterator()
-    {
-        return new ArrayIterator($this->items);
-    }
-
-    //JsonSerializable
-    public function jsonSerialize()
-    {
-        return $this->toArray();
-    }
-
-    /**
-     * 转换当前数据集为JSON字符串
-     * @access public
-     * @param  integer $options json参数
-     * @return string
-     */
-    public function toJson($options = JSON_UNESCAPED_UNICODE)
-    {
-        return json_encode($this->toArray(), $options);
-    }
-
-    public function __toString()
-    {
-        return $this->toJson();
-    }
-
-    /**
-     * 转换成数组
-     *
-     * @access public
-     * @param  mixed $items
-     * @return array
-     */
-    protected function convertToArray($items)
-    {
-        if ($items instanceof self) {
-            return $items->all();
-        }
-
-        return (array) $items;
-    }
-}

+ 0 - 313
thinkphp/library/think/Config.php

@@ -1,313 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Config implements \ArrayAccess
-{
-    /**
-     * 配置参数
-     * @var array
-     */
-    private $config = [];
-
-    /**
-     * 缓存前缀
-     * @var string
-     */
-    private $prefix = 'app';
-
-    /**
-     * 设置配置参数默认前缀
-     * @access public
-     * @param string    $prefix 前缀
-     * @return void
-     */
-    public function setDefaultPrefix($prefix)
-    {
-        $this->prefix = $prefix;
-    }
-
-    /**
-     * 解析配置文件或内容
-     * @access public
-     * @param  string    $config 配置文件路径或内容
-     * @param  string    $type 配置解析类型
-     * @param  string    $name 配置名(如设置即表示二级配置)
-     * @return mixed
-     */
-    public function parse($config, $type = '', $name = '')
-    {
-        if (empty($type)) {
-            $type = pathinfo($config, PATHINFO_EXTENSION);
-        }
-
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type);
-
-        return $this->set((new $class())->parse($config), $name);
-    }
-
-    /**
-     * 加载配置文件(多种格式)
-     * @access public
-     * @param  string    $file 配置文件名
-     * @param  string    $name 一级配置名
-     * @return mixed
-     */
-    public function load($file, $name = '')
-    {
-        if (is_file($file)) {
-            $name = strtolower($name);
-            $type = pathinfo($file, PATHINFO_EXTENSION);
-
-            if ('php' == $type) {
-                return $this->set(include $file, $name);
-            } elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
-                return $this->set(yaml_parse_file($file), $name);
-            }
-            return $this->parse($file, $type, $name);
-        }
-
-        return $this->config;
-    }
-
-    /**
-     * 自动加载配置文件(PHP格式)
-     * @access public
-     * @param  string    $name 配置名
-     * @return void
-     */
-    protected function autoLoad($name)
-    {
-        // 如果尚未载入 则动态加载配置文件
-        $module = Container::get('request')->module();
-        $module = $module ? $module . DIRECTORY_SEPARATOR : '';
-        $app    = Container::get('app');
-        $path   = $app->getAppPath() . $module;
-
-        if (is_dir($path . 'config')) {
-            $file = $path . 'config' . DIRECTORY_SEPARATOR . $name . $app->getConfigExt();
-        } elseif (is_dir($app->getConfigPath() . $module)) {
-            $file = $app->getConfigPath() . $module . $name . $app->getConfigExt();
-        }
-
-        if (isset($file) && is_file($file)) {
-            $this->load($file, $name);
-        }
-    }
-
-    /**
-     * 检测配置是否存在
-     * @access public
-     * @param  string    $name 配置参数名(支持多级配置 .号分割)
-     * @return bool
-     */
-    public function has($name)
-    {
-        if (!strpos($name, '.')) {
-            $name = $this->prefix . '.' . $name;
-        }
-
-        return !is_null($this->get($name)) ? true : false;
-    }
-
-    /**
-     * 获取一级配置
-     * @access public
-     * @param  string    $name 一级配置名
-     * @return array
-     */
-    public function pull($name)
-    {
-        $name = strtolower($name);
-
-        if (!isset($this->config[$name])) {
-            // 如果尚未载入 则动态加载配置文件
-            $this->autoLoad($name);
-        }
-
-        return isset($this->config[$name]) ? $this->config[$name] : [];
-    }
-
-    /**
-     * 获取配置参数 为空则获取所有配置
-     * @access public
-     * @param  string    $name 配置参数名(支持多级配置 .号分割)
-     * @return mixed
-     */
-    public function get($name = null)
-    {
-        // 无参数时获取所有
-        if (empty($name)) {
-            return $this->config;
-        }
-
-        if (!strpos($name, '.')) {
-            $name = $this->prefix . '.' . $name;
-        } elseif ('.' == substr($name, -1)) {
-            return $this->pull(substr($name, 0, -1));
-        }
-
-        $name    = explode('.', $name);
-        $name[0] = strtolower($name[0]);
-        $config  = $this->config;
-
-        if (!isset($config[$name[0]])) {
-            // 如果尚未载入 则动态加载配置文件
-            $this->autoLoad($name[0]);
-        }
-
-        // 按.拆分成多维数组进行判断
-        foreach ($name as $val) {
-            if (isset($config[$val])) {
-                $config = $config[$val];
-            } else {
-                return;
-            }
-        }
-
-        return $config;
-    }
-
-    /**
-     * 设置配置参数 name为数组则为批量设置
-     * @access public
-     * @param  string|array  $name 配置参数名(支持三级配置 .号分割)
-     * @param  mixed         $value 配置值
-     * @return mixed
-     */
-    public function set($name, $value = null)
-    {
-        if (is_string($name)) {
-            if (!strpos($name, '.')) {
-                $name = $this->prefix . '.' . $name;
-            }
-
-            $name = explode('.', $name, 3);
-
-            if (count($name) == 2) {
-                $this->config[strtolower($name[0])][$name[1]] = $value;
-            } else {
-                $this->config[strtolower($name[0])][$name[1]][$name[2]] = $value;
-            }
-
-            return $value;
-        } elseif (is_array($name)) {
-            // 批量设置
-            if (!empty($value)) {
-                if (isset($this->config[$value])) {
-                    $result = array_merge($this->config[$value], $name);
-                } else {
-                    $result = $name;
-                }
-
-                $this->config[$value] = $result;
-            } else {
-                $result = $this->config = array_merge($this->config, $name);
-            }
-        } else {
-            // 为空直接返回 已有配置
-            $result = $this->config;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 移除配置
-     * @access public
-     * @param  string  $name 配置参数名(支持三级配置 .号分割)
-     * @return void
-     */
-    public function remove($name)
-    {
-        if (!strpos($name, '.')) {
-            $name = $this->prefix . '.' . $name;
-        }
-
-        $name = explode('.', $name, 3);
-
-        if (count($name) == 2) {
-            unset($this->config[strtolower($name[0])][$name[1]]);
-        } else {
-            unset($this->config[strtolower($name[0])][$name[1]][$name[2]]);
-        }
-    }
-
-    /**
-     * 重置配置参数
-     * @access public
-     * @param  string    $prefix  配置前缀名
-     * @return void
-     */
-    public function reset($prefix = '')
-    {
-        if ('' === $prefix) {
-            $this->config = [];
-        } else {
-            $this->config[$prefix] = [];
-        }
-    }
-
-    /**
-     * 设置配置
-     * @access public
-     * @param  string    $name  参数名
-     * @param  mixed     $value 值
-     */
-    public function __set($name, $value)
-    {
-        return $this->set($name, $value);
-    }
-
-    /**
-     * 获取配置参数
-     * @access public
-     * @param  string $name 参数名
-     * @return mixed
-     */
-    public function __get($name)
-    {
-        return $this->get($name);
-    }
-
-    /**
-     * 检测是否存在参数
-     * @access public
-     * @param  string $name 参数名
-     * @return bool
-     */
-    public function __isset($name)
-    {
-        return $this->has($name);
-    }
-
-    // ArrayAccess
-    public function offsetSet($name, $value)
-    {
-        $this->set($name, $value);
-    }
-
-    public function offsetExists($name)
-    {
-        return $this->has($name);
-    }
-
-    public function offsetUnset($name)
-    {
-        $this->remove($name);
-    }
-
-    public function offsetGet($name)
-    {
-        return $this->get($name);
-    }
-}

+ 0 - 794
thinkphp/library/think/Console.php

@@ -1,794 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | TopThink [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2015 http://www.topthink.com All rights reserved.
-// +----------------------------------------------------------------------
-// | Author: zhangyajun <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\console\Command;
-use think\console\command\Help as HelpCommand;
-use think\console\Input;
-use think\console\input\Argument as InputArgument;
-use think\console\input\Definition as InputDefinition;
-use think\console\input\Option as InputOption;
-use think\console\Output;
-use think\console\output\driver\Buffer;
-
-class Console
-{
-
-    private $name;
-    private $version;
-
-    /** @var Command[] */
-    private $commands = [];
-
-    private $wantHelps = false;
-
-    private $catchExceptions = true;
-    private $autoExit        = true;
-    private $definition;
-    private $defaultCommand;
-
-    private static $defaultCommands = [
-        "think\\console\\command\\Help",
-        "think\\console\\command\\Lists",
-        "think\\console\\command\\Build",
-        "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",
-        "think\\console\\command\\optimize\\Route",
-        "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)
-    {
-        $this->name    = $name;
-        $this->version = $version;
-
-        if ($user) {
-            $this->setUser($user);
-        }
-
-        $this->defaultCommand = 'list';
-        $this->definition     = $this->getDefaultInputDefinition();
-
-        foreach ($this->getDefaultCommands() as $command) {
-            $this->add($command);
-        }
-    }
-
-    /**
-     * 设置执行用户
-     * @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']);
-
-            // 读取指令集
-            $file = Container::get('env')->get('app_path') . 'command.php';
-
-            if (is_file($file)) {
-                $commands = include $file;
-
-                if (is_array($commands)) {
-                    foreach ($commands as $command) {
-                        if (class_exists($command) && is_subclass_of($command, "\\think\\console\\Command")) {
-                            // 注册指令
-                            $console->add(new $command());
-                        }
-                    }
-                }
-            }
-        }
-
-        if ($run) {
-            // 运行
-            return $console->run();
-        } else {
-            return $console;
-        }
-    }
-
-    /**
-     * @access public
-     * @param  string $command
-     * @param  array  $parameters
-     * @param  string $driver
-     * @return Output|Buffer
-     */
-    public static function call($command, array $parameters = [], $driver = 'buffer')
-    {
-        $console = self::init(false);
-
-        array_unshift($parameters, $command);
-
-        $input  = new Input($parameters);
-        $output = new Output($driver);
-
-        $console->setCatchExceptions(false);
-        $console->find($command)->run($input, $output);
-
-        return $output;
-    }
-
-    /**
-     * 执行当前的指令
-     * @access public
-     * @return int
-     * @throws \Exception
-     * @api
-     */
-    public function run()
-    {
-        $input  = new Input();
-        $output = new Output();
-
-        $this->configureIO($input, $output);
-
-        try {
-            $exitCode = $this->doRun($input, $output);
-        } catch (\Exception $e) {
-            if (!$this->catchExceptions) {
-                throw $e;
-            }
-
-            $output->renderException($e);
-
-            $exitCode = $e->getCode();
-            if (is_numeric($exitCode)) {
-                $exitCode = (int) $exitCode;
-                if (0 === $exitCode) {
-                    $exitCode = 1;
-                }
-            } else {
-                $exitCode = 1;
-            }
-        }
-
-        if ($this->autoExit) {
-            if ($exitCode > 255) {
-                $exitCode = 255;
-            }
-
-            exit($exitCode);
-        }
-
-        return $exitCode;
-    }
-
-    /**
-     * 执行指令
-     * @access public
-     * @param  Input  $input
-     * @param  Output $output
-     * @return int
-     */
-    public function doRun(Input $input, Output $output)
-    {
-        if (true === $input->hasParameterOption(['--version', '-V'])) {
-            $output->writeln($this->getLongVersion());
-
-            return 0;
-        }
-
-        $name = $this->getCommandName($input);
-
-        if (true === $input->hasParameterOption(['--help', '-h'])) {
-            if (!$name) {
-                $name  = 'help';
-                $input = new Input(['help']);
-            } else {
-                $this->wantHelps = true;
-            }
-        }
-
-        if (!$name) {
-            $name  = $this->defaultCommand;
-            $input = new Input([$this->defaultCommand]);
-        }
-
-        $command = $this->find($name);
-
-        $exitCode = $this->doRunCommand($command, $input, $output);
-
-        return $exitCode;
-    }
-
-    /**
-     * 设置输入参数定义
-     * @access public
-     * @param  InputDefinition $definition
-     */
-    public function setDefinition(InputDefinition $definition)
-    {
-        $this->definition = $definition;
-    }
-
-    /**
-     * 获取输入参数定义
-     * @access public
-     * @return InputDefinition The InputDefinition instance
-     */
-    public function getDefinition()
-    {
-        return $this->definition;
-    }
-
-    /**
-     * Gets the help message.
-     * @access public
-     * @return string A help message.
-     */
-    public function getHelp()
-    {
-        return $this->getLongVersion();
-    }
-
-    /**
-     * 是否捕获异常
-     * @access public
-     * @param  bool $boolean
-     * @api
-     */
-    public function setCatchExceptions($boolean)
-    {
-        $this->catchExceptions = (bool) $boolean;
-    }
-
-    /**
-     * 是否自动退出
-     * @access public
-     * @param  bool $boolean
-     * @api
-     */
-    public function setAutoExit($boolean)
-    {
-        $this->autoExit = (bool) $boolean;
-    }
-
-    /**
-     * 获取名称
-     * @access public
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * 设置名称
-     * @access public
-     * @param  string $name
-     */
-    public function setName($name)
-    {
-        $this->name = $name;
-    }
-
-    /**
-     * 获取版本
-     * @access public
-     * @return string
-     * @api
-     */
-    public function getVersion()
-    {
-        return $this->version;
-    }
-
-    /**
-     * 设置版本
-     * @access public
-     * @param  string $version
-     */
-    public function setVersion($version)
-    {
-        $this->version = $version;
-    }
-
-    /**
-     * 获取完整的版本号
-     * @access public
-     * @return string
-     */
-    public function getLongVersion()
-    {
-        if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
-            return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
-        }
-
-        return '<info>Console Tool</info>';
-    }
-
-    /**
-     * 注册一个指令
-     * @access public
-     * @param  string $name
-     * @return Command
-     */
-    public function register($name)
-    {
-        return $this->add(new Command($name));
-    }
-
-    /**
-     * 添加指令
-     * @access public
-     * @param  Command[] $commands
-     */
-    public function addCommands(array $commands)
-    {
-        foreach ($commands as $command) {
-            $this->add($command);
-        }
-    }
-
-    /**
-     * 添加一个指令
-     * @access public
-     * @param  Command $command
-     * @return Command
-     */
-    public function add(Command $command)
-    {
-        $command->setConsole($this);
-
-        if (!$command->isEnabled()) {
-            $command->setConsole(null);
-            return;
-        }
-
-        if (null === $command->getDefinition()) {
-            throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
-        }
-
-        $this->commands[$command->getName()] = $command;
-
-        foreach ($command->getAliases() as $alias) {
-            $this->commands[$alias] = $command;
-        }
-
-        return $command;
-    }
-
-    /**
-     * 获取指令
-     * @access public
-     * @param  string $name 指令名称
-     * @return Command
-     * @throws \InvalidArgumentException
-     */
-    public function get($name)
-    {
-        if (!isset($this->commands[$name])) {
-            throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
-        }
-
-        $command = $this->commands[$name];
-
-        if ($this->wantHelps) {
-            $this->wantHelps = false;
-
-            /** @var HelpCommand $helpCommand */
-            $helpCommand = $this->get('help');
-            $helpCommand->setCommand($command);
-
-            return $helpCommand;
-        }
-
-        return $command;
-    }
-
-    /**
-     * 某个指令是否存在
-     * @access public
-     * @param  string $name 指令名称
-     * @return bool
-     */
-    public function has($name)
-    {
-        return isset($this->commands[$name]);
-    }
-
-    /**
-     * 获取所有的命名空间
-     * @access public
-     * @return array
-     */
-    public function getNamespaces()
-    {
-        $namespaces = [];
-        foreach ($this->commands as $command) {
-            $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
-
-            foreach ($command->getAliases() as $alias) {
-                $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
-            }
-        }
-
-        return array_values(array_unique(array_filter($namespaces)));
-    }
-
-    /**
-     * 查找注册命名空间中的名称或缩写。
-     * @access public
-     * @param  string $namespace
-     * @return string
-     * @throws \InvalidArgumentException
-     */
-    public function findNamespace($namespace)
-    {
-        $allNamespaces = $this->getNamespaces();
-        $expr          = preg_replace_callback('{([^:]+|)}', function ($matches) {
-            return preg_quote($matches[1]) . '[^:]*';
-        }, $namespace);
-        $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);
-
-        if (empty($namespaces)) {
-            $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
-
-            if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
-                if (1 == count($alternatives)) {
-                    $message .= "\n\nDid you mean this?\n    ";
-                } else {
-                    $message .= "\n\nDid you mean one of these?\n    ";
-                }
-
-                $message .= implode("\n    ", $alternatives);
-            }
-
-            throw new \InvalidArgumentException($message);
-        }
-
-        $exact = in_array($namespace, $namespaces, true);
-        if (count($namespaces) > 1 && !$exact) {
-            throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))));
-        }
-
-        return $exact ? $namespace : reset($namespaces);
-    }
-
-    /**
-     * 查找指令
-     * @access public
-     * @param  string $name 名称或者别名
-     * @return Command
-     * @throws \InvalidArgumentException
-     */
-    public function find($name)
-    {
-        $allCommands = array_keys($this->commands);
-
-        $expr = preg_replace_callback('{([^:]+|)}', function ($matches) {
-            return preg_quote($matches[1]) . '[^:]*';
-        }, $name);
-
-        $commands = preg_grep('{^' . $expr . '}', $allCommands);
-
-        if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) {
-            if (false !== $pos = strrpos($name, ':')) {
-                $this->findNamespace(substr($name, 0, $pos));
-            }
-
-            $message = sprintf('Command "%s" is not defined.', $name);
-
-            if ($alternatives = $this->findAlternatives($name, $allCommands)) {
-                if (1 == count($alternatives)) {
-                    $message .= "\n\nDid you mean this?\n    ";
-                } else {
-                    $message .= "\n\nDid you mean one of these?\n    ";
-                }
-                $message .= implode("\n    ", $alternatives);
-            }
-
-            throw new \InvalidArgumentException($message);
-        }
-
-        if (count($commands) > 1) {
-            $commandList = $this->commands;
-
-            $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
-                $commandName = $commandList[$nameOrAlias]->getName();
-
-                return $commandName === $nameOrAlias || !in_array($commandName, $commands);
-            });
-        }
-
-        $exact = in_array($name, $commands, true);
-        if (count($commands) > 1 && !$exact) {
-            $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
-
-            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
-        }
-
-        return $this->get($exact ? $name : reset($commands));
-    }
-
-    /**
-     * 获取所有的指令
-     * @access public
-     * @param  string $namespace 命名空间
-     * @return Command[]
-     * @api
-     */
-    public function all($namespace = null)
-    {
-        if (null === $namespace) {
-            return $this->commands;
-        }
-
-        $commands = [];
-        foreach ($this->commands as $name => $command) {
-            if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) {
-                $commands[$name] = $command;
-            }
-        }
-
-        return $commands;
-    }
-
-    /**
-     * 获取可能的指令名
-     * @access public
-     * @param  array $names
-     * @return array
-     */
-    public static function getAbbreviations($names)
-    {
-        $abbrevs = [];
-        foreach ($names as $name) {
-            for ($len = strlen($name); $len > 0; --$len) {
-                $abbrev             = substr($name, 0, $len);
-                $abbrevs[$abbrev][] = $name;
-            }
-        }
-
-        return $abbrevs;
-    }
-
-    /**
-     * 配置基于用户的参数和选项的输入和输出实例。
-     * @access protected
-     * @param  Input  $input  输入实例
-     * @param  Output $output 输出实例
-     */
-    protected function configureIO(Input $input, Output $output)
-    {
-        if (true === $input->hasParameterOption(['--ansi'])) {
-            $output->setDecorated(true);
-        } elseif (true === $input->hasParameterOption(['--no-ansi'])) {
-            $output->setDecorated(false);
-        }
-
-        if (true === $input->hasParameterOption(['--no-interaction', '-n'])) {
-            $input->setInteractive(false);
-        }
-
-        if (true === $input->hasParameterOption(['--quiet', '-q'])) {
-            $output->setVerbosity(Output::VERBOSITY_QUIET);
-        } else {
-            if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
-                $output->setVerbosity(Output::VERBOSITY_DEBUG);
-            } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
-                $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);
-            } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
-                $output->setVerbosity(Output::VERBOSITY_VERBOSE);
-            }
-        }
-    }
-
-    /**
-     * 执行指令
-     * @access protected
-     * @param  Command $command 指令实例
-     * @param  Input   $input   输入实例
-     * @param  Output  $output  输出实例
-     * @return int
-     * @throws \Exception
-     */
-    protected function doRunCommand(Command $command, Input $input, Output $output)
-    {
-        return $command->run($input, $output);
-    }
-
-    /**
-     * 获取指令的基础名称
-     * @access protected
-     * @param  Input $input
-     * @return string
-     */
-    protected function getCommandName(Input $input)
-    {
-        return $input->getFirstArgument();
-    }
-
-    /**
-     * 获取默认输入定义
-     * @access protected
-     * @return InputDefinition
-     */
-    protected function getDefaultInputDefinition()
-    {
-        return new InputDefinition([
-            new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
-            new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
-            new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this console version'),
-            new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
-            new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
-            new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
-            new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
-            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
-        ]);
-    }
-
-    /**
-     * 设置默认命令
-     * @access protected
-     * @return Command[] An array of default Command instances
-     */
-    protected function getDefaultCommands()
-    {
-        $defaultCommands = [];
-
-        foreach (self::$defaultCommands as $classname) {
-            if (class_exists($classname) && is_subclass_of($classname, "think\\console\\Command")) {
-                $defaultCommands[] = new $classname();
-            }
-        }
-
-        return $defaultCommands;
-    }
-
-    public static function addDefaultCommands(array $classnames)
-    {
-        self::$defaultCommands = array_merge(self::$defaultCommands, $classnames);
-    }
-
-    /**
-     * 获取可能的建议
-     * @access private
-     * @param  array $abbrevs
-     * @return string
-     */
-    private function getAbbreviationSuggestions($abbrevs)
-    {
-        return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
-    }
-
-    /**
-     * 返回命名空间部分
-     * @access public
-     * @param  string $name  指令
-     * @param  string $limit 部分的命名空间的最大数量
-     * @return string
-     */
-    public function extractNamespace($name, $limit = null)
-    {
-        $parts = explode(':', $name);
-        array_pop($parts);
-
-        return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
-    }
-
-    /**
-     * 查找可替代的建议
-     * @access private
-     * @param  string             $name
-     * @param  array|\Traversable $collection
-     * @return array
-     */
-    private function findAlternatives($name, $collection)
-    {
-        $threshold    = 1e3;
-        $alternatives = [];
-
-        $collectionParts = [];
-        foreach ($collection as $item) {
-            $collectionParts[$item] = explode(':', $item);
-        }
-
-        foreach (explode(':', $name) as $i => $subname) {
-            foreach ($collectionParts as $collectionName => $parts) {
-                $exists = isset($alternatives[$collectionName]);
-                if (!isset($parts[$i]) && $exists) {
-                    $alternatives[$collectionName] += $threshold;
-                    continue;
-                } elseif (!isset($parts[$i])) {
-                    continue;
-                }
-
-                $lev = levenshtein($subname, $parts[$i]);
-                if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
-                    $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
-                } elseif ($exists) {
-                    $alternatives[$collectionName] += $threshold;
-                }
-            }
-        }
-
-        foreach ($collection as $item) {
-            $lev = levenshtein($name, $item);
-            if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
-                $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
-            }
-        }
-
-        $alternatives = array_filter($alternatives, function ($lev) use ($threshold) {
-            return $lev < 2 * $threshold;
-        });
-        asort($alternatives);
-
-        return array_keys($alternatives);
-    }
-
-    /**
-     * 设置默认的指令
-     * @access public
-     * @param  string $commandName The Command name
-     */
-    public function setDefaultCommand($commandName)
-    {
-        $this->defaultCommand = $commandName;
-    }
-
-    /**
-     * 返回所有的命名空间
-     * @access private
-     * @param  string $name
-     * @return array
-     */
-    private function extractAllNamespaces($name)
-    {
-        $parts      = explode(':', $name, -1);
-        $namespaces = [];
-
-        foreach ($parts as $part) {
-            if (count($namespaces)) {
-                $namespaces[] = end($namespaces) . ':' . $part;
-            } else {
-                $namespaces[] = $part;
-            }
-        }
-
-        return $namespaces;
-    }
-
-}

+ 0 - 365
thinkphp/library/think/Container.php

@@ -1,365 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use Closure;
-use InvalidArgumentException;
-use ReflectionClass;
-use ReflectionException;
-use ReflectionFunction;
-use ReflectionMethod;
-use think\exception\ClassNotFoundException;
-
-class Container
-{
-    /**
-     * 容器对象实例
-     * @var Container
-     */
-    protected static $instance;
-
-    /**
-     * 容器中的对象实例
-     * @var array
-     */
-    protected $instances = [];
-
-    /**
-     * 容器绑定标识
-     * @var array
-     */
-    protected $bind = [];
-
-    /**
-     * 获取当前容器的实例(单例)
-     * @access public
-     * @return static
-     */
-    public static function getInstance()
-    {
-        if (is_null(static::$instance)) {
-            static::$instance = new static;
-        }
-
-        return static::$instance;
-    }
-
-    /**
-     * 获取容器中的对象实例
-     * @access public
-     * @param  string        $abstract       类名或者标识
-     * @param  array|true    $vars           变量
-     * @param  bool          $newInstance    是否每次创建新的实例
-     * @return object
-     */
-    public static function get($abstract, $vars = [], $newInstance = false)
-    {
-        return static::getInstance()->make($abstract, $vars, $newInstance);
-    }
-
-    /**
-     * 绑定一个类、闭包、实例、接口实现到容器
-     * @access public
-     * @param  string  $abstract    类标识、接口
-     * @param  mixed   $concrete    要绑定的类、闭包或者实例
-     * @return Container
-     */
-    public static function set($abstract, $concrete = null)
-    {
-        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
-     * @param  string|array  $abstract    类标识、接口
-     * @param  mixed         $concrete    要绑定的类、闭包或者实例
-     * @return $this
-     */
-    public function bind($abstract, $concrete = null)
-    {
-        if (is_array($abstract)) {
-            $this->bind = array_merge($this->bind, $abstract);
-        } elseif ($concrete instanceof Closure) {
-            $this->bind[$abstract] = $concrete;
-        } elseif (is_object($concrete)) {
-            $this->instances[$abstract] = $concrete;
-        } else {
-            $this->bind[$abstract] = $concrete;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 绑定一个类实例当容器
-     * @access public
-     * @param  string    $abstract    类名或者标识
-     * @param  object    $instance    类的实例
-     * @return $this
-     */
-    public function instance($abstract, $instance)
-    {
-        if (isset($this->bind[$abstract])) {
-            $abstract = $this->bind[$abstract];
-        }
-
-        $this->instances[$abstract] = $instance;
-
-        return $this;
-    }
-
-    /**
-     * 判断容器中是否存在类及标识
-     * @access public
-     * @param  string    $abstract    类名或者标识
-     * @return bool
-     */
-    public function bound($abstract)
-    {
-        return isset($this->bind[$abstract]) || isset($this->instances[$abstract]);
-    }
-
-    /**
-     * 判断容器中是否存在类及标识
-     * @access public
-     * @param  string    $name    类名或者标识
-     * @return bool
-     */
-    public function has($name)
-    {
-        return $this->bound($name);
-    }
-
-    /**
-     * 创建类的实例
-     * @access public
-     * @param  string        $abstract       类名或者标识
-     * @param  array|true    $vars           变量
-     * @param  bool          $newInstance    是否每次创建新的实例
-     * @return object
-     */
-    public function make($abstract, $vars = [], $newInstance = false)
-    {
-        if (true === $vars) {
-            // 总是创建新的实例化对象
-            $newInstance = true;
-            $vars        = [];
-        }
-
-        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);
-            }
-        } 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     参数
-     * @return mixed
-     */
-    public function invokeFunction($function, $vars = [])
-    {
-        try {
-            $reflect = new ReflectionFunction($function);
-
-            $args = $this->bindParams($reflect, $vars);
-
-            return $reflect->invokeArgs($args);
-        } catch (ReflectionException $e) {
-            throw new Exception('function not exists: ' . $function . '()');
-        }
-    }
-
-    /**
-     * 调用反射执行类的方法 支持参数绑定
-     * @access public
-     * @param  mixed   $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) . '()');
-        }
-    }
-
-    /**
-     * 调用反射执行类的方法 支持参数绑定
-     * @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);
-    }
-
-    /**
-     * 调用反射执行callable 支持参数绑定
-     * @access public
-     * @param  mixed $callable
-     * @param  array $vars   参数
-     * @return mixed
-     */
-    public function invoke($callable, $vars = [])
-    {
-        if ($callable instanceof Closure) {
-            return $this->invokeFunction($callable, $vars);
-        }
-
-        return $this->invokeMethod($callable, $vars);
-    }
-
-    /**
-     * 调用反射执行类的实例化 支持依赖注入
-     * @access public
-     * @param  string    $class 类名
-     * @param  array     $vars  参数
-     * @return mixed
-     */
-    public function invokeClass($class, $vars = [])
-    {
-        try {
-            $reflect = new ReflectionClass($class);
-
-            $constructor = $reflect->getConstructor();
-
-            $args = $constructor ? $this->bindParams($constructor, $vars) : [];
-
-            return $reflect->newInstanceArgs($args);
-        } catch (ReflectionException $e) {
-            throw new ClassNotFoundException('class not exists: ' . $class, $class);
-        }
-    }
-
-    /**
-     * 绑定参数
-     * @access protected
-     * @param  \ReflectionMethod|\ReflectionFunction $reflect 反射类
-     * @param  array                                 $vars    参数
-     * @return array
-     */
-    protected function bindParams($reflect, $vars = [])
-    {
-        if ($reflect->getNumberOfParameters() == 0) {
-            return [];
-        }
-
-        // 判断数组类型 数字数组时按顺序绑定参数
-        reset($vars);
-        $type   = key($vars) === 0 ? 1 : 0;
-        $params = $reflect->getParameters();
-
-        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);
-            }
-        }
-
-        return $args;
-    }
-
-}

+ 0 - 239
thinkphp/library/think/Controller.php

@@ -1,239 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ValidateException;
-use traits\controller\Jump;
-
-class Controller
-{
-    use Jump;
-
-    /**
-     * 视图类实例
-     * @var \think\View
-     */
-    protected $view;
-
-    /**
-     * Request实例
-     * @var \think\Request
-     */
-    protected $request;
-
-    /**
-     * 应用实例
-     * @var \think\App
-     */
-    protected $app;
-
-    /**
-     * 验证失败是否抛出异常
-     * @var bool
-     */
-    protected $failException = false;
-
-    /**
-     * 是否批量验证
-     * @var bool
-     */
-    protected $batchValidate = false;
-
-    /**
-     * 前置操作方法列表
-     * @var array $beforeActionList
-     */
-    protected $beforeActionList = [];
-
-    /**
-     * 构造方法
-     * @access public
-     */
-    public function __construct()
-    {
-        $this->request = Container::get('request');
-        $this->app     = Container::get('app');
-        $this->view    = Container::get('view')->init(
-            $this->app['config']->pull('template')
-        );
-
-        // 控制器初始化
-        $this->initialize();
-
-        // 前置操作方法
-        foreach ((array) $this->beforeActionList as $method => $options) {
-            is_numeric($method) ?
-            $this->beforeAction($options) :
-            $this->beforeAction($method, $options);
-        }
-    }
-
-    // 初始化
-    protected function initialize()
-    {}
-
-    /**
-     * 前置操作
-     * @access protected
-     * @param  string $method  前置操作方法名
-     * @param  array  $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
-     */
-    protected function beforeAction($method, $options = [])
-    {
-        if (isset($options['only'])) {
-            if (is_string($options['only'])) {
-                $options['only'] = explode(',', $options['only']);
-            }
-            if (!in_array($this->request->action(), $options['only'])) {
-                return;
-            }
-        } elseif (isset($options['except'])) {
-            if (is_string($options['except'])) {
-                $options['except'] = explode(',', $options['except']);
-            }
-            if (in_array($this->request->action(), $options['except'])) {
-                return;
-            }
-        }
-
-        call_user_func([$this, $method]);
-    }
-
-    /**
-     * 加载模板输出
-     * @access protected
-     * @param  string $template 模板文件名
-     * @param  array  $vars     模板输出变量
-     * @param  array  $config   模板参数
-     * @return mixed
-     */
-    protected function fetch($template = '', $vars = [], $config = [])
-    {
-        return $this->view->fetch($template, $vars, $config);
-    }
-
-    /**
-     * 渲染内容输出
-     * @access protected
-     * @param  string $content 模板内容
-     * @param  array  $vars    模板输出变量
-     * @param  array  $config  模板参数
-     * @return mixed
-     */
-    protected function display($content = '', $vars = [], $config = [])
-    {
-        return $this->view->display($content, $vars, $config);
-    }
-
-    /**
-     * 模板变量赋值
-     * @access protected
-     * @param  mixed $name  要显示的模板变量
-     * @param  mixed $value 变量的值
-     * @return $this
-     */
-    protected function assign($name, $value = '')
-    {
-        $this->view->assign($name, $value);
-
-        return $this;
-    }
-
-    /**
-     * 视图过滤
-     * @access protected
-     * @param  Callable $filter 过滤方法或闭包
-     * @return $this
-     */
-    protected function filter($filter)
-    {
-        $this->view->filter($filter);
-
-        return $this;
-    }
-
-    /**
-     * 初始化模板引擎
-     * @access protected
-     * @param  array|string $engine 引擎参数
-     * @return $this
-     */
-    protected function engine($engine)
-    {
-        $this->view->engine($engine);
-
-        return $this;
-    }
-
-    /**
-     * 设置验证失败后是否抛出异常
-     * @access protected
-     * @param  bool $fail 是否抛出异常
-     * @return $this
-     */
-    protected function validateFailException($fail = true)
-    {
-        $this->failException = $fail;
-
-        return $this;
-    }
-
-    /**
-     * 验证数据
-     * @access protected
-     * @param  array        $data     数据
-     * @param  string|array $validate 验证器名或者验证规则数组
-     * @param  array        $message  提示信息
-     * @param  bool         $batch    是否批量验证
-     * @param  mixed        $callback 回调方法(闭包)
-     * @return array|string|true
-     * @throws ValidateException
-     */
-    protected function validate($data, $validate, $message = [], $batch = false, $callback = null)
-    {
-        if (is_array($validate)) {
-            $v = $this->app->validate();
-            $v->rule($validate);
-        } else {
-            if (strpos($validate, '.')) {
-                // 支持场景
-                list($validate, $scene) = explode('.', $validate);
-            }
-            $v = $this->app->validate($validate);
-            if (!empty($scene)) {
-                $v->scene($scene);
-            }
-        }
-
-        // 是否批量验证
-        if ($batch || $this->batchValidate) {
-            $v->batch(true);
-        }
-
-        if (is_array($message)) {
-            $v->message($message);
-        }
-
-        if ($callback && is_callable($callback)) {
-            call_user_func_array($callback, [$v, &$data]);
-        }
-
-        if (!$v->check($data)) {
-            if ($this->failException) {
-                throw new ValidateException($v->getError());
-            }
-            return $v->getError();
-        }
-
-        return true;
-    }
-}

+ 0 - 262
thinkphp/library/think/Cookie.php

@@ -1,262 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Cookie
-{
-    /**
-     * 配置参数
-     * @var array
-     */
-    protected $config = [
-        // cookie 名称前缀
-        'prefix'    => '',
-        // cookie 保存时间
-        'expire'    => 0,
-        // cookie 保存路径
-        'path'      => '/',
-        // cookie 有效域名
-        'domain'    => '',
-        //  cookie 启用安全传输
-        'secure'    => false,
-        // httponly设置
-        'httponly'  => false,
-        // 是否使用 setcookie
-        'setcookie' => true,
-    ];
-
-    /**
-     * 是否初始化
-     * @var bool
-     */
-    protected $init;
-
-    /**
-     * Cookie初始化
-     * @access public
-     * @param  array $config
-     * @return void
-     */
-    public function init(array $config = [])
-    {
-        if (empty($config)) {
-            $config = Container::get('config')->pull('cookie');
-        }
-
-        $this->config = array_merge($this->config, array_change_key_case($config));
-
-        if (!empty($this->config['httponly'])) {
-            ini_set('session.cookie_httponly', 1);
-        }
-
-        $this->init = true;
-    }
-
-    /**
-     * 设置或者获取cookie作用域(前缀)
-     * @access public
-     * @param  string $prefix
-     * @return string|void
-     */
-    public function prefix($prefix = '')
-    {
-        if (empty($prefix)) {
-            return $this->config['prefix'];
-        }
-
-        $this->config['prefix'] = $prefix;
-    }
-
-    /**
-     * Cookie 设置、获取、删除
-     *
-     * @access public
-     * @param  string $name  cookie名称
-     * @param  mixed  $value cookie值
-     * @param  mixed  $option 可选参数 可能会是 null|integer|string
-     * @return void
-     */
-    public function set($name, $value = '', $option = null)
-    {
-        !isset($this->init) && $this->init();
-
-        // 参数设置(会覆盖黙认设置)
-        if (!is_null($option)) {
-            if (is_numeric($option)) {
-                $option = ['expire' => $option];
-            } elseif (is_string($option)) {
-                parse_str($option, $option);
-            }
-
-            $config = array_merge($this->config, array_change_key_case($option));
-        } else {
-            $config = $this->config;
-        }
-
-        $name = $config['prefix'] . $name;
-
-        // 设置cookie
-        if (is_array($value)) {
-            array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'encode');
-            $value = 'think:' . json_encode($value);
-        }
-
-        $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;
-
-        if ($config['setcookie']) {
-            setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
-        }
-
-        $_COOKIE[$name] = $value;
-    }
-
-    /**
-     * 永久保存Cookie数据
-     * @access public
-     * @param  string $name  cookie名称
-     * @param  mixed  $value cookie值
-     * @param  mixed  $option 可选参数 可能会是 null|integer|string
-     * @return void
-     */
-    public function forever($name, $value = '', $option = null)
-    {
-        if (is_null($option) || is_numeric($option)) {
-            $option = [];
-        }
-
-        $option['expire'] = 315360000;
-
-        $this->set($name, $value, $option);
-    }
-
-    /**
-     * 判断Cookie数据
-     * @access public
-     * @param  string        $name cookie名称
-     * @param  string|null   $prefix cookie前缀
-     * @return bool
-     */
-    public function has($name, $prefix = null)
-    {
-        !isset($this->init) && $this->init();
-
-        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
-        $name   = $prefix . $name;
-
-        return isset($_COOKIE[$name]);
-    }
-
-    /**
-     * Cookie获取
-     * @access public
-     * @param  string        $name cookie名称 留空获取全部
-     * @param  string|null   $prefix cookie前缀
-     * @return mixed
-     */
-    public function get($name = '', $prefix = null)
-    {
-        !isset($this->init) && $this->init();
-
-        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
-        $key    = $prefix . $name;
-
-        if ('' == $name) {
-            if ($prefix) {
-                $value = [];
-                foreach ($_COOKIE as $k => $val) {
-                    if (0 === strpos($k, $prefix)) {
-                        $value[$k] = $val;
-                    }
-                }
-            } else {
-                $value = $_COOKIE;
-            }
-        } elseif (isset($_COOKIE[$key])) {
-            $value = $_COOKIE[$key];
-
-            if (0 === strpos($value, 'think:')) {
-                $value = substr($value, 6);
-                $value = json_decode($value, true);
-                array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'decode');
-            }
-        } else {
-            $value = null;
-        }
-
-        return $value;
-    }
-
-    /**
-     * Cookie删除
-     * @access public
-     * @param  string        $name cookie名称
-     * @param  string|null   $prefix cookie前缀
-     * @return void
-     */
-    public function delete($name, $prefix = null)
-    {
-        !isset($this->init) && $this->init();
-
-        $config = $this->config;
-        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
-        $name   = $prefix . $name;
-
-        if ($config['setcookie']) {
-            setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
-        }
-
-        // 删除指定cookie
-        unset($_COOKIE[$name]);
-    }
-
-    /**
-     * Cookie清空
-     * @access public
-     * @param  string|null $prefix cookie前缀
-     * @return void
-     */
-    public function clear($prefix = null)
-    {
-        // 清除指定前缀的所有cookie
-        if (empty($_COOKIE)) {
-            return;
-        }
-
-        !isset($this->init) && $this->init();
-
-        // 要删除的cookie前缀,不指定则删除config设置的指定前缀
-        $config = $this->config;
-        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
-
-        if ($prefix) {
-            // 如果前缀为空字符串将不作处理直接返回
-            foreach ($_COOKIE as $key => $val) {
-                if (0 === strpos($key, $prefix)) {
-                    if ($config['setcookie']) {
-                        setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
-                    }
-                    unset($_COOKIE[$key]);
-                }
-            }
-        }
-
-        return;
-    }
-
-    private function jsonFormatProtect(&$val, $key, $type = 'encode')
-    {
-        if (!empty($val) && true !== $val) {
-            $val = 'decode' == $type ? urldecode($val) : urlencode($val);
-        }
-    }
-
-}

+ 0 - 72
thinkphp/library/think/Db.php

@@ -1,72 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-/**
- * Class Db
- * @package think
- * @method \think\db\Query connect(array $config =[], mixed $name = false) static 连接/切换数据库连接
- * @method \think\db\Query master() 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 查询条件
- * @method \think\db\Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询
- * @method \think\db\Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询
- * @method \think\db\Query union(mixed $union, boolean $all = false) static UNION查询
- * @method \think\db\Query limit(mixed $offset, integer $length = null) static 查询LIMIT
- * @method \think\db\Query order(mixed $field, string $order = null) static 查询ORDER
- * @method \think\db\Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存
- * @method mixed value(string $field) static 获取某个字段的值
- * @method array column(string $field, string $key = '') static 获取某个列的值
- * @method mixed find(mixed $data = null) static 查询单个记录
- * @method mixed select(mixed $data = null) static 查询多个记录
- * @method integer insert(array $data, boolean $replace = false, boolean $getLastInsID = false, string $sequence = null) static 插入一条记录
- * @method integer insertGetId(array $data, boolean $replace = false, string $sequence = null) static 插入一条记录并返回自增ID
- * @method integer insertAll(array $dataSet) static 插入多条记录
- * @method integer update(array $data) static 更新记录
- * @method integer delete(mixed $data = null) static 删除记录
- * @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据
- * @method \Generator cursor(mixed $data = null) static 使用游标查找记录
- * @method mixed query(string $sql, array $bind = [], boolean $master = false, bool $pdo = false) static SQL查询
- * @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行
- * @method \think\Paginator paginate(integer $listRows = 15, mixed $simple = null, array $config = []) static 分页查询
- * @method mixed transaction(callable $callback) static 执行数据库事务
- * @method void startTrans() static 启动事务
- * @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 获取数据库的配置参数
- */
-class Db
-{
-    /**
-     * 查询次数
-     * @var integer
-     */
-    public static $queryTimes = 0;
-
-    /**
-     * 执行次数
-     * @var integer
-     */
-    public static $executeTimes = 0;
-
-    public static function __callStatic($method, $args)
-    {
-        $class = Container::get('config')->get('database.query') ?: '\\think\\db\\Query';
-
-        $query = new $class();
-
-        return call_user_func_array([$query, $method], $args);
-    }
-}

+ 0 - 258
thinkphp/library/think/Debug.php

@@ -1,258 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ClassNotFoundException;
-use think\model\Collection as ModelCollection;
-use think\response\Redirect;
-
-class Debug
-{
-    /**
-     * 区间时间信息
-     * @var array
-     */
-    protected $info = [];
-
-    /**
-     * 区间内存信息
-     * @var array
-     */
-    protected $mem = [];
-
-    /**
-     * 应用对象
-     * @var App
-     */
-    protected $app;
-
-    public function __construct(App $app)
-    {
-        $this->app = $app;
-    }
-
-    /**
-     * 记录时间(微秒)和内存使用情况
-     * @access public
-     * @param  string    $name 标记位置
-     * @param  mixed     $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存
-     * @return void
-     */
-    public function remark($name, $value = '')
-    {
-        // 记录时间和内存使用
-        $this->info[$name] = is_float($value) ? $value : microtime(true);
-
-        if ('time' != $value) {
-            $this->mem['mem'][$name]  = is_float($value) ? $value : memory_get_usage();
-            $this->mem['peak'][$name] = memory_get_peak_usage();
-        }
-    }
-
-    /**
-     * 统计某个区间的时间(微秒)使用情况
-     * @access public
-     * @param  string            $start 开始标签
-     * @param  string            $end 结束标签
-     * @param  integer|string    $dec 小数位
-     * @return integer
-     */
-    public function getRangeTime($start, $end, $dec = 6)
-    {
-        if (!isset($this->info[$end])) {
-            $this->info[$end] = microtime(true);
-        }
-
-        return number_format(($this->info[$end] - $this->info[$start]), $dec);
-    }
-
-    /**
-     * 统计从开始到统计时的时间(微秒)使用情况
-     * @access public
-     * @param  integer|string $dec 小数位
-     * @return integer
-     */
-    public function getUseTime($dec = 6)
-    {
-        return number_format((microtime(true) - $this->app->getBeginTime()), $dec);
-    }
-
-    /**
-     * 获取当前访问的吞吐率情况
-     * @access public
-     * @return string
-     */
-    public function getThroughputRate()
-    {
-        return number_format(1 / $this->getUseTime(), 2) . 'req/s';
-    }
-
-    /**
-     * 记录区间的内存使用情况
-     * @access public
-     * @param  string            $start 开始标签
-     * @param  string            $end 结束标签
-     * @param  integer|string    $dec 小数位
-     * @return string
-     */
-    public function getRangeMem($start, $end, $dec = 2)
-    {
-        if (!isset($this->mem['mem'][$end])) {
-            $this->mem['mem'][$end] = memory_get_usage();
-        }
-
-        $size = $this->mem['mem'][$end] - $this->mem['mem'][$start];
-        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
-        $pos  = 0;
-
-        while ($size >= 1024) {
-            $size /= 1024;
-            $pos++;
-        }
-
-        return round($size, $dec) . " " . $a[$pos];
-    }
-
-    /**
-     * 统计从开始到统计时的内存使用情况
-     * @access public
-     * @param  integer|string $dec 小数位
-     * @return string
-     */
-    public function getUseMem($dec = 2)
-    {
-        $size = memory_get_usage() - $this->app->getBeginMem();
-        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
-        $pos  = 0;
-
-        while ($size >= 1024) {
-            $size /= 1024;
-            $pos++;
-        }
-
-        return round($size, $dec) . " " . $a[$pos];
-    }
-
-    /**
-     * 统计区间的内存峰值情况
-     * @access public
-     * @param  string            $start 开始标签
-     * @param  string            $end 结束标签
-     * @param  integer|string    $dec 小数位
-     * @return string
-     */
-    public function getMemPeak($start, $end, $dec = 2)
-    {
-        if (!isset($this->mem['peak'][$end])) {
-            $this->mem['peak'][$end] = memory_get_peak_usage();
-        }
-
-        $size = $this->mem['peak'][$end] - $this->mem['peak'][$start];
-        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
-        $pos  = 0;
-
-        while ($size >= 1024) {
-            $size /= 1024;
-            $pos++;
-        }
-
-        return round($size, $dec) . " " . $a[$pos];
-    }
-
-    /**
-     * 获取文件加载信息
-     * @access public
-     * @param  bool  $detail 是否显示详细
-     * @return integer|array
-     */
-    public function getFile($detail = false)
-    {
-        if ($detail) {
-            $files = get_included_files();
-            $info  = [];
-
-            foreach ($files as $key => $file) {
-                $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )';
-            }
-
-            return $info;
-        }
-
-        return count(get_included_files());
-    }
-
-    /**
-     * 浏览器友好的变量输出
-     * @access public
-     * @param  mixed         $var 变量
-     * @param  boolean       $echo 是否输出 默认为true 如果为false 则返回输出字符串
-     * @param  string        $label 标签 默认为空
-     * @param  integer       $flags htmlspecialchars flags
-     * @return void|string
-     */
-    public function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE)
-    {
-        $label = (null === $label) ? '' : rtrim($label) . ':';
-        if ($var instanceof Model || $var instanceof ModelCollection) {
-            $var = $var->toArray();
-        }
-
-        ob_start();
-        var_dump($var);
-
-        $output = ob_get_clean();
-        $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
-
-        if (PHP_SAPI == 'cli') {
-            $output = PHP_EOL . $label . $output . PHP_EOL;
-        } else {
-            if (!extension_loaded('xdebug')) {
-                $output = htmlspecialchars($output, $flags);
-            }
-            $output = '<pre>' . $label . $output . '</pre>';
-        }
-        if ($echo) {
-            echo($output);
-            return;
-        }
-        return $output;
-    }
-
-    public function inject(Response $response, &$content)
-    {
-        $config = $this->app['config']->pull('trace');
-        $type   = isset($config['type']) ? $config['type'] : 'Html';
-        $class  = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type);
-        unset($config['type']);
-
-        if (class_exists($class)) {
-            $trace = new $class($config);
-        } else {
-            throw new ClassNotFoundException('class not exists:' . $class, $class);
-        }
-
-        if ($response instanceof Redirect) {
-            //TODO 记录
-        } else {
-            $output = $trace->output($response, $this->app['log']->getLog());
-            if (is_string($output)) {
-                // trace调试信息注入
-                $pos = strripos($content, '</body>');
-                if (false !== $pos) {
-                    $content = substr($content, 0, $pos) . $output . substr($content, $pos);
-                } else {
-                    $content = $content . $output;
-                }
-            }
-        }
-    }
-}

+ 0 - 109
thinkphp/library/think/Env.php

@@ -1,109 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Env
-{
-    /**
-     * 环境变量数据
-     * @var array
-     */
-    protected $data = [];
-
-    public function __construct()
-    {
-        $this->data = $_ENV;
-    }
-
-    /**
-     * 读取环境变量定义文件
-     * @access public
-     * @param  string    $file  环境变量定义文件
-     * @return void
-     */
-    public function load($file)
-    {
-        $env = parse_ini_file($file, true);
-        $this->set($env);
-    }
-
-    /**
-     * 获取环境变量值
-     * @access public
-     * @param  string    $name 环境变量名
-     * @param  mixed     $default  默认值
-     * @return mixed
-     */
-    public function get($name = null, $default = null)
-    {
-        if (is_null($name)) {
-            return $this->data;
-        }
-
-        $name = strtoupper(str_replace('.', '_', $name));
-
-        if (isset($this->data[$name])) {
-            return $this->data[$name];
-        }
-
-        return $this->getEnv($name, $default);
-    }
-
-    protected function getEnv($name, $default = null)
-    {
-        $result = getenv('PHP_' . $name);
-
-        if (false === $result) {
-            return $default;
-        }
-
-        if ('false' === $result) {
-            $result = false;
-        } elseif ('true' === $result) {
-            $result = true;
-        }
-
-        if (!isset($this->data[$name])) {
-            $this->data[$name] = $result;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 设置环境变量值
-     * @access public
-     * @param  string|array  $env   环境变量
-     * @param  mixed         $value  值
-     * @return void
-     */
-    public function set($env, $value = null)
-    {
-        if (is_array($env)) {
-            $env = array_change_key_case($env, CASE_UPPER);
-
-            foreach ($env as $key => $val) {
-                if (is_array($val)) {
-                    foreach ($val as $k => $v) {
-                        $this->data[$key . '_' . strtoupper($k)] = $v;
-                    }
-                } else {
-                    $this->data[$key] = $val;
-                }
-            }
-        } else {
-            $name = strtoupper(str_replace('.', '_', $env));
-
-            $this->data[$name] = $value;
-        }
-    }
-}

+ 0 - 128
thinkphp/library/think/Error.php

@@ -1,128 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\console\Output as ConsoleOutput;
-use think\exception\ErrorException;
-use think\exception\Handle;
-use think\exception\ThrowableError;
-
-class Error
-{
-    /**
-     * 注册异常处理
-     * @access public
-     * @return void
-     */
-    public static function register()
-    {
-        error_reporting(E_ALL);
-        set_error_handler([__CLASS__, 'appError']);
-        set_exception_handler([__CLASS__, 'appException']);
-        register_shutdown_function([__CLASS__, 'appShutdown']);
-    }
-
-    /**
-     * Exception Handler
-     * @access public
-     * @param  \Exception|\Throwable $e
-     */
-    public static function appException($e)
-    {
-        if (!$e instanceof \Exception) {
-            $e = new ThrowableError($e);
-        }
-
-        self::getExceptionHandler()->report($e);
-
-        if (PHP_SAPI == 'cli') {
-            self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
-        } else {
-            self::getExceptionHandler()->render($e)->send();
-        }
-    }
-
-    /**
-     * Error Handler
-     * @access public
-     * @param  integer $errno   错误编号
-     * @param  integer $errstr  详细错误信息
-     * @param  string  $errfile 出错的文件
-     * @param  integer $errline 出错行号
-     * @throws ErrorException
-     */
-    public static function appError($errno, $errstr, $errfile = '', $errline = 0)
-    {
-        $exception = new ErrorException($errno, $errstr, $errfile, $errline);
-        if (error_reporting() & $errno) {
-            // 将错误信息托管至 think\exception\ErrorException
-            throw $exception;
-        }
-
-        self::getExceptionHandler()->report($exception);
-    }
-
-    /**
-     * Shutdown Handler
-     * @access public
-     */
-    public static function appShutdown()
-    {
-        if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
-            // 将错误信息托管至think\ErrorException
-            $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']);
-
-            self::appException($exception);
-        }
-
-        // 写入日志
-        Container::get('log')->save();
-    }
-
-    /**
-     * 确定错误类型是否致命
-     *
-     * @access protected
-     * @param  int $type
-     * @return bool
-     */
-    protected static function isFatal($type)
-    {
-        return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);
-    }
-
-    /**
-     * Get an instance of the exception handler.
-     *
-     * @access public
-     * @return Handle
-     */
-    public static function getExceptionHandler()
-    {
-        static $handle;
-
-        if (!$handle) {
-            // 异常处理handle
-            $class = Container::get('config')->get('exception_handle');
-            if ($class && is_string($class) && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) {
-                $handle = new $class;
-            } else {
-                $handle = new Handle;
-                if ($class instanceof \Closure) {
-                    $handle->setRender($class);
-                }
-            }
-        }
-
-        return $handle;
-    }
-}

+ 0 - 56
thinkphp/library/think/Exception.php

@@ -1,56 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Exception extends \Exception
-{
-
-    /**
-     * 保存异常页面显示的额外Debug数据
-     * @var array
-     */
-    protected $data = [];
-
-    /**
-     * 设置异常额外的Debug数据
-     * 数据将会显示为下面的格式
-     *
-     * Exception Data
-     * --------------------------------------------------
-     * Label 1
-     *   key1      value1
-     *   key2      value2
-     * Label 2
-     *   key1      value1
-     *   key2      value2
-     *
-     * @access protected
-     * @param  string $label 数据分类,用于异常页面显示
-     * @param  array  $data  需要显示的数据,必须为关联数组
-     */
-    final protected function setData($label, array $data)
-    {
-        $this->data[$label] = $data;
-    }
-
-    /**
-     * 获取异常额外Debug数据
-     * 主要用于输出到异常页面便于调试
-     * @access public
-     * @return array 由setData设置的Debug数据
-     */
-    final public function getData()
-    {
-        return $this->data;
-    }
-
-}

+ 0 - 126
thinkphp/library/think/Facade.php

@@ -1,126 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Facade
-{
-    /**
-     * 绑定对象
-     * @var array
-     */
-    protected static $bind = [];
-
-    /**
-     * 始终创建新的对象实例
-     * @var bool
-     */
-    protected static $alwaysNewInstance;
-
-    /**
-     * 绑定类的静态代理
-     * @static
-     * @access public
-     * @param  string|array  $name    类标识
-     * @param  string        $class   类名
-     * @return object
-     */
-    public static function bind($name, $class = null)
-    {
-        if (__CLASS__ != static::class) {
-            return self::__callStatic('bind', func_get_args());
-        }
-
-        if (is_array($name)) {
-            self::$bind = array_merge(self::$bind, $name);
-        } else {
-            self::$bind[$name] = $class;
-        }
-    }
-
-    /**
-     * 创建Facade实例
-     * @static
-     * @access protected
-     * @param  string    $class          类名或标识
-     * @param  array     $args           变量
-     * @param  bool      $newInstance    是否每次创建新的实例
-     * @return object
-     */
-    protected static function createFacade($class = '', $args = [], $newInstance = false)
-    {
-        $class       = $class ?: static::class;
-        $facadeClass = static::getFacadeClass();
-
-        if ($facadeClass) {
-            $class = $facadeClass;
-        } elseif (isset(self::$bind[$class])) {
-            $class = self::$bind[$class];
-        }
-
-        if (static::$alwaysNewInstance) {
-            $newInstance = true;
-        }
-
-        return Container::getInstance()->make($class, $args, $newInstance);
-    }
-
-    /**
-     * 获取当前Facade对应类名
-     * @access protected
-     * @return string
-     */
-    protected static function getFacadeClass()
-    {}
-
-    /**
-     * 带参数实例化当前Facade类
-     * @access public
-     * @return object
-     */
-    public static function instance(...$args)
-    {
-        if (__CLASS__ != static::class) {
-            return self::__callStatic('instance', $args);
-        }
-
-        return self::createFacade('', $args);
-    }
-
-    /**
-     * 调用类的实例
-     * @access public
-     * @param  string        $class          类名或者标识
-     * @param  array|true    $args           变量
-     * @param  bool          $newInstance    是否每次创建新的实例
-     * @return object
-     */
-    public static function make($class, $args = [], $newInstance = false)
-    {
-        if (__CLASS__ != static::class) {
-            return self::__callStatic('make', func_get_args());
-        }
-
-        if (true === $args) {
-            // 总是创建新的实例化对象
-            $newInstance = true;
-            $args        = [];
-        }
-
-        return self::createFacade($class, $args, $newInstance);
-    }
-
-    // 调用实际类的方法
-    public static function __callStatic($method, $params)
-    {
-        return call_user_func_array([static::createFacade(), $method], $params);
-    }
-}

+ 0 - 494
thinkphp/library/think/File.php

@@ -1,494 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use SplFileObject;
-
-class File extends SplFileObject
-{
-    /**
-     * 错误信息
-     * @var string
-     */
-    private $error = '';
-
-    /**
-     * 当前完整文件名
-     * @var string
-     */
-    protected $filename;
-
-    /**
-     * 上传文件名
-     * @var string
-     */
-    protected $saveName;
-
-    /**
-     * 上传文件命名规则
-     * @var string
-     */
-    protected $rule = 'date';
-
-    /**
-     * 上传文件验证规则
-     * @var array
-     */
-    protected $validate = [];
-
-    /**
-     * 是否单元测试
-     * @var bool
-     */
-    protected $isTest;
-
-    /**
-     * 上传文件信息
-     * @var array
-     */
-    protected $info = [];
-
-    /**
-     * 文件hash规则
-     * @var array
-     */
-    protected $hash = [];
-
-    public function __construct($filename, $mode = 'r')
-    {
-        parent::__construct($filename, $mode);
-
-        $this->filename = $this->getRealPath() ?: $this->getPathname();
-    }
-
-    /**
-     * 是否测试
-     * @access public
-     * @param  bool   $test 是否测试
-     * @return $this
-     */
-    public function isTest($test = false)
-    {
-        $this->isTest = $test;
-
-        return $this;
-    }
-
-    /**
-     * 设置上传信息
-     * @access public
-     * @param  array   $info 上传文件信息
-     * @return $this
-     */
-    public function setUploadInfo($info)
-    {
-        $this->info = $info;
-
-        return $this;
-    }
-
-    /**
-     * 获取上传文件的信息
-     * @access public
-     * @param  string   $name
-     * @return array|string
-     */
-    public function getInfo($name = '')
-    {
-        return isset($this->info[$name]) ? $this->info[$name] : $this->info;
-    }
-
-    /**
-     * 获取上传文件的文件名
-     * @access public
-     * @return string
-     */
-    public function getSaveName()
-    {
-        return $this->saveName;
-    }
-
-    /**
-     * 设置上传文件的保存文件名
-     * @access public
-     * @param  string   $saveName
-     * @return $this
-     */
-    public function setSaveName($saveName)
-    {
-        $this->saveName = $saveName;
-
-        return $this;
-    }
-
-    /**
-     * 获取文件的哈希散列值
-     * @access public
-     * @param  string $type
-     * @return string
-     */
-    public function hash($type = 'sha1')
-    {
-        if (!isset($this->hash[$type])) {
-            $this->hash[$type] = hash_file($type, $this->filename);
-        }
-
-        return $this->hash[$type];
-    }
-
-    /**
-     * 检查目录是否可写
-     * @access protected
-     * @param  string   $path    目录
-     * @return boolean
-     */
-    protected function checkPath($path)
-    {
-        if (is_dir($path)) {
-            return true;
-        }
-
-        if (mkdir($path, 0755, true)) {
-            return true;
-        }
-
-        $this->error = ['directory {:path} creation failed', ['path' => $path]];
-        return false;
-    }
-
-    /**
-     * 获取文件类型信息
-     * @access public
-     * @return string
-     */
-    public function getMime()
-    {
-        $finfo = finfo_open(FILEINFO_MIME_TYPE);
-
-        return finfo_file($finfo, $this->filename);
-    }
-
-    /**
-     * 设置文件的命名规则
-     * @access public
-     * @param  string   $rule    文件命名规则
-     * @return $this
-     */
-    public function rule($rule)
-    {
-        $this->rule = $rule;
-
-        return $this;
-    }
-
-    /**
-     * 设置上传文件的验证规则
-     * @access public
-     * @param  array   $rule    验证规则
-     * @return $this
-     */
-    public function validate($rule = [])
-    {
-        $this->validate = $rule;
-
-        return $this;
-    }
-
-    /**
-     * 检测是否合法的上传文件
-     * @access public
-     * @return bool
-     */
-    public function isValid()
-    {
-        if ($this->isTest) {
-            return is_file($this->filename);
-        }
-
-        return is_uploaded_file($this->filename);
-    }
-
-    /**
-     * 检测上传文件
-     * @access public
-     * @param  array   $rule    验证规则
-     * @return bool
-     */
-    public function check($rule = [])
-    {
-        $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()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 检测上传文件后缀
-     * @access public
-     * @param  array|string   $ext    允许后缀
-     * @return bool
-     */
-    public function checkExt($ext)
-    {
-        if (is_string($ext)) {
-            $ext = explode(',', $ext);
-        }
-
-        $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
-
-        if (!in_array($extension, $ext)) {
-            $this->error = 'extensions to upload is not allowed';
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 检测图像文件
-     * @access public
-     * @return bool
-     */
-    public function checkImg()
-    {
-        $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
-
-        /* 对图像文件进行严格检测 */
-        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;
-        }
-
-        return true;
-    }
-
-    // 判断图像类型
-    protected function getImageType($image)
-    {
-        if (function_exists('exif_imagetype')) {
-            return exif_imagetype($image);
-        }
-
-        try {
-            $info = getimagesize($image);
-            return $info ? $info[2] : false;
-        } catch (\Exception $e) {
-            return false;
-        }
-    }
-
-    /**
-     * 检测上传文件大小
-     * @access public
-     * @param  integer   $size    最大大小
-     * @return bool
-     */
-    public function checkSize($size)
-    {
-        if ($this->getSize() > $size) {
-            $this->error = 'filesize not match';
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 检测上传文件类型
-     * @access public
-     * @param  array|string   $mime    允许类型
-     * @return bool
-     */
-    public function checkMime($mime)
-    {
-        if (is_string($mime)) {
-            $mime = explode(',', $mime);
-        }
-
-        if (!in_array(strtolower($this->getMime()), $mime)) {
-            $this->error = 'mimetype to upload is not allowed';
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 移动文件
-     * @access public
-     * @param  string           $path    保存路径
-     * @param  string|bool      $savename    保存的文件名 默认自动生成
-     * @param  boolean          $replace 同名文件是否覆盖
-     * @return false|File       false-失败 否则返回File实例
-     */
-    public function move($path, $savename = true, $replace = true)
-    {
-        // 文件上传失败,捕获错误代码
-        if (!empty($this->info['error'])) {
-            $this->error($this->info['error']);
-            return false;
-        }
-
-        // 检测合法性
-        if (!$this->isValid()) {
-            $this->error = 'upload illegal files';
-            return false;
-        }
-
-        // 验证上传
-        if (!$this->check()) {
-            return false;
-        }
-
-        $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
-        // 文件保存命名规则
-        $saveName = $this->buildSaveName($savename);
-        $filename = $path . $saveName;
-
-        // 检测目录
-        if (false === $this->checkPath(dirname($filename))) {
-            return false;
-        }
-
-        /* 不覆盖同名文件 */
-        if (!$replace && is_file($filename)) {
-            $this->error = ['has the same filename: {:filename}', ['filename' => $filename]];
-            return false;
-        }
-
-        /* 移动文件 */
-        if ($this->isTest) {
-            rename($this->filename, $filename);
-        } elseif (!move_uploaded_file($this->filename, $filename)) {
-            $this->error = 'upload write error';
-            return false;
-        }
-
-        // 返回 File对象实例
-        $file = new self($filename);
-        $file->setSaveName($saveName);
-        $file->setUploadInfo($this->info);
-
-        return $file;
-    }
-
-    /**
-     * 获取保存文件名
-     * @access protected
-     * @param  string|bool   $savename    保存的文件名 默认自动生成
-     * @return string
-     */
-    protected function buildSaveName($savename)
-    {
-        if (true === $savename) {
-            // 自动生成文件名
-            $savename = $this->autoBuildName();
-        } elseif ('' === $savename || false === $savename) {
-            // 保留原文件名
-            $savename = $this->getInfo('name');
-        }
-
-        if (!strpos($savename, '.')) {
-            $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);
-        }
-
-        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
-     * @param  int $errorNo  错误号
-     */
-    private function error($errorNo)
-    {
-        switch ($errorNo) {
-            case 1:
-            case 2:
-                $this->error = 'upload File size exceeds the maximum value';
-                break;
-            case 3:
-                $this->error = 'only the portion of file is uploaded';
-                break;
-            case 4:
-                $this->error = 'no file to uploaded';
-                break;
-            case 6:
-                $this->error = 'upload temp dir not found';
-                break;
-            case 7:
-                $this->error = 'file write error';
-                break;
-            default:
-                $this->error = 'unknown upload error';
-        }
-    }
-
-    /**
-     * 获取错误信息(支持多语言)
-     * @access public
-     * @return string
-     */
-    public function getError()
-    {
-        $lang = Container::get('lang');
-
-        if (is_array($this->error)) {
-            list($msg, $vars) = $this->error;
-        } else {
-            $msg  = $this->error;
-            $vars = [];
-        }
-
-        return $lang->has($msg) ? $lang->get($msg, $vars) : $msg;
-    }
-
-    public function __call($method, $args)
-    {
-        return $this->hash($method);
-    }
-}

+ 0 - 212
thinkphp/library/think/Hook.php

@@ -1,212 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Hook
-{
-    /**
-     * 钩子行为定义
-     * @var array
-     */
-    private $tags = [];
-
-    /**
-     * 绑定行为列表
-     * @var array
-     */
-    protected $bind = [];
-
-    /**
-     * 入口方法名称
-     * @var string
-     */
-    private static $portal = 'run';
-
-    /**
-     * 指定入口方法名称
-     * @access public
-     * @param  string  $name     方法名
-     * @return $this
-     */
-    public function portal($name)
-    {
-        self::$portal = $name;
-        return $this;
-    }
-
-    /**
-     * 指定行为标识 便于调用
-     * @access public
-     * @param  string|array  $name     行为标识
-     * @param  mixed         $behavior 行为
-     * @return $this
-     */
-    public function alias($name, $behavior = null)
-    {
-        if (is_array($name)) {
-            $this->bind = array_merge($this->bind, $name);
-        } else {
-            $this->bind[$name] = $behavior;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 动态添加行为扩展到某个标签
-     * @access public
-     * @param  string    $tag 标签名称
-     * @param  mixed     $behavior 行为名称
-     * @param  bool      $first 是否放到开头执行
-     * @return void
-     */
-    public function add($tag, $behavior, $first = false)
-    {
-        isset($this->tags[$tag]) || $this->tags[$tag] = [];
-
-        if (is_array($behavior) && !is_callable($behavior)) {
-            if (!array_key_exists('_overlay', $behavior)) {
-                $this->tags[$tag] = array_merge($this->tags[$tag], $behavior);
-            } else {
-                unset($behavior['_overlay']);
-                $this->tags[$tag] = $behavior;
-            }
-        } elseif ($first) {
-            array_unshift($this->tags[$tag], $behavior);
-        } else {
-            $this->tags[$tag][] = $behavior;
-        }
-    }
-
-    /**
-     * 批量导入插件
-     * @access public
-     * @param  array     $tags 插件信息
-     * @param  bool      $recursive 是否递归合并
-     * @return void
-     */
-    public function import(array $tags, $recursive = true)
-    {
-        if ($recursive) {
-            foreach ($tags as $tag => $behavior) {
-                $this->add($tag, $behavior);
-            }
-        } else {
-            $this->tags = $tags + $this->tags;
-        }
-    }
-
-    /**
-     * 获取插件信息
-     * @access public
-     * @param  string $tag 插件位置 留空获取全部
-     * @return array
-     */
-    public function get($tag = '')
-    {
-        if (empty($tag)) {
-            //获取全部的插件信息
-            return $this->tags;
-        }
-
-        return array_key_exists($tag, $this->tags) ? $this->tags[$tag] : [];
-    }
-
-    /**
-     * 监听标签的行为
-     * @access public
-     * @param  string $tag    标签名称
-     * @param  mixed  $params 传入参数
-     * @param  bool   $once   只获取一个有效返回值
-     * @return mixed
-     */
-    public function listen($tag, $params = null, $once = false)
-    {
-        $results = [];
-        $tags    = $this->get($tag);
-
-        foreach ($tags as $key => $name) {
-            $results[$key] = $this->execTag($name, $tag, $params);
-
-            if (false === $results[$key] || (!is_null($results[$key]) && $once)) {
-                break;
-            }
-        }
-
-        return $once ? end($results) : $results;
-    }
-
-    /**
-     * 执行行为
-     * @access public
-     * @param  mixed     $class  行为
-     * @param  mixed     $params 参数
-     * @return mixed
-     */
-    public function exec($class, $params = null)
-    {
-        if ($class instanceof \Closure || is_array($class)) {
-            $method = $class;
-        } else {
-            if (isset($this->bind[$class])) {
-                $class = $this->bind[$class];
-            }
-            $method = [$class, self::$portal];
-        }
-
-        return Container::getInstance()->invoke($method, [$params]);
-    }
-
-    /**
-     * 执行某个标签的行为
-     * @access protected
-     * @param  mixed     $class  要执行的行为
-     * @param  string    $tag    方法名(标签名)
-     * @param  mixed     $params 参数
-     * @return mixed
-     */
-    protected function execTag($class, $tag = '', $params = null)
-    {
-        $app = Container::get('app');
-
-        $app->isDebug() && $app['debug']->remark('behavior_start', 'time');
-
-        $method = Loader::parseName($tag, 1, false);
-
-        if ($class instanceof \Closure) {
-            $call  = $class;
-            $class = 'Closure';
-        } elseif (strpos($class, '::')) {
-            $call = $class;
-        } else {
-            $obj = Container::get($class);
-
-            if (!is_callable([$obj, $method])) {
-                $method = self::$portal;
-            }
-
-            $call  = [$class, $method];
-            $class = $class . '->' . $method;
-        }
-
-        $result = Container::getInstance()->invoke($call, [$params]);
-
-        if ($app->isDebug()) {
-            $debug = $app['debug'];
-            $debug->remark('behavior_end', 'time');
-            $app->log('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . $debug->getRangeTime('behavior_start', 'behavior_end') . 's ]');
-        }
-
-        return $result;
-    }
-
-}

+ 0 - 265
thinkphp/library/think/Lang.php

@@ -1,265 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Lang
-{
-    /**
-     * 多语言信息
-     * @var array
-     */
-    private $lang = [];
-
-    /**
-     * 当前语言
-     * @var string
-     */
-    private $range = 'zh-cn';
-
-    /**
-     * 多语言自动侦测变量名
-     * @var string
-     */
-    protected $langDetectVar = 'lang';
-
-    /**
-     * 多语言cookie变量
-     * @var string
-     */
-    protected $langCookieVar = 'think_var';
-
-    /**
-     * 允许的多语言列表
-     * @var array
-     */
-    protected $allowLangList = [];
-
-    /**
-     * Accept-Language转义为对应语言包名称 系统默认配置
-     * @var string
-     */
-    protected $acceptLanguage = [
-        'zh-hans-cn' => 'zh-cn',
-    ];
-
-    // 设定当前的语言
-    public function range($range = '')
-    {
-        if ('' == $range) {
-            return $this->range;
-        } else {
-            $this->range = $range;
-        }
-    }
-
-    /**
-     * 设置语言定义(不区分大小写)
-     * @access public
-     * @param  string|array  $name 语言变量
-     * @param  string        $value 语言值
-     * @param  string        $range 语言作用域
-     * @return mixed
-     */
-    public function set($name, $value = null, $range = '')
-    {
-        $range = $range ?: $this->range;
-        // 批量定义
-        if (!isset($this->lang[$range])) {
-            $this->lang[$range] = [];
-        }
-
-        if (is_array($name)) {
-            return $this->lang[$range] = array_change_key_case($name) + $this->lang[$range];
-        }
-
-        return $this->lang[$range][strtolower($name)] = $value;
-    }
-
-    /**
-     * 加载语言定义(不区分大小写)
-     * @access public
-     * @param  string|array  $file   语言文件
-     * @param  string        $range  语言作用域
-     * @return array
-     */
-    public function load($file, $range = '')
-    {
-        $range = $range ?: $this->range;
-        if (!isset($this->lang[$range])) {
-            $this->lang[$range] = [];
-        }
-
-        // 批量定义
-        if (is_string($file)) {
-            $file = [$file];
-        }
-
-        $lang = [];
-
-        foreach ($file as $_file) {
-            if (is_file($_file)) {
-                // 记录加载信息
-                Container::get('app')->log('[ LANG ] ' . $_file);
-                $_lang = include $_file;
-                if (is_array($_lang)) {
-                    $lang = array_change_key_case($_lang) + $lang;
-                }
-            }
-        }
-
-        if (!empty($lang)) {
-            $this->lang[$range] = $lang + $this->lang[$range];
-        }
-
-        return $this->lang[$range];
-    }
-
-    /**
-     * 获取语言定义(不区分大小写)
-     * @access public
-     * @param  string|null   $name 语言变量
-     * @param  string        $range 语言作用域
-     * @return bool
-     */
-    public function has($name, $range = '')
-    {
-        $range = $range ?: $this->range;
-
-        return isset($this->lang[$range][strtolower($name)]);
-    }
-
-    /**
-     * 获取语言定义(不区分大小写)
-     * @access public
-     * @param  string|null   $name 语言变量
-     * @param  array         $vars 变量替换
-     * @param  string        $range 语言作用域
-     * @return mixed
-     */
-    public function get($name = null, $vars = [], $range = '')
-    {
-        $range = $range ?: $this->range;
-
-        // 空参数返回所有定义
-        if (empty($name)) {
-            return $this->lang[$range];
-        }
-
-        $key   = strtolower($name);
-        $value = isset($this->lang[$range][$key]) ? $this->lang[$range][$key] : $name;
-
-        // 变量解析
-        if (!empty($vars) && is_array($vars)) {
-            /**
-             * Notes:
-             * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0
-             * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数
-             */
-            if (key($vars) === 0) {
-                // 数字索引解析
-                array_unshift($vars, $value);
-                $value = call_user_func_array('sprintf', $vars);
-            } else {
-                // 关联索引解析
-                $replace = array_keys($vars);
-                foreach ($replace as &$v) {
-                    $v = "{:{$v}}";
-                }
-                $value = str_replace($replace, $vars, $value);
-            }
-        }
-
-        return $value;
-    }
-
-    /**
-     * 自动侦测设置获取语言选择
-     * @access public
-     * @return string
-     */
-    public function detect()
-    {
-        // 自动侦测设置获取语言选择
-        $langSet = '';
-
-        if (isset($_GET[$this->langDetectVar])) {
-            // url中设置了语言变量
-            $langSet = strtolower($_GET[$this->langDetectVar]);
-        } elseif (isset($_COOKIE[$this->langCookieVar])) {
-            // Cookie中设置了语言变量
-            $langSet = strtolower($_COOKIE[$this->langCookieVar]);
-        } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
-            // 自动侦测浏览器语言
-            preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
-            $langSet     = strtolower($matches[1]);
-            $acceptLangs = Container::get('config')->get('header_accept_lang');
-            if (isset($acceptLangs[$langSet])) {
-                $langSet = $acceptLangs[$langSet];
-            } elseif (isset($this->acceptLanguage[$langSet])) {
-                $langSet = $this->acceptLanguage[$langSet];
-            }
-        }
-
-        if (empty($this->allowLangList) || in_array($langSet, $this->allowLangList)) {
-            // 合法的语言
-            $this->range = $langSet ?: $this->range;
-        }
-
-        return $this->range;
-    }
-
-    /**
-     * 设置当前语言到Cookie
-     * @access public
-     * @param  string $lang 语言
-     * @return void
-     */
-    public function saveToCookie($lang = null)
-    {
-        $range = $lang ?: $this->range;
-
-        $_COOKIE[$this->langCookieVar] = $range;
-    }
-
-    /**
-     * 设置语言自动侦测的变量
-     * @access public
-     * @param  string $var 变量名称
-     * @return void
-     */
-    public function setLangDetectVar($var)
-    {
-        $this->langDetectVar = $var;
-    }
-
-    /**
-     * 设置语言的cookie保存变量
-     * @access public
-     * @param  string $var 变量名称
-     * @return void
-     */
-    public function setLangCookieVar($var)
-    {
-        $this->langCookieVar = $var;
-    }
-
-    /**
-     * 设置允许的语言列表
-     * @access public
-     * @param  array $list 语言列表
-     * @return void
-     */
-    public function setAllowLangList($list)
-    {
-        $this->allowLangList = $list;
-    }
-}

+ 0 - 405
thinkphp/library/think/Loader.php

@@ -1,405 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Loader
-{
-    /**
-     * 类名映射信息
-     * @var array
-     */
-    protected static $classMap = [];
-
-    /**
-     * 类库别名
-     * @var array
-     */
-    protected static $classAlias = [];
-
-    /**
-     * PSR-4
-     * @var array
-     */
-    private static $prefixLengthsPsr4 = [];
-    private static $prefixDirsPsr4    = [];
-    private static $fallbackDirsPsr4  = [];
-
-    /**
-     * PSR-0
-     * @var array
-     */
-    private static $prefixesPsr0     = [];
-    private static $fallbackDirsPsr0 = [];
-
-    /**
-     * 自动加载的文件列表
-     * @var array
-     */
-    private static $autoloadFiles = [];
-
-    /**
-     * Composer安装路径
-     * @var string
-     */
-    private static $composerPath;
-
-    // 获取应用根目录
-    public static function getRootPath()
-    {
-        if ('cli' == PHP_SAPI) {
-            $cwdPath = getcwd();
-
-            if (0 === strpos($_SERVER['argv'][0], $cwdPath)) {
-                $scriptName = $_SERVER['argv'][0];
-            } else {
-                $scriptName = $cwdPath . DIRECTORY_SEPARATOR . $_SERVER['argv'][0];
-            }
-        } else {
-            $scriptName = $_SERVER['SCRIPT_FILENAME'];
-        }
-
-        $path = realpath(dirname($scriptName));
-
-        if (!is_file($path . DIRECTORY_SEPARATOR . 'think')) {
-            $path = dirname($path);
-        }
-
-        return $path . DIRECTORY_SEPARATOR;
-    }
-
-    // 注册自动加载机制
-    public static function register($autoload = '')
-    {
-        // 注册系统自动加载
-        spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
-
-        $rootPath = self::getRootPath();
-
-        self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR;
-
-        // 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);
-
-                foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'prefixesPsr0', 'classMap'] as $attr) {
-                    if (property_exists($composerClass, $attr)) {
-                        self::${$attr} = $composerClass::${$attr};
-                    }
-                }
-            } 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'));
-        }
-
-        // 自动加载extend目录
-        self::addAutoLoadDir($rootPath . 'extend');
-    }
-
-    // 自动加载
-    public static function autoload($class)
-    {
-        if (isset(self::$classAlias[$class])) {
-            return class_alias(self::$classAlias[$class], $class);
-        }
-
-        if ($file = self::findFile($class)) {
-
-            // Win环境严格区分大小写
-            if (strpos(PHP_OS, 'WIN') !== false && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
-                return false;
-            }
-
-            __include_file($file);
-            return true;
-        }
-    }
-
-    /**
-     * 查找文件
-     * @access private
-     * @param  string $class
-     * @return string|false
-     */
-    private static function findFile($class)
-    {
-        if (!empty(self::$classMap[$class])) {
-            // 类库映射
-            return self::$classMap[$class];
-        }
-
-        // 查找 PSR-4
-        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
-
-        $first = $class[0];
-        if (isset(self::$prefixLengthsPsr4[$first])) {
-            foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
-                if (0 === strpos($class, $prefix)) {
-                    foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
-                        if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
-                            return $file;
-                        }
-                    }
-                }
-            }
-        }
-
-        // 查找 PSR-4 fallback dirs
-        foreach (self::$fallbackDirsPsr4 as $dir) {
-            if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
-                return $file;
-            }
-        }
-
-        // 查找 PSR-0
-        if (false !== $pos = strrpos($class, '\\')) {
-            // namespaced class name
-            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
-            . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
-        } else {
-            // PEAR-like class name
-            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . '.php';
-        }
-
-        if (isset(self::$prefixesPsr0[$first])) {
-            foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
-                if (0 === strpos($class, $prefix)) {
-                    foreach ($dirs as $dir) {
-                        if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
-                            return $file;
-                        }
-                    }
-                }
-            }
-        }
-
-        // 查找 PSR-0 fallback dirs
-        foreach (self::$fallbackDirsPsr0 as $dir) {
-            if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
-                return $file;
-            }
-        }
-
-        return self::$classMap[$class] = false;
-    }
-
-    // 注册classmap
-    public static function addClassMap($class, $map = '')
-    {
-        if (is_array($class)) {
-            self::$classMap = array_merge(self::$classMap, $class);
-        } else {
-            self::$classMap[$class] = $map;
-        }
-    }
-
-    // 注册命名空间
-    public static function addNamespace($namespace, $path = '')
-    {
-        if (is_array($namespace)) {
-            foreach ($namespace as $prefix => $paths) {
-                self::addPsr4($prefix . '\\', rtrim($paths, DIRECTORY_SEPARATOR), true);
-            }
-        } else {
-            self::addPsr4($namespace . '\\', rtrim($path, DIRECTORY_SEPARATOR), true);
-        }
-    }
-
-    // 添加Ps0空间
-    private static function addPsr0($prefix, $paths, $prepend = false)
-    {
-        if (!$prefix) {
-            if ($prepend) {
-                self::$fallbackDirsPsr0 = array_merge(
-                    (array) $paths,
-                    self::$fallbackDirsPsr0
-                );
-            } else {
-                self::$fallbackDirsPsr0 = array_merge(
-                    self::$fallbackDirsPsr0,
-                    (array) $paths
-                );
-            }
-
-            return;
-        }
-
-        $first = $prefix[0];
-        if (!isset(self::$prefixesPsr0[$first][$prefix])) {
-            self::$prefixesPsr0[$first][$prefix] = (array) $paths;
-
-            return;
-        }
-
-        if ($prepend) {
-            self::$prefixesPsr0[$first][$prefix] = array_merge(
-                (array) $paths,
-                self::$prefixesPsr0[$first][$prefix]
-            );
-        } else {
-            self::$prefixesPsr0[$first][$prefix] = array_merge(
-                self::$prefixesPsr0[$first][$prefix],
-                (array) $paths
-            );
-        }
-    }
-
-    // 添加Psr4空间
-    private static function addPsr4($prefix, $paths, $prepend = false)
-    {
-        if (!$prefix) {
-            // Register directories for the root namespace.
-            if ($prepend) {
-                self::$fallbackDirsPsr4 = array_merge(
-                    (array) $paths,
-                    self::$fallbackDirsPsr4
-                );
-            } else {
-                self::$fallbackDirsPsr4 = array_merge(
-                    self::$fallbackDirsPsr4,
-                    (array) $paths
-                );
-            }
-        } elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
-            // Register directories for a new namespace.
-            $length = strlen($prefix);
-            if ('\\' !== $prefix[$length - 1]) {
-                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
-            }
-
-            self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
-            self::$prefixDirsPsr4[$prefix]                = (array) $paths;
-        } elseif ($prepend) {
-            // Prepend directories for an already registered namespace.
-            self::$prefixDirsPsr4[$prefix] = array_merge(
-                (array) $paths,
-                self::$prefixDirsPsr4[$prefix]
-            );
-        } else {
-            // Append directories for an already registered namespace.
-            self::$prefixDirsPsr4[$prefix] = array_merge(
-                self::$prefixDirsPsr4[$prefix],
-                (array) $paths
-            );
-        }
-    }
-
-    // 注册自动加载类库目录
-    public static function addAutoLoadDir($path)
-    {
-        self::$fallbackDirsPsr4[] = $path;
-    }
-
-    // 注册类别名
-    public static function addClassAlias($alias, $class = null)
-    {
-        if (is_array($alias)) {
-            self::$classAlias = array_merge(self::$classAlias, $alias);
-        } else {
-            self::$classAlias[$alias] = $class;
-        }
-    }
-
-    // 注册composer自动加载
-    public static function registerComposerLoader($composerPath)
-    {
-        if (is_file($composerPath . 'autoload_namespaces.php')) {
-            $map = require $composerPath . 'autoload_namespaces.php';
-            foreach ($map as $namespace => $path) {
-                self::addPsr0($namespace, $path);
-            }
-        }
-
-        if (is_file($composerPath . 'autoload_psr4.php')) {
-            $map = require $composerPath . 'autoload_psr4.php';
-            foreach ($map as $namespace => $path) {
-                self::addPsr4($namespace, $path);
-            }
-        }
-
-        if (is_file($composerPath . 'autoload_classmap.php')) {
-            $classMap = require $composerPath . 'autoload_classmap.php';
-            if ($classMap) {
-                self::addClassMap($classMap);
-            }
-        }
-    }
-
-    // 加载composer autofile文件
-    public static function loadComposerAutoloadFiles()
-    {
-        if (is_file(self::$composerPath . 'autoload_files.php')) {
-            $includeFiles = require self::$composerPath . 'autoload_files.php';
-            foreach ($includeFiles as $fileIdentifier => $file) {
-                if (isset($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
-                    continue;
-                }
-
-                if (empty(self::$autoloadFiles[$fileIdentifier])) {
-                    __require_file($file);
-                    self::$autoloadFiles[$fileIdentifier] = true;
-                }
-            }
-        }
-    }
-
-    /**
-     * 字符串命名风格转换
-     * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
-     * @access public
-     * @param  string  $name 字符串
-     * @param  integer $type 转换类型
-     * @param  bool    $ucfirst 首字母是否大写(驼峰规则)
-     * @return string
-     */
-    public static function parseName($name, $type = 0, $ucfirst = true)
-    {
-        if ($type) {
-            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
-                return strtoupper($match[1]);
-            }, $name);
-            return $ucfirst ? ucfirst($name) : lcfirst($name);
-        }
-
-        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
-    }
-}
-
-/**
- * 作用范围隔离
- *
- * @param $file
- * @return mixed
- */
-function __include_file($file)
-{
-    return include $file;
-}
-
-function __require_file($file)
-{
-    return require $file;
-}

+ 0 - 398
thinkphp/library/think/Log.php

@@ -1,398 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ClassNotFoundException;
-
-class Log implements LoggerInterface
-{
-    const EMERGENCY = 'emergency';
-    const ALERT     = 'alert';
-    const CRITICAL  = 'critical';
-    const ERROR     = 'error';
-    const WARNING   = 'warning';
-    const NOTICE    = 'notice';
-    const INFO      = 'info';
-    const DEBUG     = 'debug';
-    const SQL       = 'sql';
-
-    /**
-     * 日志信息
-     * @var array
-     */
-    protected $log = [];
-
-    /**
-     * 配置参数
-     * @var array
-     */
-    protected $config = [];
-
-    /**
-     * 日志写入驱动
-     * @var object
-     */
-    protected $driver;
-
-    /**
-     * 日志授权key
-     * @var string
-     */
-    protected $key;
-
-    /**
-     * 是否允许日志写入
-     * @var bool
-     */
-    protected $allowWrite = true;
-
-    /**
-     * 应用对象
-     * @var App
-     */
-    protected $app;
-
-    public function __construct(App $app)
-    {
-        $this->app = $app;
-    }
-
-    /**
-     * 日志初始化
-     * @access public
-     * @param  array $config
-     * @return $this
-     */
-    public function init($config = [])
-    {
-        $type  = isset($config['type']) ? $config['type'] : 'File';
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type);
-
-        $this->config = $config;
-
-        unset($config['type']);
-        if (!empty($config['close'])) {
-            $this->allowWrite = false;
-        }
-
-        if (class_exists($class)) {
-            $this->driver = new $class($config);
-        } else {
-            throw new ClassNotFoundException('class not exists:' . $class, $class);
-        }
-
-        // 记录初始化信息
-        $this->app->isDebug() && $this->record('[ LOG ] INIT ' . $type);
-
-        return $this;
-    }
-
-    /**
-     * 获取日志信息
-     * @access public
-     * @param  string $type 信息类型
-     * @return array
-     */
-    public function getLog($type = '')
-    {
-        return $type ? $this->log[$type] : $this->log;
-    }
-
-    /**
-     * 记录日志信息
-     * @access public
-     * @param  mixed  $msg       日志信息
-     * @param  string $type      日志级别
-     * @param  array  $context   替换内容
-     * @return $this
-     */
-    public function record($msg, $type = 'info', array $context = [])
-    {
-        if (!$this->allowWrite) {
-            return;
-        }
-
-        if (is_string($msg)) {
-            $replace = [];
-            foreach ($context as $key => $val) {
-                $replace['{' . $key . '}'] = $val;
-            }
-
-            $msg = strtr($msg, $replace);
-        }
-
-        $this->log[$type][] = $msg;
-
-        if (PHP_SAPI == 'cli') {
-            // 命令行日志实时写入
-            $this->save();
-        }
-
-        return $this;
-    }
-
-    /**
-     * 清空日志信息
-     * @access public
-     * @return $this
-     */
-    public function clear()
-    {
-        $this->log = [];
-
-        return $this;
-    }
-
-    /**
-     * 当前日志记录的授权key
-     * @access public
-     * @param  string  $key  授权key
-     * @return $this
-     */
-    public function key($key)
-    {
-        $this->key = $key;
-
-        return $this;
-    }
-
-    /**
-     * 检查日志写入权限
-     * @access public
-     * @param  array  $config  当前日志配置参数
-     * @return bool
-     */
-    public function check($config)
-    {
-        if ($this->key && !empty($config['allow_key']) && !in_array($this->key, $config['allow_key'])) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 关闭本次请求日志写入
-     * @access public
-     * @return $this
-     */
-    public function close()
-    {
-        $this->allowWrite = false;
-        $this->log        = [];
-
-        return $this;
-    }
-
-    /**
-     * 保存调试信息
-     * @access public
-     * @return bool
-     */
-    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']);
-            }
-        } 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;
-    }
-
-    /**
-     * 实时写入日志信息 并支持行为
-     * @access public
-     * @param  mixed  $msg   调试信息
-     * @param  string $type  日志级别
-     * @param  bool   $force 是否强制写入
-     * @return bool
-     */
-    public function write($msg, $type = 'info', $force = false)
-    {
-        // 封装日志信息
-        $log = $this->log;
-
-        if (true === $force || empty($this->config['level'])) {
-            $log[$type][] = $msg;
-        } elseif (in_array($type, $this->config['level'])) {
-            $log[$type][] = $msg;
-        } else {
-            return false;
-        }
-
-        // 监听log_write
-        $this->app['hook']->listen('log_write', $log);
-
-        if (is_null($this->driver)) {
-            $this->init($this->app['config']->pull('log'));
-        }
-
-        // 写入日志
-        $result = $this->driver->save($log);
-
-        if ($result) {
-            $this->log = [];
-        }
-
-        return $result;
-    }
-
-    /**
-     * 记录日志信息
-     * @access public
-     * @param  string $level     日志级别
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function log($level, $message, array $context = [])
-    {
-        $this->record($message, $level, $context);
-    }
-
-    /**
-     * 记录emergency信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function emergency($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录警报信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function alert($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录紧急情况
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function critical($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录错误信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function error($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录warning信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function warning($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录notice信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function notice($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录一般信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function info($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录调试信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function debug($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-
-    /**
-     * 记录sql信息
-     * @access public
-     * @param  mixed  $message   日志信息
-     * @param  array  $context   替换内容
-     * @return void
-     */
-    public function sql($message, array $context = [])
-    {
-        $this->log(__FUNCTION__, $message, $context);
-    }
-}

+ 0 - 132
thinkphp/library/think/Middleware.php

@@ -1,132 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: Slince <taosikai@yeah.net>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use InvalidArgumentException;
-use LogicException;
-use think\exception\HttpResponseException;
-
-class Middleware
-{
-    protected $queue = [];
-
-    public function import(array $middlewares = [])
-    {
-        foreach ($middlewares as $middleware) {
-            $this->add($middleware);
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function add($middleware)
-    {
-        if (is_null($middleware)) {
-            return;
-        }
-
-        $middleware = $this->buildMiddleware($middleware);
-
-        if ($middleware) {
-            $this->queue[] = $middleware;
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function unshift($middleware)
-    {
-        if (is_null($middleware)) {
-            return;
-        }
-
-        $middleware = $this->buildMiddleware($middleware);
-
-        if ($middleware) {
-            array_unshift($this->queue, $middleware);
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function all()
-    {
-        return $this->queue;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    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, isset($param) ? $param : null];
-        }
-
-        if (!is_string($middleware)) {
-            throw new InvalidArgumentException('The middleware is invalid');
-        }
-
-        if (false === strpos($middleware, '\\')) {
-            $value      = Container::get('config')->get('middleware.' . $middleware);
-            $middleware = $value ?: Container::get('app')->getNamespace() . '\\http\\middleware\\' . $middleware;
-        }
-
-        if (is_array($middleware)) {
-            return $this->import($middleware);
-        }
-
-        if (strpos($middleware, ':')) {
-            list($middleware, $param) = explode(':', $middleware, 2);
-        }
-
-        return [[Container::get($middleware), 'handle'], isset($param) ? $param : null];
-    }
-
-    protected function resolve()
-    {
-        return function (Request $request) {
-            $middleware = array_shift($this->queue);
-
-            if (null === $middleware) {
-                throw new InvalidArgumentException('The queue was exhausted, with no response returned');
-            }
-
-            list($call, $param) = $middleware;
-
-            try {
-                $response = call_user_func_array($call, [$request, $this->resolve(), $param]);
-            } catch (HttpResponseException $exception) {
-                $response = $exception->getResponse();
-            }
-
-            if (!$response instanceof Response) {
-                throw new LogicException('The middleware must return Response instance');
-            }
-
-            return $response;
-        };
-    }
-
-}

+ 0 - 1014
thinkphp/library/think/Model.php

@@ -1,1014 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\db\Query;
-
-/**
- * Class Model
- * @package think
- * @mixin Query
- */
-abstract class Model implements \JsonSerializable, \ArrayAccess
-{
-    use model\concern\Attribute;
-    use model\concern\RelationShip;
-    use model\concern\ModelEvent;
-    use model\concern\TimeStamp;
-    use model\concern\Conversion;
-
-    /**
-     * 是否更新数据
-     * @var bool
-     */
-    private $isUpdate = false;
-
-    /**
-     * 是否强制更新所有数据
-     * @var bool
-     */
-    private $force = false;
-
-    /**
-     * 更新条件
-     * @var array
-     */
-    private $updateWhere;
-
-    /**
-     * 数据库配置信息
-     * @var array|string
-     */
-    protected $connection = [];
-
-    /**
-     * 数据库查询对象类名
-     * @var string
-     */
-    protected $query;
-
-    /**
-     * 模型名称
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * 数据表名称
-     * @var string
-     */
-    protected $table;
-
-    /**
-     * 写入自动完成定义
-     * @var array
-     */
-    protected $auto = [];
-
-    /**
-     * 新增自动完成定义
-     * @var array
-     */
-    protected $insert = [];
-
-    /**
-     * 更新自动完成定义
-     * @var array
-     */
-    protected $update = [];
-
-    /**
-     * 初始化过的模型.
-     * @var array
-     */
-    protected static $initialized = [];
-
-    /**
-     * 查询对象实例
-     * @var Query
-     */
-    protected $queryInstance;
-
-    /**
-     * 错误信息
-     * @var mixed
-     */
-    protected $error;
-
-    /**
-     * 软删除字段默认值
-     * @var mixed
-     */
-    protected $defaultSoftDelete;
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array|object $data 数据
-     */
-    public function __construct($data = [])
-    {
-        if (is_object($data)) {
-            $this->data = get_object_vars($data);
-        } else {
-            $this->data = $data;
-        }
-
-        if ($this->disuse) {
-            // 废弃字段
-            foreach ((array) $this->disuse as $key) {
-                if (array_key_exists($key, $this->data)) {
-                    unset($this->data[$key]);
-                }
-            }
-        }
-
-        // 记录原始数据
-        $this->origin = $this->data;
-
-        $config = Container::get('config');
-
-        if (empty($this->name)) {
-            // 当前模型名
-            $name       = str_replace('\\', '/', static::class);
-            $this->name = basename($name);
-            if ($config->get('class_suffix')) {
-                $suffix     = basename(dirname($name));
-                $this->name = substr($this->name, 0, -strlen($suffix));
-            }
-        }
-
-        if (is_null($this->autoWriteTimestamp)) {
-            // 自动写入时间戳
-            $this->autoWriteTimestamp = $config->get('database.auto_timestamp');
-        }
-
-        if (is_null($this->dateFormat)) {
-            // 设置时间戳格式
-            $this->dateFormat = $config->get('database.datetime_format');
-        }
-
-        if (is_null($this->resultSetType)) {
-            $this->resultSetType = $config->get('database.resultset_type');
-        }
-
-        if (is_null($this->query)) {
-            // 设置查询对象
-            $this->query = $config->get('database.query');
-        }
-
-        if (!empty($this->connection) && is_array($this->connection)) {
-            // 设置模型的数据库连接
-            $this->connection = array_merge($config->pull('database'), $this->connection);
-        }
-
-        // 执行初始化操作
-        $this->initialize();
-    }
-
-    /**
-     * 获取当前模型名称
-     * @access public
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * 创建新的模型实例
-     * @access public
-     * @param  array|object $data 数据
-     * @param  bool         $isUpdate 是否为更新
-     * @param  mixed        $where 更新条件
-     * @return Model
-     */
-    public function newInstance($data = [], $isUpdate = false, $where = null)
-    {
-        return (new static($data))->isUpdate($isUpdate, $where);
-    }
-
-    /**
-     * 创建模型的查询对象
-     * @access protected
-     * @return Query
-     */
-    protected function buildQuery()
-    {
-        // 设置当前模型 确保查询返回模型对象
-        $class = $this->query;
-        $query = (new $class())->connect($this->connection)->model($this)->json($this->json);
-
-        // 设置当前数据表和模型名
-        if (!empty($this->table)) {
-            $query->table($this->table);
-        } else {
-            $query->name($this->name);
-        }
-
-        if (!empty($this->pk)) {
-            $query->pk($this->pk);
-        }
-
-        return $query;
-    }
-
-    /**
-     * 获取当前模型的数据库查询对象
-     * @access public
-     * @param  Query $query 查询对象实例
-     * @return $this
-     */
-    public function setQuery($query)
-    {
-        $this->queryInstance = $query;
-        return $this;
-    }
-
-    /**
-     * 获取当前模型的数据库查询对象
-     * @access public
-     * @param  bool $useBaseQuery 是否调用全局查询范围
-     * @return Query
-     */
-    public function db($useBaseQuery = true)
-    {
-        if ($this->queryInstance) {
-            return $this->queryInstance;
-        }
-
-        $query = $this->buildQuery();
-
-        if ($useBaseQuery) {
-            // 软删除
-            if (method_exists($this, 'withNoTrashed')) {
-                $this->withNoTrashed($query);
-            }
-
-            // 全局作用域
-            if (method_exists($this, 'base')) {
-                call_user_func_array([$this, 'base'], [ & $query]);
-            }
-        }
-
-        // 返回当前模型的数据库查询对象
-        return $query;
-    }
-
-    /**
-     *  初始化模型
-     * @access protected
-     * @return void
-     */
-    protected function initialize()
-    {
-        if (!isset(static::$initialized[static::class])) {
-            static::$initialized[static::class] = true;
-            static::init();
-        }
-    }
-
-    /**
-     * 初始化处理
-     * @access protected
-     * @return void
-     */
-    protected static function init()
-    {}
-
-    /**
-     * 数据自动完成
-     * @access protected
-     * @param  array $auto 要自动更新的字段列表
-     * @return void
-     */
-    protected function autoCompleteData($auto = [])
-    {
-        foreach ($auto as $field => $value) {
-            if (is_integer($field)) {
-                $field = $value;
-                $value = null;
-            }
-
-            if (!isset($this->data[$field])) {
-                $default = null;
-            } else {
-                $default = $this->data[$field];
-            }
-
-            $this->setAttr($field, !is_null($value) ? $value : $default);
-        }
-    }
-
-    /**
-     * 更新是否强制写入数据 而不做比较
-     * @access public
-     * @param  bool $force
-     * @return $this
-     */
-    public function force($force = true)
-    {
-        $this->force = $force;
-        return $this;
-    }
-
-    /**
-     * 保存当前数据对象
-     * @access public
-     * @param  array  $data     数据
-     * @param  array  $where    更新条件
-     * @param  string $sequence 自增序列名
-     * @return integer|false
-     */
-    public function save($data = [], $where = [], $sequence = null)
-    {
-        if (is_string($data)) {
-            $sequence = $data;
-            $data     = [];
-        }
-
-        if (!$this->checkBeforeSave($data, $where)) {
-            return false;
-        }
-
-        $result = $this->isUpdate ? $this->updateData($where) : $this->insertData($sequence);
-
-        if (false === $result) {
-            return false;
-        }
-
-        // 写入回调
-        $this->trigger('after_write');
-
-        // 重新记录原始数据
-        $this->origin = $this->data;
-
-        return $result;
-    }
-
-    /**
-     * 写入之前检查数据
-     * @access protected
-     * @param  array   $data  数据
-     * @param  array   $where 保存条件
-     * @return bool
-     */
-    protected function checkBeforeSave($data, $where)
-    {
-        if (!empty($data)) {
-
-            // 数据对象赋值
-            foreach ($data as $key => $value) {
-                $this->setAttr($key, $value, $data);
-            }
-
-            if (!empty($where)) {
-                $this->isUpdate    = true;
-                $this->updateWhere = $where;
-            }
-        }
-
-        // 数据自动完成
-        $this->autoCompleteData($this->auto);
-
-        // 事件回调
-        if (false === $this->trigger('before_write')) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 检查数据是否允许写入
-     * @access protected
-     * @param  array   $append 自动完成的字段列表
-     * @return array
-     */
-    protected function checkAllowFields(array $append = [])
-    {
-        // 检测字段
-        if (empty($this->field) || true === $this->field) {
-            $query = $this->db(false);
-            $table = $this->table ?: $query->getTable();
-
-            $this->field = $query->getConnection()->getTableFields($table);
-
-            $field = $this->field;
-        } else {
-            $field = array_merge($this->field, $append);
-
-            if ($this->autoWriteTimestamp) {
-                array_push($field, $this->createTime, $this->updateTime);
-            }
-        }
-
-        if ($this->disuse) {
-            // 废弃字段
-            $field = array_diff($field, (array) $this->disuse);
-        }
-        return $field;
-    }
-
-    /**
-     * 保存写入数据
-     * @access protected
-     * @param  array   $where 保存条件
-     * @return int|false
-     */
-    protected function updateData($where)
-    {
-        // 自动更新
-        $this->autoCompleteData($this->update);
-
-        // 事件回调
-        if (false === $this->trigger('before_update')) {
-            return false;
-        }
-
-        // 获取有更新的数据
-        $data = $this->getChangedData();
-
-        if (empty($data)) {
-            // 关联更新
-            if (!empty($this->relationWrite)) {
-                $this->autoRelationUpdate();
-            }
-
-            return 0;
-        } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {
-            // 自动写入更新时间
-            $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
-
-            $this->data[$this->updateTime] = $data[$this->updateTime];
-        }
-
-        if (empty($where) && !empty($this->updateWhere)) {
-            $where = $this->updateWhere;
-        }
-
-        // 检查允许字段
-        $allowFields = $this->checkAllowFields(array_merge($this->auto, $this->update));
-
-        // 保留主键数据
-        foreach ($this->data as $key => $val) {
-            if ($this->isPk($key)) {
-                $data[$key] = $val;
-            }
-        }
-
-        $pk    = $this->getPk();
-        $array = [];
-
-        foreach ((array) $pk as $key) {
-            if (isset($data[$key])) {
-                $array[] = [$key, '=', $data[$key]];
-                unset($data[$key]);
-            }
-        }
-
-        if (!empty($array)) {
-            $where = $array;
-        }
-
-        foreach ((array) $this->relationWrite as $name => $val) {
-            if (is_array($val)) {
-                foreach ($val as $key) {
-                    if (isset($data[$key])) {
-                        unset($data[$key]);
-                    }
-                }
-            }
-        }
-
-        // 模型更新
-        $result = $this->db(false)->where($where)->strict(false)->field($allowFields)->update($data);
-
-        // 关联更新
-        if (!empty($this->relationWrite)) {
-            $this->autoRelationUpdate();
-        }
-
-        // 更新回调
-        $this->trigger('after_update');
-
-        return $result;
-    }
-
-    /**
-     * 新增写入数据
-     * @access protected
-     * @param  string   $sequence 自增名
-     * @return int|false
-     */
-    protected function insertData($sequence)
-    {
-        // 自动写入
-        $this->autoCompleteData($this->insert);
-
-        // 时间戳自动写入
-        $this->checkTimeStampWrite();
-
-        if (false === $this->trigger('before_insert')) {
-            return false;
-        }
-
-        // 检查允许字段
-        $allowFields = $this->checkAllowFields(array_merge($this->auto, $this->insert));
-
-        $result = $this->db(false)->strict(false)->field($allowFields)->insert($this->data, false, false, $sequence);
-
-        // 获取自动增长主键
-        if ($result && $insertId = $this->db(false)->getLastInsID($sequence)) {
-            $pk = $this->getPk();
-
-            foreach ((array) $pk as $key) {
-                if (!isset($this->data[$key]) || '' == $this->data[$key]) {
-                    $this->data[$key] = $insertId;
-                }
-            }
-        }
-
-        // 关联写入
-        if (!empty($this->relationWrite)) {
-            $this->autoRelationInsert();
-        }
-
-        // 标记为更新
-        $this->isUpdate = true;
-
-        // 新增回调
-        $this->trigger('after_insert');
-
-        return $result;
-    }
-
-    /**
-     * 字段值(延迟)增长
-     * @access public
-     * @param  string  $field    字段名
-     * @param  integer $step     增长值
-     * @param  integer $lazyTime 延时时间(s)
-     * @return integer|true
-     * @throws Exception
-     */
-    public function setInc($field, $step = 1, $lazyTime = 0)
-    {
-        // 读取更新条件
-        $where = $this->getWhere();
-
-        $result = $this->db(false)->where($where)->setInc($field, $step, $lazyTime);
-
-        if (true !== $result) {
-            $this->data[$field] += $step;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 字段值(延迟)减少
-     * @access public
-     * @param  string  $field    字段名
-     * @param  integer $step     减少值
-     * @param  integer $lazyTime 延时时间(s)
-     * @return integer|true
-     * @throws Exception
-     */
-    public function setDec($field, $step = 1, $lazyTime = 0)
-    {
-        // 读取更新条件
-        $where = $this->getWhere();
-
-        $result = $this->db(false)->where($where)->setDec($field, $step, $lazyTime);
-
-        if (true !== $result) {
-            $this->data[$field] -= $step;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 获取当前的更新条件
-     * @access protected
-     * @return mixed
-     */
-    protected function getWhere()
-    {
-        // 删除条件
-        $pk = $this->getPk();
-
-        if (is_string($pk) && isset($this->data[$pk])) {
-            $where[] = [$pk, '=', $this->data[$pk]];
-        } elseif (!empty($this->updateWhere)) {
-            $where = $this->updateWhere;
-        } else {
-            $where = null;
-        }
-
-        return $where;
-    }
-
-    /**
-     * 保存多个数据到当前数据对象
-     * @access public
-     * @param  array   $dataSet 数据
-     * @param  boolean $replace 是否自动识别更新和写入
-     * @return Collection
-     * @throws \Exception
-     */
-    public function saveAll($dataSet, $replace = true)
-    {
-        $result = [];
-
-        $db = $this->db(false);
-        $db->startTrans();
-
-        try {
-            $pk = $this->getPk();
-
-            if (is_string($pk) && $replace) {
-                $auto = true;
-            }
-
-            foreach ($dataSet as $key => $data) {
-                if ($this->isUpdate || (!empty($auto) && isset($data[$pk]))) {
-                    $result[$key] = self::update($data, [], $this->field);
-                } else {
-                    $result[$key] = self::create($data, $this->field);
-                }
-            }
-
-            $db->commit();
-
-            return $this->toCollection($result);
-        } catch (\Exception $e) {
-            $db->rollback();
-            throw $e;
-        }
-    }
-
-    /**
-     * 是否为更新数据
-     * @access public
-     * @param  mixed  $update
-     * @param  mixed  $where
-     * @return $this
-     */
-    public function isUpdate($update = true, $where = null)
-    {
-        if (is_bool($update)) {
-            $this->isUpdate = $update;
-
-            if (!empty($where)) {
-                $this->updateWhere = $where;
-            }
-        } else {
-            $this->isUpdate    = true;
-            $this->updateWhere = $update;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 删除当前的记录
-     * @access public
-     * @return integer
-     */
-    public function delete()
-    {
-        if (false === $this->trigger('before_delete')) {
-            return false;
-        }
-
-        // 读取更新条件
-        $where = $this->getWhere();
-
-        // 删除当前模型数据
-        $result = $this->db(false)->where($where)->delete();
-
-        // 关联删除
-        if (!empty($this->relationWrite)) {
-            $this->autoRelationDelete();
-        }
-
-        $this->trigger('after_delete');
-
-        // 清空数据
-        $this->data   = [];
-        $this->origin = [];
-
-        return $result;
-    }
-
-    /**
-     * 设置自动完成的字段( 规则通过修改器定义)
-     * @access public
-     * @param  array $fields 需要自动完成的字段
-     * @return $this
-     */
-    public function auto($fields)
-    {
-        $this->auto = $fields;
-
-        return $this;
-    }
-
-    /**
-     * 写入数据
-     * @access public
-     * @param  array      $data  数据数组
-     * @param  array|true $field 允许字段
-     * @return static
-     */
-    public static function create($data = [], $field = null)
-    {
-        $model = new static();
-
-        if (!empty($field)) {
-            $model->allowField($field);
-        }
-
-        $model->isUpdate(false)->save($data, []);
-
-        return $model;
-    }
-
-    /**
-     * 更新数据
-     * @access public
-     * @param  array      $data  数据数组
-     * @param  array      $where 更新条件
-     * @param  array|true $field 允许字段
-     * @return static
-     */
-    public static function update($data = [], $where = [], $field = null)
-    {
-        $model = new static();
-
-        if (!empty($field)) {
-            $model->allowField($field);
-        }
-
-        $model->isUpdate(true)->save($data, $where);
-
-        return $model;
-    }
-
-    /**
-     * 查找单条记录
-     * @access public
-     * @param  mixed     $data  主键值或者查询条件(闭包)
-     * @param  mixed     $with  关联预查询
-     * @param  bool      $cache 是否缓存
-     * @param  bool      $failException 是否抛出异常
-     * @return static|null
-     * @throws exception\DbException
-     */
-    public static function get($data, $with = [], $cache = false, $failException = false)
-    {
-        if (is_null($data)) {
-            return;
-        }
-
-        if (true === $with || is_int($with)) {
-            $cache = $with;
-            $with  = [];
-        }
-
-        $query = static::parseQuery($data, $with, $cache);
-
-        return $query->failException($failException)->find($data);
-    }
-
-    /**
-     * 查找单条记录 如果不存在直接抛出异常
-     * @access public
-     * @param  mixed     $data  主键值或者查询条件(闭包)
-     * @param  mixed     $with  关联预查询
-     * @param  bool      $cache 是否缓存
-     * @return static|null
-     * @throws exception\DbException
-     */
-    public static function getOrFail($data, $with = [], $cache = false)
-    {
-        return self::get($data, $with, $cache, true);
-    }
-
-    /**
-     * 查找所有记录
-     * @access public
-     * @param  mixed        $data  主键列表或者查询条件(闭包)
-     * @param  array|string $with  关联预查询
-     * @param  bool         $cache 是否缓存
-     * @return static[]|false
-     * @throws exception\DbException
-     */
-    public static function all($data = null, $with = [], $cache = false)
-    {
-        if (true === $with || is_int($with)) {
-            $cache = $with;
-            $with  = [];
-        }
-
-        $query = static::parseQuery($data, $with, $cache);
-
-        return $query->select($data);
-    }
-
-    /**
-     * 分析查询表达式
-     * @access public
-     * @param  mixed  $data  主键列表或者查询条件(闭包)
-     * @param  string $with  关联预查询
-     * @param  bool   $cache 是否缓存
-     * @return Query
-     */
-    protected static function parseQuery(&$data, $with, $cache)
-    {
-        $result = self::with($with)->cache($cache);
-
-        if (is_array($data) && key($data) !== 0) {
-            $result = $result->where($data);
-            $data   = null;
-        } elseif ($data instanceof \Closure) {
-            $data($result);
-            $data = null;
-        } elseif ($data instanceof Query) {
-            $result = $data->with($with)->cache($cache);
-            $data   = null;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 删除记录
-     * @access public
-     * @param  mixed $data 主键列表 支持闭包查询条件
-     * @return integer 成功删除的记录数
-     */
-    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) {
-            $query->where($data);
-            $data = null;
-        } elseif ($data instanceof \Closure) {
-            $data($query);
-            $data = null;
-        }
-
-        $resultSet = $query->select($data);
-        $count     = 0;
-
-        if ($resultSet) {
-            foreach ($resultSet as $data) {
-                $result = $data->delete();
-                $count += $result;
-            }
-        }
-
-        return $count;
-    }
-
-    /**
-     * 获取错误信息
-     * @access public
-     * @return mixed
-     */
-    public function getError()
-    {
-        return $this->error;
-    }
-
-    /**
-     * 解序列化后处理
-     */
-    public function __wakeup()
-    {
-        $this->initialize();
-    }
-
-    public function __debugInfo()
-    {
-        return [
-            'data'     => $this->data,
-            'relation' => $this->relation,
-        ];
-    }
-
-    /**
-     * 修改器 设置数据对象的值
-     * @access public
-     * @param  string $name  名称
-     * @param  mixed  $value 值
-     * @return void
-     */
-    public function __set($name, $value)
-    {
-        $this->setAttr($name, $value);
-    }
-
-    /**
-     * 获取器 获取数据对象的值
-     * @access public
-     * @param  string $name 名称
-     * @return mixed
-     */
-    public function __get($name)
-    {
-        return $this->getAttr($name);
-    }
-
-    /**
-     * 检测数据对象的值
-     * @access public
-     * @param  string $name 名称
-     * @return boolean
-     */
-    public function __isset($name)
-    {
-        if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 销毁数据对象的值
-     * @access public
-     * @param  string $name 名称
-     * @return void
-     */
-    public function __unset($name)
-    {
-        unset($this->data[$name], $this->relation[$name]);
-    }
-
-    // ArrayAccess
-    public function offsetSet($name, $value)
-    {
-        $this->setAttr($name, $value);
-    }
-
-    public function offsetExists($name)
-    {
-        return $this->__isset($name);
-    }
-
-    public function offsetUnset($name)
-    {
-        $this->__unset($name);
-    }
-
-    public function offsetGet($name)
-    {
-        return $this->getAttr($name);
-    }
-
-    /**
-     * 设置是否使用全局查询范围
-     * @access public
-     * @param  bool $use 是否启用全局查询范围
-     * @return Query
-     */
-    public static function useGlobalScope($use)
-    {
-        $model = new static();
-
-        return $model->db($use);
-    }
-
-    public function __call($method, $args)
-    {
-        return call_user_func_array([$this->db(), $method], $args);
-    }
-
-    public static function __callStatic($method, $args)
-    {
-        $model = new static();
-
-        return call_user_func_array([$model->db(), $method], $args);
-    }
-}

+ 0 - 437
thinkphp/library/think/Paginator.php

@@ -1,437 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: zhangyajun <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use ArrayAccess;
-use ArrayIterator;
-use Countable;
-use IteratorAggregate;
-use JsonSerializable;
-use Traversable;
-
-abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
-{
-    /**
-     * 是否简洁模式
-     * @var bool
-     */
-    protected $simple = false;
-
-    /**
-     * 数据集
-     * @var Collection
-     */
-    protected $items;
-
-    /**
-     * 当前页
-     * @var integer
-     */
-    protected $currentPage;
-
-    /**
-     * 最后一页
-     * @var integer
-     */
-    protected $lastPage;
-
-    /**
-     * 数据总数
-     * @var integer|null
-     */
-    protected $total;
-
-    /**
-     * 每页数量
-     * @var integer
-     */
-    protected $listRows;
-
-    /**
-     * 是否有下一页
-     * @var bool
-     */
-    protected $hasMore;
-
-    /**
-     * 分页配置
-     * @var array
-     */
-    protected $options = [
-        'var_page' => 'page',
-        'path'     => '/',
-        'query'    => [],
-        'fragment' => '',
-    ];
-
-    public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])
-    {
-        $this->options = array_merge($this->options, $options);
-
-        $this->options['path'] = '/' != $this->options['path'] ? rtrim($this->options['path'], '/') : $this->options['path'];
-
-        $this->simple   = $simple;
-        $this->listRows = $listRows;
-
-        if (!$items instanceof Collection) {
-            $items = Collection::make($items);
-        }
-
-        if ($simple) {
-            $this->currentPage = $this->setCurrentPage($currentPage);
-            $this->hasMore     = count($items) > ($this->listRows);
-            $items             = $items->slice(0, $this->listRows);
-        } else {
-            $this->total       = $total;
-            $this->lastPage    = (int) ceil($total / $listRows);
-            $this->currentPage = $this->setCurrentPage($currentPage);
-            $this->hasMore     = $this->currentPage < $this->lastPage;
-        }
-        $this->items = $items;
-    }
-
-    /**
-     * @access public
-     * @param       $items
-     * @param       $listRows
-     * @param null  $currentPage
-     * @param null  $total
-     * @param bool  $simple
-     * @param array $options
-     * @return Paginator
-     */
-    public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])
-    {
-        return new static($items, $listRows, $currentPage, $total, $simple, $options);
-    }
-
-    protected function setCurrentPage($currentPage)
-    {
-        if (!$this->simple && $currentPage > $this->lastPage) {
-            return $this->lastPage > 0 ? $this->lastPage : 1;
-        }
-
-        return $currentPage;
-    }
-
-    /**
-     * 获取页码对应的链接
-     *
-     * @access protected
-     * @param  $page
-     * @return string
-     */
-    protected function url($page)
-    {
-        if ($page <= 0) {
-            $page = 1;
-        }
-
-        if (strpos($this->options['path'], '[PAGE]') === false) {
-            $parameters = [$this->options['var_page'] => $page];
-            $path       = $this->options['path'];
-        } else {
-            $parameters = [];
-            $path       = str_replace('[PAGE]', $page, $this->options['path']);
-        }
-
-        if (count($this->options['query']) > 0) {
-            $parameters = array_merge($this->options['query'], $parameters);
-        }
-
-        $url = $path;
-        if (!empty($parameters)) {
-            $url .= '?' . http_build_query($parameters, null, '&');
-        }
-
-        return $url . $this->buildFragment();
-    }
-
-    /**
-     * 自动获取当前页码
-     * @access public
-     * @param  string $varPage
-     * @param  int    $default
-     * @return int
-     */
-    public static function getCurrentPage($varPage = 'page', $default = 1)
-    {
-        $page = Container::get('request')->param($varPage);
-
-        if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {
-            return $page;
-        }
-
-        return $default;
-    }
-
-    /**
-     * 自动获取当前的path
-     * @access public
-     * @return string
-     */
-    public static function getCurrentPath()
-    {
-        return Container::get('request')->baseUrl();
-    }
-
-    public function total()
-    {
-        if ($this->simple) {
-            throw new \DomainException('not support total');
-        }
-
-        return $this->total;
-    }
-
-    public function listRows()
-    {
-        return $this->listRows;
-    }
-
-    public function currentPage()
-    {
-        return $this->currentPage;
-    }
-
-    public function lastPage()
-    {
-        if ($this->simple) {
-            throw new \DomainException('not support last');
-        }
-
-        return $this->lastPage;
-    }
-
-    /**
-     * 数据是否足够分页
-     * @access public
-     * @return boolean
-     */
-    public function hasPages()
-    {
-        return !(1 == $this->currentPage && !$this->hasMore);
-    }
-
-    /**
-     * 创建一组分页链接
-     *
-     * @access public
-     * @param  int $start
-     * @param  int $end
-     * @return array
-     */
-    public function getUrlRange($start, $end)
-    {
-        $urls = [];
-
-        for ($page = $start; $page <= $end; $page++) {
-            $urls[$page] = $this->url($page);
-        }
-
-        return $urls;
-    }
-
-    /**
-     * 设置URL锚点
-     *
-     * @access public
-     * @param  string|null $fragment
-     * @return $this
-     */
-    public function fragment($fragment)
-    {
-        $this->options['fragment'] = $fragment;
-
-        return $this;
-    }
-
-    /**
-     * 添加URL参数
-     *
-     * @access public
-     * @param  array|string $key
-     * @param  string|null  $value
-     * @return $this
-     */
-    public function appends($key, $value = null)
-    {
-        if (!is_array($key)) {
-            $queries = [$key => $value];
-        } else {
-            $queries = $key;
-        }
-
-        foreach ($queries as $k => $v) {
-            if ($k !== $this->options['var_page']) {
-                $this->options['query'][$k] = $v;
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 构造锚点字符串
-     *
-     * @access public
-     * @return string
-     */
-    protected function buildFragment()
-    {
-        return $this->options['fragment'] ? '#' . $this->options['fragment'] : '';
-    }
-
-    /**
-     * 渲染分页html
-     * @access public
-     * @return mixed
-     */
-    abstract public function render();
-
-    public function items()
-    {
-        return $this->items->all();
-    }
-
-    public function getCollection()
-    {
-        return $this->items;
-    }
-
-    public function isEmpty()
-    {
-        return $this->items->isEmpty();
-    }
-
-    /**
-     * 给每个元素执行个回调
-     *
-     * @access public
-     * @param  callable $callback
-     * @return $this
-     */
-    public function each(callable $callback)
-    {
-        foreach ($this->items as $key => $item) {
-            $result = $callback($item, $key);
-
-            if (false === $result) {
-                break;
-            } elseif (!is_object($item)) {
-                $this->items[$key] = $result;
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * Retrieve an external iterator
-     * @access public
-     * @return Traversable An instance of an object implementing <b>Iterator</b> or
-     * <b>Traversable</b>
-     */
-    public function getIterator()
-    {
-        return new ArrayIterator($this->items->all());
-    }
-
-    /**
-     * Whether a offset exists
-     * @access public
-     * @param  mixed $offset
-     * @return bool
-     */
-    public function offsetExists($offset)
-    {
-        return $this->items->offsetExists($offset);
-    }
-
-    /**
-     * Offset to retrieve
-     * @access public
-     * @param  mixed $offset
-     * @return mixed
-     */
-    public function offsetGet($offset)
-    {
-        return $this->items->offsetGet($offset);
-    }
-
-    /**
-     * Offset to set
-     * @access public
-     * @param  mixed $offset
-     * @param  mixed $value
-     */
-    public function offsetSet($offset, $value)
-    {
-        $this->items->offsetSet($offset, $value);
-    }
-
-    /**
-     * Offset to unset
-     * @access public
-     * @param  mixed $offset
-     * @return void
-     * @since  5.0.0
-     */
-    public function offsetUnset($offset)
-    {
-        $this->items->offsetUnset($offset);
-    }
-
-    /**
-     * Count elements of an object
-     */
-    public function count()
-    {
-        return $this->items->count();
-    }
-
-    public function __toString()
-    {
-        return (string) $this->render();
-    }
-
-    public function toArray()
-    {
-        try {
-            $total = $this->total();
-        } catch (\DomainException $e) {
-            $total = null;
-        }
-
-        return [
-            'total'        => $total,
-            'per_page'     => $this->listRows(),
-            'current_page' => $this->currentPage(),
-            'last_page'    => $this->lastPage,
-            'data'         => $this->items->toArray(),
-        ];
-    }
-
-    /**
-     * Specify data which should be serialized to JSON
-     */
-    public function jsonSerialize()
-    {
-        return $this->toArray();
-    }
-
-    public function __call($name, $arguments)
-    {
-        return call_user_func_array([$this->getCollection(), $name], $arguments);
-    }
-
-}

+ 0 - 1268
thinkphp/library/think/Process.php

@@ -1,1268 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\process\exception\Failed as ProcessFailedException;
-use think\process\exception\Timeout as ProcessTimeoutException;
-use think\process\pipes\Pipes;
-use think\process\pipes\Unix as UnixPipes;
-use think\process\pipes\Windows as WindowsPipes;
-use think\process\Utils;
-
-class Process
-{
-
-    const ERR = 'err';
-    const OUT = 'out';
-
-    const STATUS_READY      = 'ready';
-    const STATUS_STARTED    = 'started';
-    const STATUS_TERMINATED = 'terminated';
-
-    const STDIN  = 0;
-    const STDOUT = 1;
-    const STDERR = 2;
-
-    const TIMEOUT_PRECISION = 0.2;
-
-    private $callback;
-    private $commandline;
-    private $cwd;
-    private $env;
-    private $input;
-    private $starttime;
-    private $lastOutputTime;
-    private $timeout;
-    private $idleTimeout;
-    private $options;
-    private $exitcode;
-    private $fallbackExitcode;
-    private $processInformation;
-    private $outputDisabled = false;
-    private $stdout;
-    private $stderr;
-    private $enhanceWindowsCompatibility = true;
-    private $enhanceSigchildCompatibility;
-    private $process;
-    private $status                       = self::STATUS_READY;
-    private $incrementalOutputOffset      = 0;
-    private $incrementalErrorOutputOffset = 0;
-    private $tty;
-    private $pty;
-
-    private $useFileHandles = false;
-
-    /** @var Pipes */
-    private $processPipes;
-
-    private $latestSignal;
-
-    private static $sigchild;
-
-    /**
-     * @var array
-     */
-    public static $exitCodes = [
-        0   => 'OK',
-        1   => 'General error',
-        2   => 'Misuse of shell builtins',
-        126 => 'Invoked command cannot execute',
-        127 => 'Command not found',
-        128 => 'Invalid exit argument',
-        // signals
-        129 => 'Hangup',
-        130 => 'Interrupt',
-        131 => 'Quit and dump core',
-        132 => 'Illegal instruction',
-        133 => 'Trace/breakpoint trap',
-        134 => 'Process aborted',
-        135 => 'Bus error: "access to undefined portion of memory object"',
-        136 => 'Floating point exception: "erroneous arithmetic operation"',
-        137 => 'Kill (terminate immediately)',
-        138 => 'User-defined 1',
-        139 => 'Segmentation violation',
-        140 => 'User-defined 2',
-        141 => 'Write to pipe with no one reading',
-        142 => 'Signal raised by alarm',
-        143 => 'Termination (request to terminate)',
-        // 144 - not defined
-        145 => 'Child process terminated, stopped (or continued*)',
-        146 => 'Continue if stopped',
-        147 => 'Stop executing temporarily',
-        148 => 'Terminal stop signal',
-        149 => 'Background process attempting to read from tty ("in")',
-        150 => 'Background process attempting to write to tty ("out")',
-        151 => 'Urgent data available on socket',
-        152 => 'CPU time limit exceeded',
-        153 => 'File size limit exceeded',
-        154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
-        155 => 'Profiling timer expired',
-        // 156 - not defined
-        157 => 'Pollable event',
-        // 158 - not defined
-        159 => 'Bad syscall',
-    ];
-
-    /**
-     * 构造方法
-     * @access public
-     * @param  string         $commandline 指令
-     * @param  string|null    $cwd         工作目录
-     * @param  array|null     $env         环境变量
-     * @param  string|null    $input       输入
-     * @param  int|float|null $timeout     超时时间
-     * @param  array          $options     proc_open的选项
-     * @throws \RuntimeException
-     * @api
-     */
-    public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = [])
-    {
-        if (!function_exists('proc_open')) {
-            throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
-        }
-
-        $this->commandline = $commandline;
-        $this->cwd         = $cwd;
-
-        if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) {
-            $this->cwd = getcwd();
-        }
-        if (null !== $env) {
-            $this->setEnv($env);
-        }
-
-        $this->input = $input;
-        $this->setTimeout($timeout);
-        $this->useFileHandles               = '\\' === DIRECTORY_SEPARATOR;
-        $this->pty                          = false;
-        $this->enhanceWindowsCompatibility  = true;
-        $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
-        $this->options                      = array_replace([
-            'suppress_errors' => true,
-            'binary_pipes'    => true,
-        ], $options);
-    }
-
-    public function __destruct()
-    {
-        $this->stop();
-    }
-
-    public function __clone()
-    {
-        $this->resetProcessData();
-    }
-
-    /**
-     * 运行指令
-     * @access public
-     * @param  callback|null $callback
-     * @return int
-     */
-    public function run($callback = null)
-    {
-        $this->start($callback);
-
-        return $this->wait();
-    }
-
-    /**
-     * 运行指令
-     * @access public
-     * @param  callable|null $callback
-     * @return self
-     * @throws \RuntimeException
-     * @throws ProcessFailedException
-     */
-    public function mustRun($callback = null)
-    {
-        if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {
-            throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
-        }
-
-        if (0 !== $this->run($callback)) {
-            throw new ProcessFailedException($this);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 启动进程并写到 STDIN 输入后返回。
-     * @access public
-     * @param  callable|null $callback
-     * @throws \RuntimeException
-     * @throws \RuntimeException
-     * @throws \LogicException
-     */
-    public function start($callback = null)
-    {
-        if ($this->isRunning()) {
-            throw new \RuntimeException('Process is already running');
-        }
-        if ($this->outputDisabled && null !== $callback) {
-            throw new \LogicException('Output has been disabled, enable it to allow the use of a callback.');
-        }
-
-        $this->resetProcessData();
-        $this->starttime = $this->lastOutputTime = microtime(true);
-        $this->callback  = $this->buildCallback($callback);
-        $descriptors     = $this->getDescriptors();
-
-        $commandline = $this->commandline;
-
-        if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
-            $commandline = 'cmd /V:ON /E:ON /C "(' . $commandline . ')';
-            foreach ($this->processPipes->getFiles() as $offset => $filename) {
-                $commandline .= ' ' . $offset . '>' . Utils::escapeArgument($filename);
-            }
-            $commandline .= '"';
-
-            if (!isset($this->options['bypass_shell'])) {
-                $this->options['bypass_shell'] = true;
-            }
-        }
-
-        $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);
-
-        if (!is_resource($this->process)) {
-            throw new \RuntimeException('Unable to launch a new process.');
-        }
-        $this->status = self::STATUS_STARTED;
-
-        if ($this->tty) {
-            return;
-        }
-
-        $this->updateStatus(false);
-        $this->checkTimeout();
-    }
-
-    /**
-     * 重启进程
-     * @access public
-     * @param  callable|null $callback
-     * @return Process
-     * @throws \RuntimeException
-     * @throws \RuntimeException
-     */
-    public function restart($callback = null)
-    {
-        if ($this->isRunning()) {
-            throw new \RuntimeException('Process is already running');
-        }
-
-        $process = clone $this;
-        $process->start($callback);
-
-        return $process;
-    }
-
-    /**
-     * 等待要终止的进程
-     * @access public
-     * @param  callable|null $callback
-     * @return int
-     */
-    public function wait($callback = null)
-    {
-        $this->requireProcessIsStarted(__FUNCTION__);
-
-        $this->updateStatus(false);
-        if (null !== $callback) {
-            $this->callback = $this->buildCallback($callback);
-        }
-
-        do {
-            $this->checkTimeout();
-            $running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
-            $close   = '\\' !== DIRECTORY_SEPARATOR || !$running;
-            $this->readPipes(true, $close);
-        } while ($running);
-
-        while ($this->isRunning()) {
-            usleep(1000);
-        }
-
-        if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
-            throw new \RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
-        }
-
-        return $this->exitcode;
-    }
-
-    /**
-     * 获取PID
-     * @access public
-     * @return int|null
-     * @throws \RuntimeException
-     */
-    public function getPid()
-    {
-        if ($this->isSigchildEnabled()) {
-            throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.');
-        }
-
-        $this->updateStatus(false);
-
-        return $this->isRunning() ? $this->processInformation['pid'] : null;
-    }
-
-    /**
-     * 将一个 POSIX 信号发送到进程中
-     * @access public
-     * @param  int $signal
-     * @return Process
-     */
-    public function signal($signal)
-    {
-        $this->doSignal($signal, true);
-
-        return $this;
-    }
-
-    /**
-     * 禁用从底层过程获取输出和错误输出。
-     * @access public
-     * @return Process
-     */
-    public function disableOutput()
-    {
-        if ($this->isRunning()) {
-            throw new \RuntimeException('Disabling output while the process is running is not possible.');
-        }
-        if (null !== $this->idleTimeout) {
-            throw new \LogicException('Output can not be disabled while an idle timeout is set.');
-        }
-
-        $this->outputDisabled = true;
-
-        return $this;
-    }
-
-    /**
-     * 开启从底层过程获取输出和错误输出。
-     * @access public
-     * @return Process
-     * @throws \RuntimeException
-     */
-    public function enableOutput()
-    {
-        if ($this->isRunning()) {
-            throw new \RuntimeException('Enabling output while the process is running is not possible.');
-        }
-
-        $this->outputDisabled = false;
-
-        return $this;
-    }
-
-    /**
-     * 输出是否禁用
-     * @access public
-     * @return bool
-     */
-    public function isOutputDisabled()
-    {
-        return $this->outputDisabled;
-    }
-
-    /**
-     * 获取当前的输出管道
-     * @access public
-     * @return string
-     * @throws \LogicException
-     * @api
-     */
-    public function getOutput()
-    {
-        if ($this->outputDisabled) {
-            throw new \LogicException('Output has been disabled.');
-        }
-
-        $this->requireProcessIsStarted(__FUNCTION__);
-
-        $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
-
-        return $this->stdout;
-    }
-
-    /**
-     * 以增量方式返回的输出结果。
-     * @access public
-     * @return string
-     */
-    public function getIncrementalOutput()
-    {
-        $this->requireProcessIsStarted(__FUNCTION__);
-
-        $data = $this->getOutput();
-
-        $latest = substr($data, $this->incrementalOutputOffset);
-
-        if (false === $latest) {
-            return '';
-        }
-
-        $this->incrementalOutputOffset = strlen($data);
-
-        return $latest;
-    }
-
-    /**
-     * 清空输出
-     * @access public
-     * @return Process
-     */
-    public function clearOutput()
-    {
-        $this->stdout                  = '';
-        $this->incrementalOutputOffset = 0;
-
-        return $this;
-    }
-
-    /**
-     * 返回当前的错误输出的过程 (STDERR)。
-     * @access public
-     * @return string
-     */
-    public function getErrorOutput()
-    {
-        if ($this->outputDisabled) {
-            throw new \LogicException('Output has been disabled.');
-        }
-
-        $this->requireProcessIsStarted(__FUNCTION__);
-
-        $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
-
-        return $this->stderr;
-    }
-
-    /**
-     * 以增量方式返回 errorOutput
-     * @access public
-     * @return string
-     */
-    public function getIncrementalErrorOutput()
-    {
-        $this->requireProcessIsStarted(__FUNCTION__);
-
-        $data = $this->getErrorOutput();
-
-        $latest = substr($data, $this->incrementalErrorOutputOffset);
-
-        if (false === $latest) {
-            return '';
-        }
-
-        $this->incrementalErrorOutputOffset = strlen($data);
-
-        return $latest;
-    }
-
-    /**
-     * 清空 errorOutput
-     * @access public
-     * @return Process
-     */
-    public function clearErrorOutput()
-    {
-        $this->stderr                       = '';
-        $this->incrementalErrorOutputOffset = 0;
-
-        return $this;
-    }
-
-    /**
-     * 获取退出码
-     * @access public
-     * @return null|int
-     */
-    public function getExitCode()
-    {
-        if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {
-            throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
-        }
-
-        $this->updateStatus(false);
-
-        return $this->exitcode;
-    }
-
-    /**
-     * 获取退出文本
-     * @access public
-     * @return null|string
-     */
-    public function getExitCodeText()
-    {
-        if (null === $exitcode = $this->getExitCode()) {
-            return;
-        }
-
-        return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
-    }
-
-    /**
-     * 检查是否成功
-     * @access public
-     * @return bool
-     */
-    public function isSuccessful()
-    {
-        return 0 === $this->getExitCode();
-    }
-
-    /**
-     * 是否未捕获的信号已被终止子进程
-     * @access public
-     * @return bool
-     */
-    public function hasBeenSignaled()
-    {
-        $this->requireProcessIsTerminated(__FUNCTION__);
-
-        if ($this->isSigchildEnabled()) {
-            throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
-        }
-
-        $this->updateStatus(false);
-
-        return $this->processInformation['signaled'];
-    }
-
-    /**
-     * 返回导致子进程终止其执行的数。
-     * @access public
-     * @return int
-     */
-    public function getTermSignal()
-    {
-        $this->requireProcessIsTerminated(__FUNCTION__);
-
-        if ($this->isSigchildEnabled()) {
-            throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
-        }
-
-        $this->updateStatus(false);
-
-        return $this->processInformation['termsig'];
-    }
-
-    /**
-     * 检查子进程信号是否已停止
-     * @access public
-     * @return bool
-     */
-    public function hasBeenStopped()
-    {
-        $this->requireProcessIsTerminated(__FUNCTION__);
-
-        $this->updateStatus(false);
-
-        return $this->processInformation['stopped'];
-    }
-
-    /**
-     * 返回导致子进程停止其执行的数。
-     * @access public
-     * @return int
-     */
-    public function getStopSignal()
-    {
-        $this->requireProcessIsTerminated(__FUNCTION__);
-
-        $this->updateStatus(false);
-
-        return $this->processInformation['stopsig'];
-    }
-
-    /**
-     * 检查是否正在运行
-     * @access public
-     * @return bool
-     */
-    public function isRunning()
-    {
-        if (self::STATUS_STARTED !== $this->status) {
-            return false;
-        }
-
-        $this->updateStatus(false);
-
-        return $this->processInformation['running'];
-    }
-
-    /**
-     * 检查是否已开始
-     * @access public
-     * @return bool
-     */
-    public function isStarted()
-    {
-        return self::STATUS_READY != $this->status;
-    }
-
-    /**
-     * 检查是否已终止
-     * @access public
-     * @return bool
-     */
-    public function isTerminated()
-    {
-        $this->updateStatus(false);
-
-        return self::STATUS_TERMINATED == $this->status;
-    }
-
-    /**
-     * 获取当前的状态
-     * @access public
-     * @return string
-     */
-    public function getStatus()
-    {
-        $this->updateStatus(false);
-
-        return $this->status;
-    }
-
-    /**
-     * 终止进程
-     * @access public
-     */
-    public function stop()
-    {
-        if ($this->isRunning()) {
-            if ('\\' === DIRECTORY_SEPARATOR && !$this->isSigchildEnabled()) {
-                exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode);
-                if ($exitCode > 0) {
-                    throw new \RuntimeException('Unable to kill the process');
-                }
-            } else {
-                $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid {$this->getPid()}`);
-                foreach ($pids as $pid) {
-                    if (is_numeric($pid)) {
-                        posix_kill($pid, 9);
-                    }
-                }
-            }
-        }
-
-        $this->updateStatus(false);
-        if ($this->processInformation['running']) {
-            $this->close();
-        }
-
-        return $this->exitcode;
-    }
-
-    /**
-     * 添加一行输出
-     * @access public
-     * @param string $line
-     */
-    public function addOutput($line)
-{
-        $this->lastOutputTime = microtime(true);
-        $this->stdout .= $line;
-    }
-
-    /**
-     * 添加一行错误输出
-     * @access public
-     * @param string $line
-     */
-    public function addErrorOutput($line)
-{
-        $this->lastOutputTime = microtime(true);
-        $this->stderr .= $line;
-    }
-
-    /**
-     * 获取被执行的指令
-     * @access public
-     * @return string
-     */
-    public function getCommandLine()
-{
-        return $this->commandline;
-    }
-
-    /**
-     * 设置指令
-     * @access public
-     * @param string $commandline
-     * @return self
-     */
-    public function setCommandLine($commandline)
-{
-        $this->commandline = $commandline;
-
-        return $this;
-    }
-
-    /**
-     * 获取超时时间
-     * @access public
-     * @return float|null
-     */
-    public function getTimeout()
-{
-        return $this->timeout;
-    }
-
-    /**
-     * 获取idle超时时间
-     * @access public
-     * @return float|null
-     */
-    public function getIdleTimeout()
-{
-        return $this->idleTimeout;
-    }
-
-    /**
-     * 设置超时时间
-     * @access public
-     * @param  int|float|null $timeout
-     * @return self
-     */
-    public function setTimeout($timeout)
-{
-        $this->timeout = $this->validateTimeout($timeout);
-
-        return $this;
-    }
-
-    /**
-     * 设置idle超时时间
-     * @access public
-     * @param  int|float|null $timeout
-     * @return self
-     */
-    public function setIdleTimeout($timeout)
-{
-        if (null !== $timeout && $this->outputDisabled) {
-            throw new \LogicException('Idle timeout can not be set while the output is disabled.');
-        }
-
-        $this->idleTimeout = $this->validateTimeout($timeout);
-
-        return $this;
-    }
-
-    /**
-     * 设置TTY
-     * @access public
-     * @param  bool $tty
-     * @return self
-     */
-    public function setTty($tty)
-{
-        if ('\\' === DIRECTORY_SEPARATOR && $tty) {
-            throw new \RuntimeException('TTY mode is not supported on Windows platform.');
-        }
-        if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) {
-            throw new \RuntimeException('TTY mode requires /dev/tty to be readable.');
-        }
-
-        $this->tty = (bool) $tty;
-
-        return $this;
-    }
-
-    /**
-     * 检查是否是tty模式
-     * @access public
-     * @return bool
-     */
-    public function isTty()
-{
-        return $this->tty;
-    }
-
-    /**
-     * 设置pty模式
-     * @access public
-     * @param  bool $bool
-     * @return self
-     */
-    public function setPty($bool)
-{
-        $this->pty = (bool) $bool;
-
-        return $this;
-    }
-
-    /**
-     * 是否是pty模式
-     * @access public
-     * @return bool
-     */
-    public function isPty()
-{
-        return $this->pty;
-    }
-
-    /**
-     * 获取工作目录
-     * @access public
-     * @return string|null
-     */
-    public function getWorkingDirectory()
-{
-        if (null === $this->cwd) {
-            return getcwd() ?: null;
-        }
-
-        return $this->cwd;
-    }
-
-    /**
-     * 设置工作目录
-     * @access public
-     * @param  string $cwd
-     * @return self
-     */
-    public function setWorkingDirectory($cwd)
-{
-        $this->cwd = $cwd;
-
-        return $this;
-    }
-
-    /**
-     * 获取环境变量
-     * @access public
-     * @return array
-     */
-    public function getEnv()
-{
-        return $this->env;
-    }
-
-    /**
-     * 设置环境变量
-     * @access public
-     * @param  array $env
-     * @return self
-     */
-    public function setEnv(array $env)
-{
-        $env = array_filter($env, function ($value) {
-            return !is_array($value);
-        });
-
-        $this->env = [];
-        foreach ($env as $key => $value) {
-            $this->env[(binary) $key] = (binary) $value;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 获取输入
-     * @access public
-     * @return null|string
-     */
-    public function getInput()
-{
-        return $this->input;
-    }
-
-    /**
-     * 设置输入
-     * @access public
-     * @param  mixed $input
-     * @return self
-     */
-    public function setInput($input)
-{
-        if ($this->isRunning()) {
-            throw new \LogicException('Input can not be set while the process is running.');
-        }
-
-        $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input);
-
-        return $this;
-    }
-
-    /**
-     * 获取proc_open的选项
-     * @access public
-     * @return array
-     */
-    public function getOptions()
-{
-        return $this->options;
-    }
-
-    /**
-     * 设置proc_open的选项
-     * @access public
-     * @param  array $options
-     * @return self
-     */
-    public function setOptions(array $options)
-{
-        $this->options = $options;
-
-        return $this;
-    }
-
-    /**
-     * 是否兼容windows
-     * @access public
-     * @return bool
-     */
-    public function getEnhanceWindowsCompatibility()
-{
-        return $this->enhanceWindowsCompatibility;
-    }
-
-    /**
-     * 设置是否兼容windows
-     * @access public
-     * @param  bool $enhance
-     * @return self
-     */
-    public function setEnhanceWindowsCompatibility($enhance)
-{
-        $this->enhanceWindowsCompatibility = (bool) $enhance;
-
-        return $this;
-    }
-
-    /**
-     * 返回是否 sigchild 兼容模式激活
-     * @access public
-     * @return bool
-     */
-    public function getEnhanceSigchildCompatibility()
-{
-        return $this->enhanceSigchildCompatibility;
-    }
-
-    /**
-     * 激活 sigchild 兼容性模式。
-     * @access public
-     * @param  bool $enhance
-     * @return self
-     */
-    public function setEnhanceSigchildCompatibility($enhance)
-{
-        $this->enhanceSigchildCompatibility = (bool) $enhance;
-
-        return $this;
-    }
-
-    /**
-     * 是否超时
-     */
-    public function checkTimeout()
-{
-        if (self::STATUS_STARTED !== $this->status) {
-            return;
-        }
-
-        if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
-            $this->stop();
-
-            throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_GENERAL);
-        }
-
-        if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
-            $this->stop();
-
-            throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_IDLE);
-        }
-    }
-
-    /**
-     * 是否支持pty
-     * @access public
-     * @return bool
-     */
-    public static function isPtySupported()
-{
-        static $result;
-
-        if (null !== $result) {
-            return $result;
-        }
-
-        if ('\\' === DIRECTORY_SEPARATOR) {
-            return $result = false;
-        }
-
-        $proc = @proc_open('echo 1', [['pty'], ['pty'], ['pty']], $pipes);
-        if (is_resource($proc)) {
-            proc_close($proc);
-
-            return $result = true;
-        }
-
-        return $result = false;
-    }
-
-    /**
-     * 创建所需的 proc_open 的描述符
-     * @access private
-     * @return array
-     */
-    private function getDescriptors()
-{
-        if ('\\' === DIRECTORY_SEPARATOR) {
-            $this->processPipes = WindowsPipes::create($this, $this->input);
-        } else {
-            $this->processPipes = UnixPipes::create($this, $this->input);
-        }
-        $descriptors = $this->processPipes->getDescriptors($this->outputDisabled);
-
-        if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-
-            $descriptors = array_merge($descriptors, [['pipe', 'w']]);
-
-            $this->commandline = '(' . $this->commandline . ') 3>/dev/null; code=$?; echo $code >&3; exit $code';
-        }
-
-        return $descriptors;
-    }
-
-    /**
-     * 建立 wait () 使用的回调。
-     * @access protected
-     * @param  callable|null $callback
-     * @return callable
-     */
-    protected function buildCallback($callback)
-{
-        $out      = self::OUT;
-        $callback = function ($type, $data) use ($callback, $out) {
-            if ($out == $type) {
-                $this->addOutput($data);
-            } else {
-                $this->addErrorOutput($data);
-            }
-
-            if (null !== $callback) {
-                call_user_func($callback, $type, $data);
-            }
-        };
-
-        return $callback;
-    }
-
-    /**
-     * 更新状态
-     * @access protected
-     * @param bool $blocking
-     */
-    protected function updateStatus($blocking)
-{
-        if (self::STATUS_STARTED !== $this->status) {
-            return;
-        }
-
-        $this->processInformation = proc_get_status($this->process);
-        $this->captureExitCode();
-
-        $this->readPipes($blocking, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
-
-        if (!$this->processInformation['running']) {
-            $this->close();
-        }
-    }
-
-    /**
-     * 是否开启 '--enable-sigchild'
-     * @access protected
-     * @return bool
-     */
-    protected function isSigchildEnabled()
-{
-        if (null !== self::$sigchild) {
-            return self::$sigchild;
-        }
-
-        if (!function_exists('phpinfo')) {
-            return self::$sigchild = false;
-        }
-
-        ob_start();
-        phpinfo(INFO_GENERAL);
-
-        return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
-    }
-
-    /**
-     * 验证是否超时
-     * @access private
-     * @param  int|float|null $timeout
-     * @return float|null
-     */
-    private function validateTimeout($timeout)
-{
-        $timeout = (float) $timeout;
-
-        if (0.0 === $timeout) {
-            $timeout = null;
-        } elseif ($timeout < 0) {
-            throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
-        }
-
-        return $timeout;
-    }
-
-    /**
-     * 读取pipes
-     * @access private
-     * @param  bool $blocking
-     * @param  bool $close
-     */
-    private function readPipes($blocking, $close)
-{
-        $result = $this->processPipes->readAndWrite($blocking, $close);
-
-        $callback = $this->callback;
-        foreach ($result as $type => $data) {
-            if (3 == $type) {
-                $this->fallbackExitcode = (int) $data;
-            } else {
-                $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);
-            }
-        }
-    }
-
-    /**
-     * 捕获退出码
-     */
-    private function captureExitCode()
-{
-        if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) {
-            $this->exitcode = $this->processInformation['exitcode'];
-        }
-    }
-
-    /**
-     * 关闭资源
-     * @access private
-     * @return int 退出码
-     */
-    private function close()
-{
-        $this->processPipes->close();
-        if (is_resource($this->process)) {
-            $exitcode = proc_close($this->process);
-        } else {
-            $exitcode = -1;
-        }
-
-        $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1);
-        $this->status   = self::STATUS_TERMINATED;
-
-        if (-1 === $this->exitcode && null !== $this->fallbackExitcode) {
-            $this->exitcode = $this->fallbackExitcode;
-        } elseif (-1 === $this->exitcode && $this->processInformation['signaled']
-            && 0 < $this->processInformation['termsig']
-        ) {
-            $this->exitcode = 128 + $this->processInformation['termsig'];
-        }
-
-        return $this->exitcode;
-    }
-
-    /**
-     * 重置数据
-     */
-    private function resetProcessData()
-{
-        $this->starttime                    = null;
-        $this->callback                     = null;
-        $this->exitcode                     = null;
-        $this->fallbackExitcode             = null;
-        $this->processInformation           = null;
-        $this->stdout                       = null;
-        $this->stderr                       = null;
-        $this->process                      = null;
-        $this->latestSignal                 = null;
-        $this->status                       = self::STATUS_READY;
-        $this->incrementalOutputOffset      = 0;
-        $this->incrementalErrorOutputOffset = 0;
-    }
-
-    /**
-     * 将一个 POSIX 信号发送到进程中。
-     * @access private
-     * @param  int  $signal
-     * @param  bool $throwException
-     * @return bool
-     */
-    private function doSignal($signal, $throwException)
-{
-        if (!$this->isRunning()) {
-            if ($throwException) {
-                throw new \LogicException('Can not send signal on a non running process.');
-            }
-
-            return false;
-        }
-
-        if ($this->isSigchildEnabled()) {
-            if ($throwException) {
-                throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
-            }
-
-            return false;
-        }
-
-        if (true !== @proc_terminate($this->process, $signal)) {
-            if ($throwException) {
-                throw new \RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
-            }
-
-            return false;
-        }
-
-        $this->latestSignal = $signal;
-
-        return true;
-    }
-
-    /**
-     * 确保进程已经开启
-     * @access private
-     * @param  string $functionName
-     */
-    private function requireProcessIsStarted($functionName)
-{
-        if (!$this->isStarted()) {
-            throw new \LogicException(sprintf('Process must be started before calling %s.', $functionName));
-        }
-    }
-
-    /**
-     * 确保进程已经终止
-     * @access private
-     * @param  string $functionName
-     */
-    private function requireProcessIsTerminated($functionName)
-{
-        if (!$this->isTerminated()) {
-            throw new \LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
-        }
-    }
-}

+ 0 - 1966
thinkphp/library/think/Request.php

@@ -1,1966 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\HttpResponseException;
-
-class Request
-{
-    /**
-     * 对象实例
-     * @var object
-     */
-    protected $instance;
-
-    /**
-     * 配置对象
-     * @var Config
-     */
-    protected $config;
-
-    /**
-     * 请求类型
-     * @var string
-     */
-    protected $method;
-
-    /**
-     * 域名(含协议及端口)
-     * @var string
-     */
-    protected $domain;
-
-    /**
-     * 子域名
-     * @var string
-     */
-    protected $subDomain;
-
-    /**
-     * 泛域名
-     * @var string
-     */
-    protected $panDomain;
-
-    /**
-     * 当前URL地址
-     * @var string
-     */
-    protected $url;
-
-    /**
-     * 基础URL
-     * @var string
-     */
-    protected $baseUrl;
-
-    /**
-     * 当前执行的文件
-     * @var string
-     */
-    protected $baseFile;
-
-    /**
-     * 访问的ROOT地址
-     * @var string
-     */
-    protected $root;
-
-    /**
-     * pathinfo
-     * @var string
-     */
-    protected $pathinfo;
-
-    /**
-     * pathinfo(不含后缀)
-     * @var string
-     */
-    protected $path;
-
-    /**
-     * 当前路由信息
-     * @var array
-     */
-    protected $routeInfo = [];
-
-    /**
-     * 当前调度信息
-     * @var array
-     */
-    protected $dispatch = [];
-
-    /**
-     * 当前模块名
-     * @var string
-     */
-    protected $module;
-
-    /**
-     * 当前控制器名
-     * @var string
-     */
-    protected $controller;
-
-    /**
-     * 当前操作名
-     * @var string
-     */
-    protected $action;
-
-    /**
-     * 当前语言集
-     * @var string
-     */
-    protected $langset;
-
-    /**
-     * 当前请求参数
-     * @var array
-     */
-    protected $param = [];
-
-    /**
-     * 当前GET参数
-     * @var array
-     */
-    protected $get = [];
-
-    /**
-     * 当前POST参数
-     * @var array
-     */
-    protected $post = [];
-
-    /**
-     * 当前REQUEST参数
-     * @var array
-     */
-    protected $request = [];
-
-    /**
-     * 当前ROUTE参数
-     * @var array
-     */
-    protected $route = [];
-
-    /**
-     * 当前PUT参数
-     * @var array
-     */
-    protected $put;
-
-    /**
-     * 当前SESSION参数
-     * @var array
-     */
-    protected $session = [];
-
-    /**
-     * 当前FILE参数
-     * @var array
-     */
-    protected $file = [];
-
-    /**
-     * 当前COOKIE参数
-     * @var array
-     */
-    protected $cookie = [];
-
-    /**
-     * 当前SERVER参数
-     * @var array
-     */
-    protected $server = [];
-
-    /**
-     * 当前ENV参数
-     * @var array
-     */
-    protected $env = [];
-
-    /**
-     * 当前HEADER参数
-     * @var array
-     */
-    protected $header = [];
-
-    /**
-     * 资源类型定义
-     * @var array
-     */
-    protected $mimeType = [
-        'xml'   => 'application/xml,text/xml,application/x-xml',
-        'json'  => 'application/json,text/x-json,application/jsonrequest,text/json',
-        'js'    => 'text/javascript,application/javascript,application/x-javascript',
-        'css'   => 'text/css',
-        'rss'   => 'application/rss+xml',
-        'yaml'  => 'application/x-yaml,text/yaml',
-        'atom'  => 'application/atom+xml',
-        'pdf'   => 'application/pdf',
-        'text'  => 'text/plain',
-        'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*',
-        'csv'   => 'text/csv',
-        'html'  => 'text/html,application/xhtml+xml,*/*',
-    ];
-
-    /**
-     * 当前请求内容
-     * @var string
-     */
-    protected $content;
-
-    /**
-     * 全局过滤规则
-     * @var array
-     */
-    protected $filter;
-
-    /**
-     * 扩展方法
-     * @var array
-     */
-    protected $hook = [];
-
-    /**
-     * php://input内容
-     * @var string
-     */
-    // php://input
-    protected $input;
-
-    /**
-     * 请求缓存
-     * @var array
-     */
-    protected $cache;
-
-    /**
-     * 缓存是否检查
-     * @var bool
-     */
-    protected $isCheckCache;
-
-    /**
-     * 请求安全Key
-     * @var string
-     */
-    protected $secureKey;
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array  $options 参数
-     */
-    public function __construct($options = [])
-    {
-        foreach ($options as $name => $item) {
-            if (property_exists($this, $name)) {
-                $this->$name = $item;
-            }
-        }
-
-        $this->config = Container::get('config');
-
-        if (is_null($this->filter)) {
-            $this->filter = $this->config->get('default_filter');
-        }
-
-        // 保存 php://input
-        $this->input = file_get_contents('php://input');
-    }
-
-    public function __call($method, $args)
-    {
-        if (array_key_exists($method, $this->hook)) {
-            array_unshift($args, $this);
-            return call_user_func_array($this->hook[$method], $args);
-        }
-
-        throw new Exception('method not exists:' . static::class . '->' . $method);
-    }
-
-    /**
-     * Hook 方法注入
-     * @access public
-     * @param  string|array  $method 方法名
-     * @param  mixed         $callback callable
-     * @return void
-     */
-    public function hook($method, $callback = null)
-    {
-        if (is_array($method)) {
-            $this->hook = array_merge($this->hook, $method);
-        } else {
-            $this->hook[$method] = $callback;
-        }
-    }
-
-    /**
-     * 创建一个URL请求
-     * @access public
-     * @param  string    $uri URL地址
-     * @param  string    $method 请求类型
-     * @param  array     $params 请求参数
-     * @param  array     $cookie
-     * @param  array     $files
-     * @param  array     $server
-     * @param  string    $content
-     * @return \think\Request
-     */
-    public function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null)
-    {
-        $server['PATH_INFO']      = '';
-        $server['REQUEST_METHOD'] = strtoupper($method);
-        $info                     = parse_url($uri);
-
-        if (isset($info['host'])) {
-            $server['SERVER_NAME'] = $info['host'];
-            $server['HTTP_HOST']   = $info['host'];
-        }
-
-        if (isset($info['scheme'])) {
-            if ('https' === $info['scheme']) {
-                $server['HTTPS']       = 'on';
-                $server['SERVER_PORT'] = 443;
-            } else {
-                unset($server['HTTPS']);
-                $server['SERVER_PORT'] = 80;
-            }
-        }
-
-        if (isset($info['port'])) {
-            $server['SERVER_PORT'] = $info['port'];
-            $server['HTTP_HOST']   = $server['HTTP_HOST'] . ':' . $info['port'];
-        }
-
-        if (isset($info['user'])) {
-            $server['PHP_AUTH_USER'] = $info['user'];
-        }
-
-        if (isset($info['pass'])) {
-            $server['PHP_AUTH_PW'] = $info['pass'];
-        }
-
-        if (!isset($info['path'])) {
-            $info['path'] = '/';
-        }
-
-        $options     = [];
-        $queryString = '';
-
-        $options[strtolower($method)] = $params;
-
-        if (isset($info['query'])) {
-            parse_str(html_entity_decode($info['query']), $query);
-            if (!empty($params)) {
-                $params      = array_replace($query, $params);
-                $queryString = http_build_query($params, '', '&');
-            } else {
-                $params      = $query;
-                $queryString = $info['query'];
-            }
-        } elseif (!empty($params)) {
-            $queryString = http_build_query($params, '', '&');
-        }
-
-        if ($queryString) {
-            parse_str($queryString, $get);
-            $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;
-        }
-
-        $server['REQUEST_URI']  = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
-        $server['QUERY_STRING'] = $queryString;
-        $options['cookie']      = $cookie;
-        $options['param']       = $params;
-        $options['file']        = $files;
-        $options['server']      = $server;
-        $options['url']         = $server['REQUEST_URI'];
-        $options['baseUrl']     = $info['path'];
-        $options['pathinfo']    = '/' == $info['path'] ? '/' : ltrim($info['path'], '/');
-        $options['method']      = $server['REQUEST_METHOD'];
-        $options['domain']      = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : '';
-        $options['content']     = $content;
-
-        foreach ($options as $name => $item) {
-            if (property_exists($this, $name)) {
-                $this->$name = $item;
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置或获取当前包含协议的域名
-     * @access public
-     * @param  string $domain 域名
-     * @return string|$this
-     */
-    public function domain($domain = null)
-    {
-        if (!is_null($domain)) {
-            $this->domain = $domain;
-            return $this;
-        } elseif (!$this->domain) {
-            $this->domain = $this->scheme() . '://' . $this->host();
-        }
-
-        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
-     */
-    public function subDomain()
-    {
-        if (is_null($this->subDomain)) {
-            // 获取当前主域名
-            $rootDomain = $this->config->get('app.url_domain_root');
-
-            if ($rootDomain) {
-                // 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置
-                $domain = explode('.', rtrim(stristr($this->host(), $rootDomain, true), '.'));
-            } else {
-                $domain = explode('.', $this->host(), -2);
-            }
-
-            $this->subDomain = implode('.', $domain);
-        }
-
-        return $this->subDomain;
-    }
-
-    /**
-     * 设置或获取当前泛域名的值
-     * @access public
-     * @param  string $domain 域名
-     * @return string|$this
-     */
-    public function panDomain($domain = null)
-    {
-        if (is_null($domain)) {
-            return $this->panDomain;
-        }
-
-        $this->panDomain = $domain;
-        return $this;
-    }
-
-    /**
-     * 设置或获取当前完整URL 包括QUERY_STRING
-     * @access public
-     * @param  string|true $url URL地址 true 带域名获取
-     * @return string|$this
-     */
-    public function url($url = null)
-    {
-        if (!is_null($url) && true !== $url) {
-            $this->url = $url;
-            return $this;
-        } elseif (!$this->url) {
-            if ($this->isCli()) {
-                $this->url = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
-            } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
-                $this->url = $_SERVER['HTTP_X_REWRITE_URL'];
-            } elseif (isset($_SERVER['REQUEST_URI'])) {
-                $this->url = $_SERVER['REQUEST_URI'];
-            } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
-                $this->url = $_SERVER['ORIG_PATH_INFO'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '');
-            } else {
-                $this->url = '';
-            }
-        }
-
-        return true === $url ? $this->domain() . $this->url : $this->url;
-    }
-
-    /**
-     * 设置或获取当前URL 不含QUERY_STRING
-     * @access public
-     * @param  string $url URL地址
-     * @return string|$this
-     */
-    public function baseUrl($url = null)
-    {
-        if (!is_null($url) && true !== $url) {
-            $this->baseUrl = $url;
-            return $this;
-        } elseif (!$this->baseUrl) {
-            $str           = $this->url();
-            $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str;
-        }
-
-        return true === $url ? $this->domain() . $this->baseUrl : $this->baseUrl;
-    }
-
-    /**
-     * 设置或获取当前执行的文件 SCRIPT_NAME
-     * @access public
-     * @param  string $file 当前执行的文件
-     * @return string|$this
-     */
-    public function baseFile($file = null)
-    {
-        if (!is_null($file) && true !== $file) {
-            $this->baseFile = $file;
-            return $this;
-        } elseif (!$this->baseFile) {
-            $url = '';
-            if (!$this->isCli()) {
-                $script_name = basename($_SERVER['SCRIPT_FILENAME']);
-                if (basename($_SERVER['SCRIPT_NAME']) === $script_name) {
-                    $url = $_SERVER['SCRIPT_NAME'];
-                } elseif (basename($_SERVER['PHP_SELF']) === $script_name) {
-                    $url = $_SERVER['PHP_SELF'];
-                } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) {
-                    $url = $_SERVER['ORIG_SCRIPT_NAME'];
-                } elseif (($pos = strpos($_SERVER['PHP_SELF'], '/' . $script_name)) !== false) {
-                    $url = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name;
-                } elseif (isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) {
-                    $url = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME']));
-                }
-            }
-            $this->baseFile = $url;
-        }
-
-        return true === $file ? $this->domain() . $this->baseFile : $this->baseFile;
-    }
-
-    /**
-     * 设置或获取URL访问根地址
-     * @access public
-     * @param  string $url URL地址
-     * @return string|$this
-     */
-    public function root($url = null)
-    {
-        if (!is_null($url) && true !== $url) {
-            $this->root = $url;
-            return $this;
-        } elseif (!$this->root) {
-            $file = $this->baseFile();
-            if ($file && 0 !== strpos($this->url(), $file)) {
-                $file = str_replace('\\', '/', dirname($file));
-            }
-            $this->root = rtrim($file, '/');
-        }
-
-        return true === $url ? $this->domain() . $this->root : $this->root;
-    }
-
-    /**
-     * 获取URL访问根目录
-     * @access public
-     * @return string
-     */
-    public function rootUrl()
-    {
-        $base = $this->root();
-        $root = strpos($base, '.') ? ltrim(dirname($base), DIRECTORY_SEPARATOR) : $base;
-
-        if ('' != $root) {
-            $root = '/' . ltrim($root, '/');
-        }
-
-        return $root;
-    }
-
-    /**
-     * 获取当前请求URL的pathinfo信息(含URL后缀)
-     * @access public
-     * @return string
-     */
-    public function pathinfo()
-    {
-        if (is_null($this->pathinfo)) {
-            if (isset($_GET[$this->config->get('var_pathinfo')])) {
-                // 判断URL里面是否有兼容模式参数
-                $_SERVER['PATH_INFO'] = $_GET[$this->config->get('var_pathinfo')];
-                unset($_GET[$this->config->get('var_pathinfo')]);
-            } elseif ($this->isCli()) {
-                // CLI模式下 index.php module/controller/action/params/...
-                $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
-            } elseif ('cli-server' == PHP_SAPI) {
-                $_SERVER['PATH_INFO'] = strpos($_SERVER['REQUEST_URI'], '?') ? strstr($_SERVER['REQUEST_URI'], '?', true) : $_SERVER['REQUEST_URI'];
-            }
-
-            // 分析PATHINFO信息
-            if (!isset($_SERVER['PATH_INFO'])) {
-                foreach ($this->config->get('pathinfo_fetch') as $type) {
-                    if (!empty($_SERVER[$type])) {
-                        $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
-                        substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
-                        break;
-                    }
-                }
-            }
-
-            $this->pathinfo = empty($_SERVER['PATH_INFO']) || '/' == $_SERVER['PATH_INFO'] ? '' : ltrim($_SERVER['PATH_INFO'], '/');
-        }
-
-        return $this->pathinfo;
-    }
-
-    /**
-     * 获取当前请求URL的pathinfo信息(不含URL后缀)
-     * @access public
-     * @return string
-     */
-    public function path()
-    {
-        if (is_null($this->path)) {
-            $suffix   = $this->config->get('url_html_suffix');
-            $pathinfo = $this->pathinfo();
-            if (false === $suffix) {
-                // 禁止伪静态访问
-                $this->path = $pathinfo;
-            } elseif ($suffix) {
-                // 去除正常的URL后缀
-                $this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
-            } else {
-                // 允许任何后缀访问
-                $this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo);
-            }
-        }
-
-        return $this->path;
-    }
-
-    /**
-     * 当前URL的访问后缀
-     * @access public
-     * @return string
-     */
-    public function ext()
-    {
-        return pathinfo($this->pathinfo(), PATHINFO_EXTENSION);
-    }
-
-    /**
-     * 获取当前请求的时间
-     * @access public
-     * @param  bool $float 是否使用浮点类型
-     * @return integer|float
-     */
-    public function time($float = false)
-    {
-        return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME'];
-    }
-
-    /**
-     * 当前请求的资源类型
-     * @access public
-     * @return false|string
-     */
-    public function type()
-    {
-        $accept = $this->server('HTTP_ACCEPT');
-
-        if (empty($accept)) {
-            return false;
-        }
-
-        foreach ($this->mimeType as $key => $val) {
-            $array = explode(',', $val);
-            foreach ($array as $k => $v) {
-                if (stristr($accept, $v)) {
-                    return $key;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * 设置资源类型
-     * @access public
-     * @param  string|array  $type 资源类型名
-     * @param  string        $val 资源类型
-     * @return void
-     */
-    public function mimeType($type, $val = '')
-    {
-        if (is_array($type)) {
-            $this->mimeType = array_merge($this->mimeType, $type);
-        } else {
-            $this->mimeType[$type] = $val;
-        }
-    }
-
-    /**
-     * 当前的请求类型
-     * @access public
-     * @param  bool $method  true 获取原始请求类型
-     * @return string
-     */
-    public function method($method = false)
-    {
-        if (true === $method) {
-            // 获取原始请求类型
-            return $this->isCli() ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
-        } elseif (!$this->method) {
-            if (isset($_POST[$this->config->get('var_method')])) {
-                $this->method = strtoupper($_POST[$this->config->get('var_method')]);
-                $this->{$this->method}($_POST);
-            } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
-                $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
-            } else {
-                $this->method = $this->isCli() ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
-            }
-        }
-
-        return $this->method;
-    }
-
-    /**
-     * 是否为GET请求
-     * @access public
-     * @return bool
-     */
-    public function isGet()
-    {
-        return $this->method() == 'GET';
-    }
-
-    /**
-     * 是否为POST请求
-     * @access public
-     * @return bool
-     */
-    public function isPost()
-    {
-        return $this->method() == 'POST';
-    }
-
-    /**
-     * 是否为PUT请求
-     * @access public
-     * @return bool
-     */
-    public function isPut()
-    {
-        return $this->method() == 'PUT';
-    }
-
-    /**
-     * 是否为DELTE请求
-     * @access public
-     * @return bool
-     */
-    public function isDelete()
-    {
-        return $this->method() == 'DELETE';
-    }
-
-    /**
-     * 是否为HEAD请求
-     * @access public
-     * @return bool
-     */
-    public function isHead()
-    {
-        return $this->method() == 'HEAD';
-    }
-
-    /**
-     * 是否为PATCH请求
-     * @access public
-     * @return bool
-     */
-    public function isPatch()
-    {
-        return $this->method() == 'PATCH';
-    }
-
-    /**
-     * 是否为OPTIONS请求
-     * @access public
-     * @return bool
-     */
-    public function isOptions()
-    {
-        return $this->method() == 'OPTIONS';
-    }
-
-    /**
-     * 是否为cli
-     * @access public
-     * @return bool
-     */
-    public function isCli()
-    {
-        return PHP_SAPI == 'cli';
-    }
-
-    /**
-     * 是否为cgi
-     * @access public
-     * @return bool
-     */
-    public function isCgi()
-    {
-        return strpos(PHP_SAPI, 'cgi') === 0;
-    }
-
-    /**
-     * 获取当前请求的参数
-     * @access public
-     * @param  mixed         $name 变量名
-     * @param  mixed         $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function param($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->param)) {
-            $method = $this->method(true);
-
-            // 自动获取请求变量
-            switch ($method) {
-                case 'POST':
-                    $vars = $this->post(false);
-                    break;
-                case 'PUT':
-                case 'DELETE':
-                case 'PATCH':
-                    $vars = $this->put(false);
-                    break;
-                default:
-                    $vars = [];
-            }
-
-            // 当前请求参数和URL地址中的参数合并
-            $this->param = array_merge($this->get(false), $vars, $this->route(false));
-        }
-
-        if (true === $name) {
-            // 获取包含文件上传信息的数组
-            $file = $this->file();
-            $data = is_array($file) ? array_merge($this->param, $file) : $this->param;
-            return $this->input($data, '', $default, $filter);
-        }
-
-        return $this->input($this->param, $name, $default, $filter);
-    }
-
-    /**
-     * 设置获取路由参数
-     * @access public
-     * @param  mixed         $name 变量名
-     * @param  mixed         $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function route($name = '', $default = null, $filter = '')
-    {
-        if (is_array($name)) {
-            $this->param        = [];
-            return $this->route = array_merge($this->route, $name);
-        }
-
-        return $this->input($this->route, $name, $default, $filter);
-    }
-
-    /**
-     * 设置获取GET参数
-     * @access public
-     * @param  mixed         $name 变量名
-     * @param  mixed         $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function get($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->get)) {
-            $this->get = $_GET;
-        }
-
-        if (is_array($name)) {
-            $this->param      = [];
-            return $this->get = array_merge($this->get, $name);
-        }
-
-        return $this->input($this->get, $name, $default, $filter);
-    }
-
-    /**
-     * 设置获取POST参数
-     * @access public
-     * @param  mixed         $name 变量名
-     * @param  mixed         $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function post($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->post)) {
-            $content = $this->input;
-            if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) {
-                $this->post = (array) json_decode($content, true);
-            } else {
-                $this->post = $_POST;
-            }
-        }
-
-        if (is_array($name)) {
-            $this->param       = [];
-            return $this->post = array_merge($this->post, $name);
-        }
-
-        return $this->input($this->post, $name, $default, $filter);
-    }
-
-    /**
-     * 设置获取PUT参数
-     * @access public
-     * @param  mixed             $name 变量名
-     * @param  mixed             $default 默认值
-     * @param  string|array      $filter 过滤方法
-     * @return mixed
-     */
-    public function put($name = '', $default = null, $filter = '')
-    {
-        if (is_null($this->put)) {
-            $content = $this->input;
-            if (false !== strpos($this->contentType(), 'application/json')) {
-                $this->put = (array) json_decode($content, true);
-            } else {
-                parse_str($content, $this->put);
-            }
-        }
-
-        if (is_array($name)) {
-            $this->param      = [];
-            return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name);
-        }
-
-        return $this->input($this->put, $name, $default, $filter);
-    }
-
-    /**
-     * 设置获取DELETE参数
-     * @access public
-     * @param  mixed             $name 变量名
-     * @param  mixed             $default 默认值
-     * @param  string|array      $filter 过滤方法
-     * @return mixed
-     */
-    public function delete($name = '', $default = null, $filter = '')
-    {
-        return $this->put($name, $default, $filter);
-    }
-
-    /**
-     * 设置获取PATCH参数
-     * @access public
-     * @param  mixed             $name 变量名
-     * @param  mixed             $default 默认值
-     * @param  string|array      $filter 过滤方法
-     * @return mixed
-     */
-    public function patch($name = '', $default = null, $filter = '')
-    {
-        return $this->put($name, $default, $filter);
-    }
-
-    /**
-     * 获取request变量
-     * @access public
-     * @param  mixed         $name 数据名称
-     * @param  string        $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function request($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->request)) {
-            $this->request = $_REQUEST;
-        }
-
-        if (is_array($name)) {
-            $this->param          = [];
-            return $this->request = array_merge($this->request, $name);
-        }
-
-        return $this->input($this->request, $name, $default, $filter);
-    }
-
-    /**
-     * 获取session数据
-     * @access public
-     * @param  mixed         $name 数据名称
-     * @param  string        $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function session($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->session)) {
-            $this->session = Container::get('session')->get();
-        }
-
-        if (is_array($name)) {
-            return $this->session = array_merge($this->session, $name);
-        }
-
-        return $this->input($this->session, $name, $default, $filter);
-    }
-
-    /**
-     * 获取cookie参数
-     * @access public
-     * @param  mixed         $name 数据名称
-     * @param  string        $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function cookie($name = '', $default = null, $filter = '')
-    {
-        $cookie = Container::get('cookie');
-
-        if (empty($this->cookie)) {
-            $this->cookie = $cookie->get();
-        }
-
-        if (is_array($name)) {
-            return $this->cookie = array_merge($this->cookie, $name);
-        } elseif (!empty($name)) {
-            $data = $cookie->has($name) ? $cookie->get($name) : $default;
-        } else {
-            $data = $this->cookie;
-        }
-
-        // 解析过滤器
-        $filter = $this->getFilter($filter, $default);
-
-        if (is_array($data)) {
-            array_walk_recursive($data, [$this, 'filterValue'], $filter);
-            reset($data);
-        } else {
-            $this->filterValue($data, $name, $filter);
-        }
-
-        return $data;
-    }
-
-    /**
-     * 获取server参数
-     * @access public
-     * @param  mixed         $name 数据名称
-     * @param  string        $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function server($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->server)) {
-            $this->server = $_SERVER;
-        }
-
-        if (is_array($name)) {
-            return $this->server = array_merge($this->server, $name);
-        }
-
-        return $this->input($this->server, false === $name ? false : strtoupper($name), $default, $filter);
-    }
-
-    /**
-     * 获取上传的文件信息
-     * @access public
-     * @param  string|array $name 名称
-     * @return null|array|\think\File
-     */
-    public function file($name = '')
-    {
-        if (empty($this->file)) {
-            $this->file = isset($_FILES) ? $_FILES : [];
-        }
-
-        if (is_array($name)) {
-            return $this->file = array_merge($this->file, $name);
-        }
-
-        $files = $this->file;
-        if (!empty($files)) {
-            // 处理上传文件
-            $array = $this->dealUploadFile($files);
-
-            if (strpos($name, '.')) {
-                list($name, $sub) = explode('.', $name);
-            }
-
-            if ('' === $name) {
-                // 获取全部文件
-                return $array;
-            } elseif (isset($sub) && isset($array[$name][$sub])) {
-                return $array[$name][$sub];
-            } elseif (isset($array[$name])) {
-                return $array[$name];
-            }
-        }
-
-        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
-     * @param  mixed         $name 数据名称
-     * @param  string        $default 默认值
-     * @param  string|array  $filter 过滤方法
-     * @return mixed
-     */
-    public function env($name = '', $default = null, $filter = '')
-    {
-        if (empty($this->env)) {
-            $this->env = Container::get('env')->get();
-        }
-
-        if (is_array($name)) {
-            return $this->env = array_merge($this->env, $name);
-        }
-
-        return $this->input($this->env, false === $name ? false : strtoupper($name), $default, $filter);
-    }
-
-    /**
-     * 设置或者获取当前的Header
-     * @access public
-     * @param  string|array  $name header名称
-     * @param  string        $default 默认值
-     * @return string
-     */
-    public function header($name = '', $default = null)
-    {
-        if (empty($this->header)) {
-            $header = [];
-            if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
-                $header = $result;
-            } else {
-                $server = $this->server ?: $_SERVER;
-                foreach ($server as $key => $val) {
-                    if (0 === strpos($key, 'HTTP_')) {
-                        $key          = str_replace('_', '-', strtolower(substr($key, 5)));
-                        $header[$key] = $val;
-                    }
-                }
-                if (isset($server['CONTENT_TYPE'])) {
-                    $header['content-type'] = $server['CONTENT_TYPE'];
-                }
-                if (isset($server['CONTENT_LENGTH'])) {
-                    $header['content-length'] = $server['CONTENT_LENGTH'];
-                }
-            }
-            $this->header = array_change_key_case($header);
-        }
-
-        if (is_array($name)) {
-            return $this->header = array_merge($this->header, $name);
-        }
-
-        if ('' === $name) {
-            return $this->header;
-        }
-
-        $name = str_replace('_', '-', strtolower($name));
-
-        return isset($this->header[$name]) ? $this->header[$name] : $default;
-    }
-
-    /**
-     * 获取变量 支持过滤和默认值
-     * @access public
-     * @param  array         $data 数据源
-     * @param  string|false  $name 字段名
-     * @param  mixed         $default 默认值
-     * @param  string|array  $filter 过滤函数
-     * @return mixed
-     */
-    public function input($data = [], $name = '', $default = null, $filter = '')
-    {
-        if (false === $name) {
-            // 获取原始数据
-            return $data;
-        }
-
-        $name = (string) $name;
-        if ('' != $name) {
-            // 解析name
-            if (strpos($name, '/')) {
-                list($name, $type) = explode('/', $name);
-            } else {
-                $type = 's';
-            }
-
-            // 按.拆分成多维数组进行判断
-            foreach (explode('.', $name) as $val) {
-                if (isset($data[$val])) {
-                    $data = $data[$val];
-                } else {
-                    // 无输入数据,返回默认值
-                    return $default;
-                }
-            }
-
-            if (is_object($data)) {
-                return $data;
-            }
-        }
-
-        // 解析过滤器
-        $filter = $this->getFilter($filter, $default);
-
-        if (is_array($data)) {
-            array_walk_recursive($data, [$this, 'filterValue'], $filter);
-            reset($data);
-        } else {
-            $this->filterValue($data, $name, $filter);
-        }
-
-        if (isset($type) && $data !== $default) {
-            // 强制类型转换
-            $this->typeCast($data, $type);
-        }
-
-        return $data;
-    }
-
-    /**
-     * 设置或获取当前的过滤规则
-     * @access public
-     * @param  mixed $filter 过滤规则
-     * @return mixed
-     */
-    public function filter($filter = null)
-    {
-        if (is_null($filter)) {
-            return $this->filter;
-        }
-
-        $this->filter = $filter;
-    }
-
-    protected function getFilter($filter, $default)
-    {
-        if (is_null($filter)) {
-            $filter = [];
-        } else {
-            $filter = $filter ?: $this->filter;
-            if (is_string($filter) && false === strpos($filter, '/')) {
-                $filter = explode(',', $filter);
-            } else {
-                $filter = (array) $filter;
-            }
-        }
-
-        $filter[] = $default;
-
-        return $filter;
-    }
-
-    /**
-     * 递归过滤给定的值
-     * @access public
-     * @param  mixed     $value 键值
-     * @param  mixed     $key 键名
-     * @param  array     $filters 过滤方法+默认值
-     * @return mixed
-     */
-    private function filterValue(&$value, $key, $filters)
-    {
-        $default = array_pop($filters);
-
-        foreach ($filters as $filter) {
-            if (is_callable($filter)) {
-                // 调用函数或者方法过滤
-                $value = call_user_func($filter, $value);
-            } elseif (is_scalar($value)) {
-                if (false !== strpos($filter, '/')) {
-                    // 正则过滤
-                    if (!preg_match($filter, $value)) {
-                        // 匹配不成功返回默认值
-                        $value = $default;
-                        break;
-                    }
-                } elseif (!empty($filter)) {
-                    // filter函数不存在时, 则使用filter_var进行过滤
-                    // filter为非整形值时, 调用filter_id取得过滤id
-                    $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));
-                    if (false === $value) {
-                        $value = $default;
-                        break;
-                    }
-                }
-            }
-        }
-
-        return $value;
-    }
-
-    /**
-     * 强制类型转换
-     * @access public
-     * @param  string $data
-     * @param  string $type
-     * @return mixed
-     */
-    private function typeCast(&$data, $type)
-    {
-        switch (strtolower($type)) {
-            // 数组
-            case 'a':
-                $data = (array) $data;
-                break;
-            // 数字
-            case 'd':
-                $data = (int) $data;
-                break;
-            // 浮点
-            case 'f':
-                $data = (float) $data;
-                break;
-            // 布尔
-            case 'b':
-                $data = (boolean) $data;
-                break;
-            // 字符串
-            case 's':
-            default:
-                if (is_scalar($data)) {
-                    $data = (string) $data;
-                } else {
-                    throw new \InvalidArgumentException('variable type error:' . gettype($data));
-                }
-        }
-    }
-
-    /**
-     * 是否存在某个请求参数
-     * @access public
-     * @param  string    $name 变量名
-     * @param  string    $type 变量类型
-     * @param  bool      $checkEmpty 是否检测空值
-     * @return mixed
-     */
-    public function has($name, $type = 'param', $checkEmpty = false)
-    {
-        if (empty($this->$type)) {
-            $param = $this->$type();
-        } else {
-            $param = $this->$type;
-        }
-
-        // 按.拆分成多维数组进行判断
-        foreach (explode('.', $name) as $val) {
-            if (isset($param[$val])) {
-                $param = $param[$val];
-            } else {
-                return false;
-            }
-        }
-
-        return ($checkEmpty && '' === $param) ? false : true;
-    }
-
-    /**
-     * 获取指定的参数
-     * @access public
-     * @param  string|array  $name 变量名
-     * @param  string        $type 变量类型
-     * @return mixed
-     */
-    public function only($name, $type = 'param')
-    {
-        $param = $this->$type();
-
-        if (is_string($name)) {
-            $name = explode(',', $name);
-        }
-
-        $item = [];
-        foreach ($name as $key => $val) {
-
-            if (is_int($key)) {
-                $default = null;
-                $key     = $val;
-            } else {
-                $default = $val;
-            }
-
-            if (isset($param[$key])) {
-                $item[$key] = $param[$key];
-            } elseif (isset($default)) {
-                $item[$key] = $default;
-            }
-        }
-
-        return $item;
-    }
-
-    /**
-     * 排除指定参数获取
-     * @access public
-     * @param  string|array  $name 变量名
-     * @param  string        $type 变量类型
-     * @return mixed
-     */
-    public function except($name, $type = 'param')
-    {
-        $param = $this->$type();
-        if (is_string($name)) {
-            $name = explode(',', $name);
-        }
-
-        foreach ($name as $key) {
-            if (isset($param[$key])) {
-                unset($param[$key]);
-            }
-        }
-
-        return $param;
-    }
-
-    /**
-     * 当前是否ssl
-     * @access public
-     * @return bool
-     */
-    public function isSsl()
-    {
-        $server = array_merge($_SERVER, $this->server);
-
-        if (isset($server['HTTPS']) && ('1' == $server['HTTPS'] || 'on' == strtolower($server['HTTPS']))) {
-            return true;
-        } elseif (isset($server['REQUEST_SCHEME']) && 'https' == $server['REQUEST_SCHEME']) {
-            return true;
-        } elseif (isset($server['SERVER_PORT']) && ('443' == $server['SERVER_PORT'])) {
-            return true;
-        } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) {
-            return true;
-        } elseif ($this->config->get('https_agent_name') && isset($server[$this->config->get('https_agent_name')])) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 当前是否Ajax请求
-     * @access public
-     * @param  bool $ajax  true 获取原始ajax请求
-     * @return bool
-     */
-    public function isAjax($ajax = false)
-    {
-        $value  = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower');
-        $result = ('xmlhttprequest' == $value) ? true : false;
-
-        if (true === $ajax) {
-            return $result;
-        }
-
-        return $this->param($this->config->get('var_ajax')) ? true : $result;
-    }
-
-    /**
-     * 当前是否Pjax请求
-     * @access public
-     * @param  bool $pjax  true 获取原始pjax请求
-     * @return bool
-     */
-    public function isPjax($pjax = false)
-    {
-        $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false;
-
-        if (true === $pjax) {
-            return $result;
-        }
-
-        return $this->param($this->config->get('var_pjax')) ? true : $result;
-    }
-
-    /**
-     * 获取客户端IP地址
-     * @access public
-     * @param  integer   $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
-     * @param  boolean   $adv 是否进行高级模式获取(有可能被伪装)
-     * @return mixed
-     */
-    public function ip($type = 0, $adv = true)
-    {
-        $type      = $type ? 1 : 0;
-        static $ip = null;
-
-        if (null !== $ip) {
-            return $ip[$type];
-        }
-
-        $httpAgentIp = $this->config->get('http_agent_ip');
-
-        if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) {
-            $ip = $_SERVER[$httpAgentIp];
-        } elseif ($adv) {
-            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
-                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
-                $pos = array_search('unknown', $arr);
-                if (false !== $pos) {
-                    unset($arr[$pos]);
-                }
-                $ip = trim(current($arr));
-            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
-                $ip = $_SERVER['HTTP_CLIENT_IP'];
-            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
-                $ip = $_SERVER['REMOTE_ADDR'];
-            }
-        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
-            $ip = $_SERVER['REMOTE_ADDR'];
-        }
-
-        // IP地址类型
-        $ip_mode = (strpos($ip, ':') === false) ? 'ipv4' : 'ipv6';
-
-        // IP地址合法验证
-        if (filter_var($ip, FILTER_VALIDATE_IP) !== $ip) {
-            $ip = ($ip_mode === 'ipv4') ? '0.0.0.0' : '::';
-        }
-
-        // 如果是ipv4地址,则直接使用ip2long返回int类型ip;如果是ipv6地址,暂时不支持,直接返回0
-        $long_ip = ($ip_mode === 'ipv4') ? sprintf("%u", ip2long($ip)) : 0;
-
-        $ip = [$ip, $long_ip];
-
-        return $ip[$type];
-    }
-
-    /**
-     * 检测是否使用手机访问
-     * @access public
-     * @return bool
-     */
-    public function isMobile()
-    {
-        if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
-            return true;
-        } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) {
-            return true;
-        } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
-            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;
-        }
-
-        return false;
-    }
-
-    /**
-     * 当前URL地址中的scheme参数
-     * @access public
-     * @return string
-     */
-    public function scheme()
-    {
-        return $this->isSsl() ? 'https' : 'http';
-    }
-
-    /**
-     * 当前请求URL地址中的query参数
-     * @access public
-     * @return string
-     */
-    public function query()
-    {
-        return $this->server('QUERY_STRING');
-    }
-
-    /**
-     * 当前请求的host
-     * @access public
-     * @return string
-     */
-    public function host()
-    {
-        if (isset($_SERVER['HTTP_X_REAL_HOST'])) {
-            return $_SERVER['HTTP_X_REAL_HOST'];
-        }
-
-        return $this->server('HTTP_HOST');
-    }
-
-    /**
-     * 当前请求URL地址中的port参数
-     * @access public
-     * @return integer
-     */
-    public function port()
-    {
-        return $this->server('SERVER_PORT');
-    }
-
-    /**
-     * 当前请求 SERVER_PROTOCOL
-     * @access public
-     * @return integer
-     */
-    public function protocol()
-    {
-        return $this->server('SERVER_PROTOCOL');
-    }
-
-    /**
-     * 当前请求 REMOTE_PORT
-     * @access public
-     * @return integer
-     */
-    public function remotePort()
-    {
-        return $this->server('REMOTE_PORT');
-    }
-
-    /**
-     * 当前请求 HTTP_CONTENT_TYPE
-     * @access public
-     * @return string
-     */
-    public function contentType()
-    {
-        $contentType = $this->server('CONTENT_TYPE');
-
-        if ($contentType) {
-            if (strpos($contentType, ';')) {
-                list($type) = explode(';', $contentType);
-            } else {
-                $type = $contentType;
-            }
-            return trim($type);
-        }
-
-        return '';
-    }
-
-    /**
-     * 获取当前请求的路由信息
-     * @access public
-     * @param  array $route 路由名称
-     * @return array
-     */
-    public function routeInfo($route = [])
-    {
-        if (!empty($route)) {
-            $this->routeInfo = $route;
-        }
-
-        return $this->routeInfo;
-    }
-
-    /**
-     * 设置或者获取当前请求的调度信息
-     * @access public
-     * @param  array  $dispatch 调度信息
-     * @return array
-     */
-    public function dispatch($dispatch = null)
-    {
-        if (!is_null($dispatch)) {
-            $this->dispatch = $dispatch;
-        }
-
-        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
-     * @param  string $module 模块名
-     * @return string|Request
-     */
-    public function module($module = null)
-    {
-        if (!is_null($module)) {
-            $this->module = $module;
-            return $this;
-        }
-
-        return $this->module ?: '';
-    }
-
-    /**
-     * 设置或者获取当前的控制器名
-     * @access public
-     * @param  string $controller 控制器名
-     * @return string|Request
-     */
-    public function controller($controller = null)
-    {
-        if (!is_null($controller)) {
-            $this->controller = $controller;
-            return $this;
-        }
-
-        return $this->controller ?: '';
-    }
-
-    /**
-     * 设置或者获取当前的操作名
-     * @access public
-     * @param  string $action 操作名
-     * @return string|Request
-     */
-    public function action($action = null)
-    {
-        if (!is_null($action) && !is_bool($action)) {
-            $this->action = $action;
-            return $this;
-        }
-
-        $name = $this->action ?: '';
-        return true === $action ? $name : strtolower($name);
-    }
-
-    /**
-     * 设置或者获取当前的语言
-     * @access public
-     * @param  string $lang 语言名
-     * @return string|Request
-     */
-    public function langset($lang = null)
-    {
-        if (!is_null($lang)) {
-            $this->langset = $lang;
-            return $this;
-        }
-
-        return $this->langset ?: '';
-    }
-
-    /**
-     * 设置或者获取当前请求的content
-     * @access public
-     * @return string
-     */
-    public function getContent()
-    {
-        if (is_null($this->content)) {
-            $this->content = $this->input;
-        }
-
-        return $this->content;
-    }
-
-    /**
-     * 获取当前请求的php://input
-     * @access public
-     * @return string
-     */
-    public function getInput()
-    {
-        return $this->input;
-    }
-
-    /**
-     * 生成请求令牌
-     * @access public
-     * @param  string $name 令牌名称
-     * @param  mixed  $type 令牌生成方法
-     * @return string
-     */
-    public function token($name = '__token__', $type = 'md5')
-    {
-        $type  = is_callable($type) ? $type : 'md5';
-        $token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']);
-
-        if ($this->isAjax()) {
-            header($name . ': ' . $token);
-        }
-
-        Container::get('session')->set($name, $token);
-
-        return $token;
-    }
-
-    /**
-     * 设置当前地址的请求缓存
-     * @access public
-     * @param  string $key 缓存标识,支持变量规则 ,例如 item/:name/:id
-     * @param  mixed  $expire 缓存有效期
-     * @param  array  $except 缓存排除
-     * @param  string $tag    缓存标签
-     * @return void
-     */
-    public function cache($key, $expire = null, $except = [], $tag = null)
-    {
-        if (!is_array($except)) {
-            $tag    = $except;
-            $except = [];
-        }
-
-        if (false === $key || !$this->isGet() || $this->isCheckCache || false === $expire) {
-            // 关闭当前缓存
-            return;
-        }
-
-        // 标记请求缓存检查
-        $this->isCheckCache = true;
-
-        foreach ($except as $rule) {
-            if (0 === stripos($this->url(), $rule)) {
-                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);
-                }
-            }
-        } 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);
-        }
-
-        $this->cache = [$key, $expire, $tag];
-    }
-
-    /**
-     * 读取请求缓存设置
-     * @access public
-     * @return array
-     */
-    public function getCache()
-    {
-        return $this->cache;
-    }
-
-    /**
-     * 获取请求数据的值
-     * @access public
-     * @param  string $name 名称
-     * @return mixed
-     */
-    public function __get($name)
-    {
-        return $this->param($name);
-    }
-
-}

+ 0 - 401
thinkphp/library/think/Response.php

@@ -1,401 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\response\Redirect as RedirectResponse;
-
-class Response
-{
-    /**
-     * 原始数据
-     * @var mixed
-     */
-    protected $data;
-
-    /**
-     * 当前contentType
-     * @var string
-     */
-    protected $contentType = 'text/html';
-
-    /**
-     * 字符集
-     * @var string
-     */
-    protected $charset = 'utf-8';
-
-    /**
-     * 状态码
-     * @var integer
-     */
-    protected $code = 200;
-
-    /**
-     * 是否允许请求缓存
-     * @var bool
-     */
-    protected $allowCache = true;
-
-    /**
-     * 输出参数
-     * @var array
-     */
-    protected $options = [];
-
-    /**
-     * header参数
-     * @var array
-     */
-    protected $header = [];
-
-    /**
-     * 输出内容
-     * @var string
-     */
-    protected $content = null;
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  mixed $data    输出数据
-     * @param  int   $code
-     * @param  array $header
-     * @param  array $options 输出参数
-     */
-    public function __construct($data = '', $code = 200, array $header = [], $options = [])
-    {
-        $this->data($data);
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        $this->contentType($this->contentType, $this->charset);
-
-        $this->code   = $code;
-        $this->header = array_merge($this->header, $header);
-    }
-
-    /**
-     * 创建Response对象
-     * @access public
-     * @param  mixed  $data    输出数据
-     * @param  string $type    输出类型
-     * @param  int    $code
-     * @param  array  $header
-     * @param  array  $options 输出参数
-     * @return Response
-     */
-    public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
-    {
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));
-
-        if (class_exists($class)) {
-            return new $class($data, $code, $header, $options);
-        }
-
-        return new static($data, $code, $header, $options);
-    }
-
-    /**
-     * 发送数据到客户端
-     * @access public
-     * @return void
-     * @throws \InvalidArgumentException
-     */
-    public function send()
-    {
-        // 监听response_send
-        Container::get('hook')->listen('response_send', $this);
-
-        // 处理输出数据
-        $data = $this->getContent();
-
-        // Trace调试注入
-        if ('cli' != PHP_SAPI && Container::get('env')->get('app_trace', Container::get('app')->config('app.app_trace'))) {
-            Container::get('debug')->inject($this, $data);
-        }
-
-        if (200 == $this->code && $this->allowCache) {
-            $cache = Container::get('request')->getCache();
-            if ($cache) {
-                $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';
-                $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
-                $this->header['Expires']       = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';
-
-                Container::get('cache')->tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);
-            }
-        }
-
-        if (!headers_sent() && !empty($this->header)) {
-            // 发送状态码
-            http_response_code($this->code);
-            // 发送头部信息
-            foreach ($this->header as $name => $val) {
-                header($name . (!is_null($val) ? ':' . $val : ''));
-            }
-        }
-
-        $this->sendData($data);
-
-        if (function_exists('fastcgi_finish_request')) {
-            // 提高页面响应
-            fastcgi_finish_request();
-        }
-
-        // 监听response_end
-        Container::get('hook')->listen('response_end', $this);
-
-        // 清空当次请求有效的数据
-        if (!($this instanceof RedirectResponse)) {
-            Container::get('session')->flush();
-        }
-    }
-
-    /**
-     * 处理数据
-     * @access protected
-     * @param  mixed $data 要处理的数据
-     * @return mixed
-     */
-    protected function output($data)
-    {
-        return $data;
-    }
-
-    /**
-     * 输出数据
-     * @access protected
-     * @param string $data 要处理的数据
-     * @return void
-     */
-    protected function sendData($data)
-    {
-        echo $data;
-    }
-
-    /**
-     * 输出的参数
-     * @access public
-     * @param  mixed $options 输出参数
-     * @return $this
-     */
-    public function options($options = [])
-    {
-        $this->options = array_merge($this->options, $options);
-
-        return $this;
-    }
-
-    /**
-     * 输出数据设置
-     * @access public
-     * @param  mixed $data 输出数据
-     * @return $this
-     */
-    public function data($data)
-    {
-        $this->data = $data;
-
-        return $this;
-    }
-
-    /**
-     * 是否允许请求缓存
-     * @access public
-     * @param  bool $cache 允许请求缓存
-     * @return $this
-     */
-    public function allowCache($cache)
-    {
-        $this->allowCache = $cache;
-
-        return $this;
-    }
-
-    /**
-     * 设置响应头
-     * @access public
-     * @param  string|array $name  参数名
-     * @param  string       $value 参数值
-     * @return $this
-     */
-    public function header($name, $value = null)
-    {
-        if (is_array($name)) {
-            $this->header = array_merge($this->header, $name);
-        } else {
-            $this->header[$name] = $value;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置页面输出内容
-     * @access public
-     * @param  mixed $content
-     * @return $this
-     */
-    public function content($content)
-    {
-        if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
-            $content,
-            '__toString',
-        ])
-        ) {
-            throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
-        }
-
-        $this->content = (string) $content;
-
-        return $this;
-    }
-
-    /**
-     * 发送HTTP状态
-     * @access public
-     * @param  integer $code 状态码
-     * @return $this
-     */
-    public function code($code)
-    {
-        $this->code = $code;
-
-        return $this;
-    }
-
-    /**
-     * LastModified
-     * @access public
-     * @param  string $time
-     * @return $this
-     */
-    public function lastModified($time)
-    {
-        $this->header['Last-Modified'] = $time;
-
-        return $this;
-    }
-
-    /**
-     * Expires
-     * @access public
-     * @param  string $time
-     * @return $this
-     */
-    public function expires($time)
-    {
-        $this->header['Expires'] = $time;
-
-        return $this;
-    }
-
-    /**
-     * ETag
-     * @access public
-     * @param  string $eTag
-     * @return $this
-     */
-    public function eTag($eTag)
-    {
-        $this->header['ETag'] = $eTag;
-
-        return $this;
-    }
-
-    /**
-     * 页面缓存控制
-     * @access public
-     * @param  string $cache 状态码
-     * @return $this
-     */
-    public function cacheControl($cache)
-    {
-        $this->header['Cache-control'] = $cache;
-
-        return $this;
-    }
-
-    /**
-     * 页面输出类型
-     * @access public
-     * @param  string $contentType 输出类型
-     * @param  string $charset     输出编码
-     * @return $this
-     */
-    public function contentType($contentType, $charset = 'utf-8')
-    {
-        $this->header['Content-Type'] = $contentType . '; charset=' . $charset;
-
-        return $this;
-    }
-
-    /**
-     * 获取头部信息
-     * @access public
-     * @param  string $name 头部名称
-     * @return mixed
-     */
-    public function getHeader($name = '')
-    {
-        if (!empty($name)) {
-            return isset($this->header[$name]) ? $this->header[$name] : null;
-        }
-
-        return $this->header;
-    }
-
-    /**
-     * 获取原始数据
-     * @access public
-     * @return mixed
-     */
-    public function getData()
-    {
-        return $this->data;
-    }
-
-    /**
-     * 获取输出数据
-     * @access public
-     * @return mixed
-     */
-    public function getContent()
-    {
-        if (null == $this->content) {
-            $content = $this->output($this->data);
-
-            if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
-                $content,
-                '__toString',
-            ])
-            ) {
-                throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
-            }
-
-            $this->content = (string) $content;
-        }
-
-        return $this->content;
-    }
-
-    /**
-     * 获取状态码
-     * @access public
-     * @return integer
-     */
-    public function getCode()
-    {
-        return $this->code;
-    }
-}

+ 0 - 858
thinkphp/library/think/Route.php

@@ -1,858 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-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;
-use think\route\RuleGroup;
-use think\route\RuleItem;
-
-class Route
-{
-    /**
-     * REST定义
-     * @var array
-     */
-    protected $rest = [
-        'index'  => ['get', '', 'index'],
-        'create' => ['get', '/create', 'create'],
-        'edit'   => ['get', '/:id/edit', 'edit'],
-        'read'   => ['get', '/:id', 'read'],
-        'save'   => ['post', '', 'save'],
-        'update' => ['put', '/:id', 'update'],
-        'delete' => ['delete', '/:id', 'delete'],
-    ];
-
-    /**
-     * 请求方法前缀定义
-     * @var array
-     */
-    protected $methodPrefix = [
-        'get'    => 'get',
-        'post'   => 'post',
-        'put'    => 'put',
-        'delete' => 'delete',
-        'patch'  => 'patch',
-    ];
-
-    /**
-     * 配置对象
-     * @var Config
-     */
-    protected $config;
-
-    /**
-     * 请求对象
-     * @var Request
-     */
-    protected $request;
-
-    /**
-     * 当前HOST
-     * @var string
-     */
-    protected $host;
-
-    /**
-     * 当前域名
-     * @var string
-     */
-    protected $domain;
-
-    /**
-     * 当前分组对象
-     * @var RuleGroup
-     */
-    protected $group;
-
-    /**
-     * 路由绑定
-     * @var array
-     */
-    protected $bind = [];
-
-    /**
-     * 域名对象
-     * @var array
-     */
-    protected $domains = [];
-
-    /**
-     * 跨域路由规则
-     * @var RuleGroup
-     */
-    protected $cross;
-
-    /**
-     * 路由别名
-     * @var array
-     */
-    protected $alias = [];
-
-    /**
-     * 路由是否延迟解析
-     * @var bool
-     */
-    protected $lazy = true;
-
-    /**
-     * (分组)路由规则是否合并解析
-     * @var bool
-     */
-    protected $mergeRuleRegex = true;
-
-    /**
-     * 路由解析自动搜索多级控制器
-     * @var bool
-     */
-    protected $autoSearchController = true;
-
-    public function __construct(Request $request)
-    {
-        $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
-     * @return void
-     */
-    protected function setDefaultDomain()
-    {
-        // 默认域名
-        $this->domain = $this->host;
-
-        // 注册默认域名
-        $domain = new Domain($this, $this->host);
-
-        $this->domains[$this->host] = $domain;
-
-        // 默认分组
-        $this->group = $domain;
-    }
-
-    /**
-     * 设置当前域名
-     * @access public
-     * @param  RuleGroup    $group 域名
-     * @return void
-     */
-    public function setGroup(RuleGroup $group)
-    {
-        $this->group = $group;
-    }
-
-    /**
-     * 获取当前分组
-     * @access public
-     * @return RuleGroup
-     */
-    public function getGroup()
-    {
-        return $this->group;
-    }
-
-    /**
-     * 注册变量规则
-     * @access public
-     * @param  string|array  $name 变量名
-     * @param  string        $rule 变量规则
-     * @return $this
-     */
-    public function pattern($name, $rule = '')
-    {
-        $this->group->pattern($name, $rule);
-
-        return $this;
-    }
-
-    /**
-     * 注册路由参数
-     * @access public
-     * @param  string|array  $name  参数名
-     * @param  mixed         $value 值
-     * @return $this
-     */
-    public function option($name, $value = '')
-    {
-        $this->group->option($name, $value);
-
-        return $this;
-    }
-
-    /**
-     * 注册域名路由
-     * @access public
-     * @param  string|array  $name 子域名
-     * @param  mixed         $rule 路由规则
-     * @param  array         $option 路由参数
-     * @param  array         $pattern 变量规则
-     * @return Domain
-     */
-    public function domain($name, $rule = '', $option = [], $pattern = [])
-    {
-        // 支持多个域名使用相同路由规则
-        $domainName = is_array($name) ? array_shift($name) : $name;
-
-        if ('*' != $domainName && !strpos($domainName, '.')) {
-            $domainName .= '.' . $this->request->rootDomain();
-        }
-
-        if (!isset($this->domains[$domainName])) {
-            $domain = (new Domain($this, $domainName, $rule, $option, $pattern))
-                ->lazy($this->lazy)
-                ->mergeRuleRegex($this->mergeRuleRegex);
-
-            $this->domains[$domainName] = $domain;
-        } else {
-            $domain = $this->domains[$domainName];
-            $domain->parseGroupRule($rule);
-        }
-
-        if (is_array($name) && !empty($name)) {
-            $root = $this->request->rootDomain();
-            foreach ($name as $item) {
-                if (!strpos($item, '.')) {
-                    $item .= '.' . $root;
-                }
-
-                $this->domains[$item] = $domainName;
-            }
-        }
-
-        // 返回域名对象
-        return $domain;
-    }
-
-    /**
-     * 获取域名
-     * @access public
-     * @return array
-     */
-    public function getDomains()
-    {
-        return $this->domains;
-    }
-
-    /**
-     * 设置路由绑定
-     * @access public
-     * @param  string     $bind 绑定信息
-     * @param  string     $domain 域名
-     * @return $this
-     */
-    public function bind($bind, $domain = null)
-    {
-        $domain = is_null($domain) ? $this->domain : $domain;
-
-        $this->bind[$domain] = $bind;
-
-        return $this;
-    }
-
-    /**
-     * 读取路由绑定
-     * @access public
-     * @param  string    $domain 域名
-     * @return string|null
-     */
-    public function getBind($domain = null)
-    {
-        if (is_null($domain)) {
-            $domain = $this->domain;
-        } elseif (!strpos($domain, '.')) {
-            $domain .= '.' . $this->request->rootDomain();
-        }
-
-        $subDomain = $this->request->subDomain();
-
-        if (strpos($subDomain, '.')) {
-            $name = '*' . strstr($subDomain, '.');
-        }
-
-        if (isset($this->bind[$domain])) {
-            $result = $this->bind[$domain];
-        } elseif (isset($name) && isset($this->bind[$name])) {
-            $result = $this->bind[$name];
-        } elseif (isset($this->bind['*'])) {
-            $result = $this->bind['*'];
-        } else {
-            $result = null;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 读取路由标识
-     * @access public
-     * @param  string    $name 路由标识
-     * @return mixed
-     */
-    public function getName($name = null)
-    {
-        return Container::get('rule_name')->get($name);
-    }
-
-    /**
-     * 批量导入路由标识
-     * @access public
-     * @param  array    $name 路由标识
-     * @return $this
-     */
-    public function setName($name)
-    {
-        Container::get('rule_name')->import($name);
-        return $this;
-    }
-
-    /**
-     * 导入配置文件的路由规则
-     * @access public
-     * @param  array     $rules 路由规则
-     * @param  string    $type  请求类型
-     * @return void
-     */
-    public function import(array $rules, $type = '*')
-    {
-        // 检查域名部署
-        if (isset($rules['__domain__'])) {
-            foreach ($rules['__domain__'] as $key => $rule) {
-                $this->domain($key, $rule);
-            }
-            unset($rules['__domain__']);
-        }
-
-        // 检查变量规则
-        if (isset($rules['__pattern__'])) {
-            $this->pattern($rules['__pattern__']);
-            unset($rules['__pattern__']);
-        }
-
-        // 检查路由别名
-        if (isset($rules['__alias__'])) {
-            $this->alias($rules['__alias__']);
-            unset($rules['__alias__']);
-        }
-
-        // 检查资源路由
-        if (isset($rules['__rest__'])) {
-            foreach ($rules['__rest__'] as $key => $rule) {
-                $this->resource($key, $rule);
-            }
-            unset($rules['__rest__']);
-        }
-
-        // 检查路由规则(包含分组)
-        foreach ($rules as $key => $val) {
-            if (is_numeric($key)) {
-                $key = array_shift($val);
-            }
-
-            if (empty($val)) {
-                continue;
-            }
-
-            if (is_string($key) && 0 === strpos($key, '[')) {
-                $key = substr($key, 1, -1);
-                $this->group($key, $val);
-            } elseif (is_array($val)) {
-                $this->rule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []);
-            } else {
-                $this->rule($key, $val, $type);
-            }
-        }
-    }
-
-    /**
-     * 注册路由规则
-     * @access public
-     * @param  string    $rule       路由规则
-     * @param  mixed     $route      路由地址
-     * @param  string    $method     请求类型
-     * @param  array     $option     路由参数
-     * @param  array     $pattern    变量规则
-     * @return RuleItem
-     */
-    public function rule($rule, $route, $method = '*', array $option = [], array $pattern = [])
-    {
-        return $this->group->addRule($rule, $route, $method, $option, $pattern);
-    }
-
-    /**
-     * 设置跨域有效路由规则
-     * @access public
-     * @param  Rule      $rule      路由规则
-     * @param  string    $method    请求类型
-     * @return $this
-     */
-    public function setCrossDomainRule($rule, $method = '*')
-    {
-        if (!isset($this->cross)) {
-            $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
-        }
-
-        $this->cross->addRuleItem($rule, $method);
-
-        return $this;
-    }
-
-    /**
-     * 批量注册路由规则
-     * @access public
-     * @param  array     $rules      路由规则
-     * @param  string    $method     请求类型
-     * @param  array     $option     路由参数
-     * @param  array     $pattern    变量规则
-     * @return void
-     */
-    public function rules($rules, $method = '*', array $option = [], array $pattern = [])
-    {
-        $this->group->addRules($rules, $method, $option, $pattern);
-    }
-
-    /**
-     * 注册路由分组
-     * @access public
-     * @param  string|array      $name       分组名称或者参数
-     * @param  array|\Closure    $route      分组路由
-     * @param  array             $option     路由参数
-     * @param  array             $pattern    变量规则
-     * @return RuleGroup
-     */
-    public function group($name, $route, array $option = [], array $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);
-    }
-
-    /**
-     * 注册路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function any($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, '*', $option, $pattern);
-    }
-
-    /**
-     * 注册GET路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function get($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, 'GET', $option, $pattern);
-    }
-
-    /**
-     * 注册POST路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function post($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, 'POST', $option, $pattern);
-    }
-
-    /**
-     * 注册PUT路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function put($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, 'PUT', $option, $pattern);
-    }
-
-    /**
-     * 注册DELETE路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function delete($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, 'DELETE', $option, $pattern);
-    }
-
-    /**
-     * 注册PATCH路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  mixed     $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleItem
-     */
-    public function patch($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, 'PATCH', $option, $pattern);
-    }
-
-    /**
-     * 注册资源路由
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  string    $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return Resource
-     */
-    public function resource($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        return (new Resource($this, $this->group, $rule, $route, $option, $pattern, $this->rest))
-            ->lazy($this->lazy);
-    }
-
-    /**
-     * 注册控制器路由 操作方法对应不同的请求前缀
-     * @access public
-     * @param  string    $rule 路由规则
-     * @param  string    $route 路由地址
-     * @param  array     $option 路由参数
-     * @param  array     $pattern 变量规则
-     * @return RuleGroup
-     */
-    public function controller($rule, $route = '', array $option = [], array $pattern = [])
-    {
-        $group = new RuleGroup($this, $this->group, $rule, null, $option, $pattern);
-
-        foreach ($this->methodPrefix as $type => $val) {
-            $group->addRule('<action>', $val . '<action>', $type);
-        }
-
-        return $group->prefix($route . '/');
-    }
-
-    /**
-     * 注册视图路由
-     * @access public
-     * @param  string|array $rule 路由规则
-     * @param  string       $template 路由模板地址
-     * @param  array        $vars 模板变量
-     * @param  array        $option 路由参数
-     * @param  array        $pattern 变量规则
-     * @return RuleItem
-     */
-    public function view($rule, $template = '', array $vars = [], array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $template, 'GET', $option, $pattern)->view($vars);
-    }
-
-    /**
-     * 注册重定向路由
-     * @access public
-     * @param  string|array $rule 路由规则
-     * @param  string       $route 路由地址
-     * @param  array        $status 状态码
-     * @param  array        $option 路由参数
-     * @param  array        $pattern 变量规则
-     * @return RuleItem
-     */
-    public function redirect($rule, $route = '', $status = 301, array $option = [], array $pattern = [])
-    {
-        return $this->rule($rule, $route, '*', $option, $pattern)->redirect()->status($status);
-    }
-
-    /**
-     * 注册别名路由
-     * @access public
-     * @param  string  $rule 路由别名
-     * @param  string  $route 路由地址
-     * @param  array   $option 路由参数
-     * @return AliasRule
-     */
-    public function alias($rule, $route, array $option = [])
-    {
-        $aliasRule = new AliasRule($this, $this->group, $rule, $route, $option);
-
-        $this->alias[$rule] = $aliasRule;
-
-        return $aliasRule;
-    }
-
-    /**
-     * 获取别名路由定义
-     * @access public
-     * @param  string    $name 路由别名
-     * @return string|array|null
-     */
-    public function getAlias($name = null)
-    {
-        if (is_null($name)) {
-            return $this->alias;
-        }
-
-        return isset($this->alias[$name]) ? $this->alias[$name] : null;
-    }
-
-    /**
-     * 设置不同请求类型下面的方法前缀
-     * @access public
-     * @param  string|array  $method 请求类型
-     * @param  string        $prefix 类型前缀
-     * @return $this
-     */
-    public function setMethodPrefix($method, $prefix = '')
-    {
-        if (is_array($method)) {
-            $this->methodPrefix = array_merge($this->methodPrefix, array_change_key_case($method));
-        } else {
-            $this->methodPrefix[strtolower($method)] = $prefix;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 获取请求类型的方法前缀
-     * @access public
-     * @param  string    $method 请求类型
-     * @param  string    $prefix 类型前缀
-     * @return string|null
-     */
-    public function getMethodPrefix($method)
-    {
-        $method = strtolower($method);
-
-        return isset($this->methodPrefix[$method]) ? $this->methodPrefix[$method] : null;
-    }
-
-    /**
-     * rest方法定义和修改
-     * @access public
-     * @param  string        $name 方法名称
-     * @param  array|bool    $resource 资源
-     * @return $this
-     */
-    public function rest($name, $resource = [])
-    {
-        if (is_array($name)) {
-            $this->rest = $resource ? $name : array_merge($this->rest, $name);
-        } else {
-            $this->rest[$name] = $resource;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 获取rest方法定义的参数
-     * @access public
-     * @param  string        $name 方法名称
-     * @return array|null
-     */
-    public function getRest($name = null)
-    {
-        if (is_null($name)) {
-            return $this->rest;
-        }
-
-        return isset($this->rest[$name]) ? $this->rest[$name] : null;
-    }
-
-    /**
-     * 注册未匹配路由规则后的处理
-     * @access public
-     * @param  string    $route 路由地址
-     * @param  string    $method 请求类型
-     * @param  array     $option 路由参数
-     * @return RuleItem
-     */
-    public function miss($route, $method = '*', array $option = [])
-    {
-        return $this->group->addMissRule($route, $method, $option);
-    }
-
-    /**
-     * 注册一个自动解析的URL路由
-     * @access public
-     * @param  string    $route 路由地址
-     * @return RuleItem
-     */
-    public function auto($route)
-    {
-        return $this->group->addAutoRule($route);
-    }
-
-    /**
-     * 检测URL路由
-     * @access public
-     * @param  string    $url URL地址
-     * @param  string    $depr URL分隔符
-     * @param  bool      $must 是否强制路由
-     * @param  bool      $completeMatch   路由是否完全匹配
-     * @return Dispatch
-     * @throws RouteNotFoundException
-     */
-    public function check($url, $depr = '/', $must = false, $completeMatch = false)
-    {
-        // 自动检测域名路由
-        $domain = $this->checkDomain();
-        $url    = str_replace($depr, '|', $url);
-
-        $result = $domain->check($this->request, $url, $depr, $completeMatch);
-
-        if (false === $result && !empty($this->cross)) {
-            // 检测跨域路由
-            $result = $this->cross->check($this->request, $url, $depr, $completeMatch);
-        }
-
-        if (false !== $result) {
-            // 路由匹配
-            return $result;
-        } elseif ($must) {
-            // 强制路由不匹配则抛出异常
-            throw new RouteNotFoundException();
-        }
-
-        // 默认路由解析
-        return new UrlDispatch($url, ['depr' => $depr, 'auto_search' => $this->autoSearchController]);
-    }
-
-    /**
-     * 检测域名的路由规则
-     * @access protected
-     * @return Domain
-     */
-    protected function checkDomain()
-    {
-        // 获取当前子域名
-        $subDomain = $this->request->subDomain();
-
-        $item = false;
-
-        if ($subDomain && count($this->domains) > 1) {
-            $domain  = explode('.', $subDomain);
-            $domain2 = array_pop($domain);
-
-            if ($domain) {
-                // 存在三级域名
-                $domain3 = array_pop($domain);
-            }
-
-            if ($subDomain && isset($this->domains[$subDomain])) {
-                // 子域名配置
-                $item = $this->domains[$subDomain];
-            } elseif (isset($this->domains['*.' . $domain2]) && !empty($domain3)) {
-                // 泛三级域名
-                $item      = $this->domains['*.' . $domain2];
-                $panDomain = $domain3;
-            } elseif (isset($this->domains['*']) && !empty($domain2)) {
-                // 泛二级域名
-                if ('www' != $domain2) {
-                    $item      = $this->domains['*'];
-                    $panDomain = $domain2;
-                }
-            }
-
-            if (isset($panDomain)) {
-                // 保存当前泛域名
-                $this->request->panDomain($panDomain);
-            }
-        }
-
-        if (false === $item) {
-            // 检测当前完整域名
-            $item = $this->domains[$this->host];
-        }
-
-        if (is_string($item)) {
-            $item = $this->domains[$item];
-        }
-
-        return $item;
-    }
-
-    /**
-     * 设置全局的路由分组参数
-     * @access public
-     * @param  string    $method     方法名
-     * @param  array     $args       调用参数
-     * @return RuleGroup
-     */
-    public function __call($method, $args)
-    {
-        return call_user_func_array([$this->group, $method], $args);
-    }
-}

+ 0 - 531
thinkphp/library/think/Session.php

@@ -1,531 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ClassNotFoundException;
-
-class Session
-{
-    /**
-     * 前缀
-     * @var string
-     */
-    protected $prefix = '';
-
-    /**
-     * 是否初始化
-     * @var bool
-     */
-    protected $init = null;
-
-    /**
-     * 锁驱动
-     * @var object
-     */
-    protected $lockDriver = null;
-
-    /**
-     * 锁key
-     * @var string
-     */
-    protected $sessKey = 'PHPSESSID';
-
-    /**
-     * 锁超时时间
-     * @var integer
-     */
-    protected $lockTimeout = 3;
-
-    /**
-     * 是否启用锁机制
-     * @var bool
-     */
-    protected $lock = false;
-
-    /**
-     * 设置或者获取session作用域(前缀)
-     * @access public
-     * @param  string $prefix
-     * @return string|void
-     */
-    public function prefix($prefix = '')
-    {
-        empty($this->init) && $this->boot();
-
-        if (empty($prefix) && null !== $prefix) {
-            return $this->prefix;
-        } else {
-            $this->prefix = $prefix;
-        }
-    }
-
-    /**
-     * session初始化
-     * @access public
-     * @param  array $config
-     * @return void
-     * @throws \think\Exception
-     */
-    public function init(array $config = [])
-    {
-        if (empty($config)) {
-            $config = Container::get('config')->pull('session');
-        }
-
-        // 记录初始化信息
-        Container::get('app')->log('[ SESSION ] INIT ' . var_export($config, true));
-        $isDoStart = false;
-        if (isset($config['use_trans_sid'])) {
-            ini_set('session.use_trans_sid', $config['use_trans_sid'] ? 1 : 0);
-        }
-
-        // 启动session
-        if (!empty($config['auto_start']) && PHP_SESSION_ACTIVE != session_status()) {
-            ini_set('session.auto_start', 0);
-            $isDoStart = true;
-        }
-
-        if (isset($config['prefix'])) {
-            $this->prefix = $config['prefix'];
-        }
-
-        if (isset($config['use_lock'])) {
-            $this->lock = $config['use_lock'];
-        }
-
-        if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) {
-            session_id($_REQUEST[$config['var_session_id']]);
-        } elseif (isset($config['id']) && !empty($config['id'])) {
-            session_id($config['id']);
-        }
-
-        if (isset($config['name'])) {
-            session_name($config['name']);
-        }
-
-        if (isset($config['path'])) {
-            session_save_path($config['path']);
-        }
-
-        if (isset($config['domain'])) {
-            ini_set('session.cookie_domain', $config['domain']);
-        }
-
-        if (isset($config['expire'])) {
-            ini_set('session.gc_maxlifetime', $config['expire']);
-            ini_set('session.cookie_lifetime', $config['expire']);
-        }
-
-        if (isset($config['secure'])) {
-            ini_set('session.cookie_secure', $config['secure']);
-        }
-
-        if (isset($config['httponly'])) {
-            ini_set('session.cookie_httponly', $config['httponly']);
-        }
-
-        if (isset($config['use_cookies'])) {
-            ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0);
-        }
-
-        if (isset($config['cache_limiter'])) {
-            session_cache_limiter($config['cache_limiter']);
-        }
-
-        if (isset($config['cache_expire'])) {
-            session_cache_expire($config['cache_expire']);
-        }
-
-        if (!empty($config['type'])) {
-            // 读取session驱动
-            $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\session\\driver\\' . ucwords($config['type']);
-
-            // 检查驱动类
-            if (!class_exists($class) || !session_set_save_handler(new $class($config))) {
-                throw new ClassNotFoundException('error session handler:' . $class, $class);
-            }
-        }
-
-        if ($isDoStart) {
-            session_start();
-            $this->init = true;
-        } else {
-            $this->init = false;
-        }
-    }
-
-    /**
-     * session自动启动或者初始化
-     * @access public
-     * @return void
-     */
-    public function boot()
-    {
-        if (is_null($this->init)) {
-            $this->init();
-        } elseif (false === $this->init) {
-            if (PHP_SESSION_ACTIVE != session_status()) {
-                session_start();
-            }
-            $this->init = true;
-        }
-    }
-
-    /**
-     * session设置
-     * @access public
-     * @param  string        $name session名称
-     * @param  mixed         $value session值
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return void
-     */
-    public function set($name, $value, $prefix = null)
-    {
-        $this->lock();
-
-        empty($this->init) && $this->boot();
-
-        $prefix = !is_null($prefix) ? $prefix : $this->prefix;
-
-        if (strpos($name, '.')) {
-            // 二维数组赋值
-            list($name1, $name2) = explode('.', $name);
-            if ($prefix) {
-                $_SESSION[$prefix][$name1][$name2] = $value;
-            } else {
-                $_SESSION[$name1][$name2] = $value;
-            }
-        } elseif ($prefix) {
-            $_SESSION[$prefix][$name] = $value;
-        } else {
-            $_SESSION[$name] = $value;
-        }
-
-        $this->unlock();
-    }
-
-    /**
-     * session获取
-     * @access public
-     * @param  string        $name session名称
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return mixed
-     */
-    public function get($name = '', $prefix = null)
-    {
-        $this->lock();
-
-        empty($this->init) && $this->boot();
-
-        $prefix = !is_null($prefix) ? $prefix : $this->prefix;
-
-        $value = $prefix ? (!empty($_SESSION[$prefix]) ? $_SESSION[$prefix] : []) : $_SESSION;
-
-        if ('' != $name) {
-            $name = explode('.', $name);
-
-            foreach ($name as $val) {
-                if (isset($value[$val])) {
-                    $value = $value[$val];
-                } else {
-                    $value = null;
-                    break;
-                }
-            }
-        }
-
-        $this->unlock();
-
-        return $value;
-    }
-
-    /**
-     * session 读写锁驱动实例化
-     */
-    protected function initDriver()
-    {
-        // 不在 init 方法中实例化lockDriver,是因为 init 方法不一定先于 set 或 get 方法调用
-        $config = Container::get('config')->pull('session');
-
-        if (!empty($config['type']) && isset($config['use_lock']) && $config['use_lock']) {
-            // 读取session驱动
-            $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\session\\driver\\' . ucwords($config['type']);
-
-            // 检查驱动类及类中是否存在 lock 和 unlock 函数
-            if (class_exists($class) && method_exists($class, 'lock') && method_exists($class, 'unlock')) {
-                $this->lockDriver = new $class($config);
-            }
-        }
-
-        // 通过cookie获得session_id
-        if (isset($config['name']) && $config['name']) {
-            $this->sessKey = $config['name'];
-        }
-
-        if (isset($config['lock_timeout']) && $config['lock_timeout'] > 0) {
-            $this->lockTimeout = $config['lock_timeout'];
-        }
-    }
-
-    /**
-     * session 读写加锁
-     * @access protected
-     * @return void
-     */
-    protected function lock()
-    {
-        if (empty($this->lock)) {
-            return;
-        }
-
-        $this->initDriver();
-
-        if (null !== $this->lockDriver && method_exists($this->lockDriver, 'lock')) {
-            $t = time();
-            // 使用 session_id 作为互斥条件,即只对同一 session_id 的会话互斥。第一次请求没有 session_id
-            $sessID = isset($_COOKIE[$this->sessKey]) ? $_COOKIE[$this->sessKey] : '';
-
-            do {
-                if (time() - $t > $this->lockTimeout) {
-                    $this->unlock();
-                }
-            } while (!$this->lockDriver->lock($sessID, $this->lockTimeout));
-        }
-    }
-
-    /**
-     * session 读写解锁
-     * @access protected
-     * @return void
-     */
-    protected function unlock()
-    {
-        if (empty($this->lock)) {
-            return;
-        }
-
-        $this->pause();
-
-        if ($this->lockDriver && method_exists($this->lockDriver, 'unlock')) {
-            $sessID = isset($_COOKIE[$this->sessKey]) ? $_COOKIE[$this->sessKey] : '';
-            $this->lockDriver->unlock($sessID);
-        }
-    }
-
-    /**
-     * session获取并删除
-     * @access public
-     * @param  string        $name session名称
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return mixed
-     */
-    public function pull($name, $prefix = null)
-    {
-        $result = $this->get($name, $prefix);
-
-        if ($result) {
-            $this->delete($name, $prefix);
-            return $result;
-        } else {
-            return;
-        }
-    }
-
-    /**
-     * session设置 下一次请求有效
-     * @access public
-     * @param  string        $name session名称
-     * @param  mixed         $value session值
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return void
-     */
-    public function flash($name, $value)
-    {
-        $this->set($name, $value);
-
-        if (!$this->has('__flash__.__time__')) {
-            $this->set('__flash__.__time__', $_SERVER['REQUEST_TIME_FLOAT']);
-        }
-
-        $this->push('__flash__', $name);
-    }
-
-    /**
-     * 清空当前请求的session数据
-     * @access public
-     * @return void
-     */
-    public function flush()
-    {
-        if (!$this->init) {
-            return;
-        }
-
-        $item = $this->get('__flash__');
-
-        if (!empty($item)) {
-            $time = $item['__time__'];
-
-            if ($_SERVER['REQUEST_TIME_FLOAT'] > $time) {
-                unset($item['__time__']);
-                $this->delete($item);
-                $this->set('__flash__', []);
-            }
-        }
-    }
-
-    /**
-     * 删除session数据
-     * @access public
-     * @param  string|array  $name session名称
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return void
-     */
-    public function delete($name, $prefix = null)
-    {
-        empty($this->init) && $this->boot();
-
-        $prefix = !is_null($prefix) ? $prefix : $this->prefix;
-
-        if (is_array($name)) {
-            foreach ($name as $key) {
-                $this->delete($key, $prefix);
-            }
-        } elseif (strpos($name, '.')) {
-            list($name1, $name2) = explode('.', $name);
-            if ($prefix) {
-                unset($_SESSION[$prefix][$name1][$name2]);
-            } else {
-                unset($_SESSION[$name1][$name2]);
-            }
-        } else {
-            if ($prefix) {
-                unset($_SESSION[$prefix][$name]);
-            } else {
-                unset($_SESSION[$name]);
-            }
-        }
-    }
-
-    /**
-     * 清空session数据
-     * @access public
-     * @param  string|null   $prefix 作用域(前缀)
-     * @return void
-     */
-    public function clear($prefix = null)
-    {
-        empty($this->init) && $this->boot();
-        $prefix = !is_null($prefix) ? $prefix : $this->prefix;
-
-        if ($prefix) {
-            unset($_SESSION[$prefix]);
-        } else {
-            $_SESSION = [];
-        }
-    }
-
-    /**
-     * 判断session数据
-     * @access public
-     * @param  string        $name session名称
-     * @param  string|null   $prefix
-     * @return bool
-     */
-    public function has($name, $prefix = null)
-    {
-        empty($this->init) && $this->boot();
-        $prefix = !is_null($prefix) ? $prefix : $this->prefix;
-
-        if (strpos($name, '.')) {
-            // 支持数组
-            list($name1, $name2) = explode('.', $name);
-
-            return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]);
-        } else {
-            return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]);
-        }
-    }
-
-    /**
-     * 添加数据到一个session数组
-     * @access public
-     * @param  string  $key
-     * @param  mixed   $value
-     * @return void
-     */
-    public function push($key, $value)
-    {
-        $array = $this->get($key);
-
-        if (is_null($array)) {
-            $array = [];
-        }
-
-        $array[] = $value;
-
-        $this->set($key, $array);
-    }
-
-    /**
-     * 启动session
-     * @access public
-     * @return void
-     */
-    public function start()
-    {
-        session_start();
-
-        $this->init = true;
-    }
-
-    /**
-     * 销毁session
-     * @access public
-     * @return void
-     */
-    public function destroy()
-    {
-        if (!empty($_SESSION)) {
-            $_SESSION = [];
-        }
-
-        session_unset();
-        session_destroy();
-
-        $this->init       = null;
-        $this->lockDriver = null;
-    }
-
-    /**
-     * 重新生成session_id
-     * @access public
-     * @param  bool $delete 是否删除关联会话文件
-     * @return void
-     */
-    public function regenerate($delete = false)
-    {
-        session_regenerate_id($delete);
-    }
-
-    /**
-     * 暂停session
-     * @access public
-     * @return void
-     */
-    public function pause()
-    {
-        // 暂停session
-        session_write_close();
-        $this->init = false;
-    }
-}

+ 0 - 1304
thinkphp/library/think/Template.php

@@ -1,1304 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\TemplateNotFoundException;
-
-/**
- * ThinkPHP分离出来的模板引擎
- * 支持XML标签和普通标签的模板解析
- * 编译型模板引擎 支持动态缓存
- */
-class Template
-{
-    /**
-     * 模板变量
-     * @var array
-     */
-    protected $data = [];
-
-    /**
-     * 模板配置参数
-     * @var array
-     */
-    protected $config = [
-        'view_path'          => '', // 模板路径
-        'view_base'          => '',
-        'view_suffix'        => 'html', // 默认模板文件后缀
-        'view_depr'          => DIRECTORY_SEPARATOR,
-        'cache_suffix'       => 'php', // 默认模板缓存后缀
-        'tpl_deny_func_list' => 'echo,exit', // 模板引擎禁用函数
-        'tpl_deny_php'       => false, // 默认模板引擎是否禁用PHP原生代码
-        'tpl_begin'          => '{', // 模板引擎普通标签开始标记
-        'tpl_end'            => '}', // 模板引擎普通标签结束标记
-        'strip_space'        => false, // 是否去除模板文件里面的html空格与换行
-        'tpl_cache'          => true, // 是否开启模板编译缓存,设为false则每次都会重新编译
-        'compile_type'       => 'file', // 模板编译类型
-        'cache_prefix'       => '', // 模板缓存前缀标识,可以动态改变
-        'cache_time'         => 0, // 模板缓存有效期 0 为永久,(以数字为值,单位:秒)
-        'layout_on'          => false, // 布局模板开关
-        'layout_name'        => 'layout', // 布局模板入口文件
-        'layout_item'        => '{__CONTENT__}', // 布局模板的内容替换标识
-        'taglib_begin'       => '{', // 标签库标签开始标记
-        'taglib_end'         => '}', // 标签库标签结束标记
-        'taglib_load'        => true, // 是否使用内置标签库之外的其它标签库,默认自动检测
-        'taglib_build_in'    => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序
-        'taglib_pre_load'    => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔
-        'display_cache'      => false, // 模板渲染缓存
-        'cache_id'           => '', // 模板缓存ID
-        'tpl_replace_string' => [],
-        'tpl_var_identify'   => 'array', // .语法变量识别,array|object|'', 为空时自动识别
-        'default_filter'     => 'htmlentities', // 默认过滤方法 用于普通标签输出
-    ];
-
-    /**
-     * 保留内容信息
-     * @var array
-     */
-    private $literal = [];
-
-    /**
-     * 模板包含信息
-     * @var array
-     */
-    private $includeFile = [];
-
-    /**
-     * 模板存储对象
-     * @var object
-     */
-    protected $storage;
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $config
-     */
-    public function __construct(array $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'], '/');
-
-        // 初始化模板编译存储器
-        $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 public
-     * @param  mixed $name
-     * @param  mixed $value
-     * @return void
-     */
-    public function assign($name, $value = '')
-    {
-        if (is_array($name)) {
-            $this->data = array_merge($this->data, $name);
-        } else {
-            $this->data[$name] = $value;
-        }
-    }
-
-    /**
-     * 模板引擎参数赋值
-     * @access public
-     * @param  mixed $name
-     * @param  mixed $value
-     */
-    public function __set($name, $value)
-    {
-        $this->config[$name] = $value;
-    }
-
-    /**
-     * 模板引擎配置项
-     * @access public
-     * @param  array|string $config
-     * @return void|array
-     */
-    public function config($config)
-    {
-        if (is_array($config)) {
-            $this->config = array_merge($this->config, $config);
-        } elseif (isset($this->config[$config])) {
-            return $this->config[$config];
-        }
-    }
-
-    /**
-     * 模板变量获取
-     * @access public
-     * @param  string $name 变量名
-     * @return mixed
-     */
-    public function get($name = '')
-    {
-        if ('' == $name) {
-            return $this->data;
-        }
-
-        $data = $this->data;
-
-        foreach (explode('.', $name) as $key => $val) {
-            if (isset($data[$val])) {
-                $data = $data[$val];
-            } else {
-                $data = null;
-                break;
-            }
-        }
-
-        return $data;
-    }
-
-    /**
-     * 渲染模板文件
-     * @access public
-     * @param  string    $template 模板文件
-     * @param  array     $vars 模板变量
-     * @param  array     $config 模板参数
-     * @return void
-     */
-    public function fetch($template, $vars = [], $config = [])
-    {
-        if ($vars) {
-            $this->data = $vars;
-        }
-
-        if ($config) {
-            $this->config($config);
-        }
-
-        $cache = Container::get('cache');
-
-        if (!empty($this->config['cache_id']) && $this->config['display_cache']) {
-            // 读取渲染缓存
-            $cacheContent = $cache->get($this->config['cache_id']);
-
-            if (false !== $cacheContent) {
-                echo $cacheContent;
-                return;
-            }
-        }
-
-        $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'], '.');
-
-            if (!$this->checkCache($cacheFile)) {
-                // 缓存无效 重新模板编译
-                $content = file_get_contents($template);
-                $this->compiler($content, $cacheFile);
-            }
-
-            // 页面缓存
-            ob_start();
-            ob_implicit_flush(0);
-
-            // 读取编译存储
-            $this->storage->read($cacheFile, $this->data);
-
-            // 获取并清空缓存
-            $content = ob_get_clean();
-
-            if (!empty($this->config['cache_id']) && $this->config['display_cache']) {
-                // 缓存页面输出
-                $cache->set($this->config['cache_id'], $content, $this->config['cache_time']);
-            }
-
-            echo $content;
-        }
-    }
-
-    /**
-     * 渲染模板内容
-     * @access public
-     * @param  string    $content 模板内容
-     * @param  array     $vars 模板变量
-     * @param  array     $config 模板参数
-     * @return void
-     */
-    public function display($content, $vars = [], $config = [])
-    {
-        if ($vars) {
-            $this->data = $vars;
-        }
-
-        if ($config) {
-            $this->config($config);
-        }
-
-        $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . '.' . ltrim($this->config['cache_suffix'], '.');
-
-        if (!$this->checkCache($cacheFile)) {
-            // 缓存无效 模板编译
-            $this->compiler($content, $cacheFile);
-        }
-
-        // 读取编译存储
-        $this->storage->read($cacheFile, $this->data);
-    }
-
-    /**
-     * 设置布局
-     * @access public
-     * @param  mixed     $name 布局模板名称 false 则关闭布局
-     * @param  string    $replace 布局模板内容替换标识
-     * @return object
-     */
-    public function layout($name, $replace = '')
-    {
-        if (false === $name) {
-            // 关闭布局
-            $this->config['layout_on'] = false;
-        } else {
-            // 开启布局
-            $this->config['layout_on'] = true;
-
-            // 名称必须为字符串
-            if (is_string($name)) {
-                $this->config['layout_name'] = $name;
-            }
-
-            if (!empty($replace)) {
-                $this->config['layout_item'] = $replace;
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 检查编译缓存是否有效
-     * 如果无效则需要重新编译
-     * @access private
-     * @param  string $cacheFile 缓存文件名
-     * @return boolean
-     */
-    private function checkCache($cacheFile)
-    {
-        if (!$this->config['tpl_cache'] || !is_file($cacheFile) || !$handle = @fopen($cacheFile, "r")) {
-            return false;
-        }
-
-        // 读取第一行
-        preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches);
-
-        if (!isset($matches[1])) {
-            return false;
-        }
-
-        $includeFile = unserialize($matches[1]);
-
-        if (!is_array($includeFile)) {
-            return false;
-        }
-
-        // 检查模板文件是否有更新
-        foreach ($includeFile as $path => $time) {
-            if (is_file($path) && filemtime($path) > $time) {
-                // 模板文件如果有更新则缓存需要更新
-                return false;
-            }
-        }
-
-        // 检查编译存储是否有效
-        return $this->storage->check($cacheFile, $this->config['cache_time']);
-    }
-
-    /**
-     * 检查编译缓存是否存在
-     * @access public
-     * @param  string $cacheId 缓存的id
-     * @return boolean
-     */
-    public function isCache($cacheId)
-    {
-        if ($cacheId && $this->config['display_cache']) {
-            // 缓存页面输出
-            return Container::get('cache')->has($cacheId);
-        }
-
-        return false;
-    }
-
-    /**
-     * 编译模板文件内容
-     * @access private
-     * @param  string    $content 模板内容
-     * @param  string    $cacheFile 缓存文件名
-     * @return void
-     */
-    private function compiler(&$content, $cacheFile)
-    {
-        // 判断是否启用布局
-        if ($this->config['layout_on']) {
-            if (false !== strpos($content, '{__NOLAYOUT__}')) {
-                // 可以单独定义不使用布局
-                $content = str_replace('{__NOLAYOUT__}', '', $content);
-            } else {
-                // 读取布局模板
-                $layoutFile = $this->parseTemplateFile($this->config['layout_name']);
-
-                if ($layoutFile) {
-                    // 替换布局的主体内容
-                    $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));
-                }
-            }
-        } else {
-            $content = str_replace('{__NOLAYOUT__}', '', $content);
-        }
-
-        // 模板解析
-        $this->parse($content);
-
-        if ($this->config['strip_space']) {
-            /* 去除html空格与换行 */
-            $find    = ['~>\s+<~', '~>(\s+\n|\r)~'];
-            $replace = ['><', '>'];
-            $content = preg_replace($find, $replace, $content);
-        }
-
-        // 优化生成的php代码
-        $content = preg_replace('/\?>\s*<\?php\s(?!echo\b)/s', '', $content);
-
-        // 模板过滤输出
-        $replace = $this->config['tpl_replace_string'];
-        $content = str_replace(array_keys($replace), array_values($replace), $content);
-
-        // 添加安全代码及模板引用记录
-        $content = '<?php /*' . serialize($this->includeFile) . '*/ ?>' . "\n" . $content;
-        // 编译存储
-        $this->storage->write($cacheFile, $content);
-
-        $this->includeFile = [];
-    }
-
-    /**
-     * 模板解析入口
-     * 支持普通标签和TagLib解析 支持自定义标签库
-     * @access public
-     * @param  string $content 要解析的模板内容
-     * @return void
-     */
-    public function parse(&$content)
-    {
-        // 内容为空不解析
-        if (empty($content)) {
-            return;
-        }
-
-        // 替换literal标签内容
-        $this->parseLiteral($content);
-
-        // 解析继承
-        $this->parseExtend($content);
-
-        // 解析布局
-        $this->parseLayout($content);
-
-        // 检查include语法
-        $this->parseInclude($content);
-
-        // 替换包含文件中literal标签内容
-        $this->parseLiteral($content);
-
-        // 检查PHP语法
-        $this->parsePhp($content);
-
-        // 获取需要引入的标签库列表
-        // 标签库只需要定义一次,允许引入多个一次
-        // 一般放在文件的最前面
-        // 格式:<taglib name="html,mytag..." />
-        // 当TAGLIB_LOAD配置为true时才会进行检测
-        if ($this->config['taglib_load']) {
-            $tagLibs = $this->getIncludeTagLib($content);
-
-            if (!empty($tagLibs)) {
-                // 对导入的TagLib进行解析
-                foreach ($tagLibs as $tagLibName) {
-                    $this->parseTagLib($tagLibName, $content);
-                }
-            }
-        }
-
-        // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀
-        if ($this->config['taglib_pre_load']) {
-            $tagLibs = explode(',', $this->config['taglib_pre_load']);
-
-            foreach ($tagLibs as $tag) {
-                $this->parseTagLib($tag, $content);
-            }
-        }
-
-        // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀
-        $tagLibs = explode(',', $this->config['taglib_build_in']);
-
-        foreach ($tagLibs as $tag) {
-            $this->parseTagLib($tag, $content, true);
-        }
-
-        // 解析普通模板标签 {$tagName}
-        $this->parseTag($content);
-
-        // 还原被替换的Literal标签
-        $this->parseLiteral($content, true);
-    }
-
-    /**
-     * 检查PHP语法
-     * @access private
-     * @param  string $content 要解析的模板内容
-     * @return void
-     * @throws \think\Exception
-     */
-    private function parsePhp(&$content)
-    {
-        // 短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识
-        $content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>' . "\n", $content);
-
-        // PHP语法检查
-        if ($this->config['tpl_deny_php'] && false !== strpos($content, '<?php')) {
-            throw new Exception('not allow php tag');
-        }
-    }
-
-    /**
-     * 解析模板中的布局标签
-     * @access private
-     * @param  string $content 要解析的模板内容
-     * @return void
-     */
-    private function parseLayout(&$content)
-    {
-        // 读取模板中的布局标签
-        if (preg_match($this->getRegex('layout'), $content, $matches)) {
-            // 替换Layout标签
-            $content = str_replace($matches[0], '', $content);
-            // 解析Layout标签
-            $array = $this->parseAttr($matches[0]);
-
-            if (!$this->config['layout_on'] || $this->config['layout_name'] != $array['name']) {
-                // 读取布局模板
-                $layoutFile = $this->parseTemplateFile($array['name']);
-
-                if ($layoutFile) {
-                    $replace = isset($array['replace']) ? $array['replace'] : $this->config['layout_item'];
-                    // 替换布局的主体内容
-                    $content = str_replace($replace, $content, file_get_contents($layoutFile));
-                }
-            }
-        } else {
-            $content = str_replace('{__NOLAYOUT__}', '', $content);
-        }
-    }
-
-    /**
-     * 解析模板中的include标签
-     * @access private
-     * @param  string $content 要解析的模板内容
-     * @return void
-     */
-    private function parseInclude(&$content)
-    {
-        $regex = $this->getRegex('include');
-        $func  = function ($template) use (&$func, &$regex, &$content) {
-            if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {
-                foreach ($matches as $match) {
-                    $array = $this->parseAttr($match[0]);
-                    $file  = $array['file'];
-                    unset($array['file']);
-
-                    // 分析模板文件名并读取内容
-                    $parseStr = $this->parseTemplateName($file);
-
-                    foreach ($array as $k => $v) {
-                        // 以$开头字符串转换成模板变量
-                        if (0 === strpos($v, '$')) {
-                            $v = $this->get(substr($v, 1));
-                        }
-
-                        $parseStr = str_replace('[' . $k . ']', $v, $parseStr);
-                    }
-
-                    $content = str_replace($match[0], $parseStr, $content);
-                    // 再次对包含文件进行模板分析
-                    $func($parseStr);
-                }
-                unset($matches);
-            }
-        };
-
-        // 替换模板中的include标签
-        $func($content);
-    }
-
-    /**
-     * 解析模板中的extend标签
-     * @access private
-     * @param  string $content 要解析的模板内容
-     * @return void
-     */
-    private function parseExtend(&$content)
-    {
-        $regex  = $this->getRegex('extend');
-        $array  = $blocks  = $baseBlocks  = [];
-        $extend = '';
-
-        $func = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) {
-            if (preg_match($regex, $template, $matches)) {
-                if (!isset($array[$matches['name']])) {
-                    $array[$matches['name']] = 1;
-                    // 读取继承模板
-                    $extend = $this->parseTemplateName($matches['name']);
-
-                    // 递归检查继承
-                    $func($extend);
-
-                    // 取得block标签内容
-                    $blocks = array_merge($blocks, $this->parseBlock($template));
-
-                    return;
-                }
-            } else {
-                // 取得顶层模板block标签内容
-                $baseBlocks = $this->parseBlock($template, true);
-
-                if (empty($extend)) {
-                    // 无extend标签但有block标签的情况
-                    $extend = $template;
-                }
-            }
-        };
-
-        $func($content);
-
-        if (!empty($extend)) {
-            if ($baseBlocks) {
-                $children = [];
-                foreach ($baseBlocks as $name => $val) {
-                    $replace = $val['content'];
-
-                    if (!empty($children[$name])) {
-                        // 如果包含有子block标签
-                        foreach ($children[$name] as $key) {
-                            $replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace);
-                        }
-                    }
-
-                    if (isset($blocks[$name])) {
-                        // 带有{__block__}表示与所继承模板的相应标签合并,而不是覆盖
-                        $replace = str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']);
-
-                        if (!empty($val['parent'])) {
-                            // 如果不是最顶层的block标签
-                            $parent = $val['parent'];
-
-                            if (isset($blocks[$parent])) {
-                                $blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']);
-                            }
-
-                            $blocks[$name]['content'] = $replace;
-                            $children[$parent][]      = $name;
-
-                            continue;
-                        }
-                    } elseif (!empty($val['parent'])) {
-                        // 如果子标签没有被继承则用原值
-                        $children[$val['parent']][] = $name;
-                        $blocks[$name]              = $val;
-                    }
-
-                    if (!$val['parent']) {
-                        // 替换模板中的顶级block标签
-                        $extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);
-                    }
-                }
-            }
-
-            $content = $extend;
-            unset($blocks, $baseBlocks);
-        }
-    }
-
-    /**
-     * 替换页面中的literal标签
-     * @access private
-     * @param  string   $content 模板内容
-     * @param  boolean  $restore 是否为还原
-     * @return void
-     */
-    private function parseLiteral(&$content, $restore = false)
-    {
-        $regex = $this->getRegex($restore ? 'restoreliteral' : 'literal');
-
-        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
-            if (!$restore) {
-                $count = count($this->literal);
-
-                // 替换literal标签
-                foreach ($matches as $match) {
-                    $this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2]));
-                    $content         = str_replace($match[0], "<!--###literal{$count}###-->", $content);
-                    $count++;
-                }
-            } else {
-                // 还原literal标签
-                foreach ($matches as $match) {
-                    $content = str_replace($match[0], $this->literal[$match[1]], $content);
-                }
-
-                // 清空literal记录
-                $this->literal = [];
-            }
-
-            unset($matches);
-        }
-    }
-
-    /**
-     * 获取模板中的block标签
-     * @access private
-     * @param  string   $content 模板内容
-     * @param  boolean  $sort 是否排序
-     * @return array
-     */
-    private function parseBlock(&$content, $sort = false)
-    {
-        $regex  = $this->getRegex('block');
-        $result = [];
-
-        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
-            $right = $keys = [];
-
-            foreach ($matches as $match) {
-                if (empty($match['name'][0])) {
-                    if (count($right) > 0) {
-                        $tag    = array_pop($right);
-                        $start  = $tag['offset'] + strlen($tag['tag']);
-                        $length = $match[0][1] - $start;
-
-                        $result[$tag['name']] = [
-                            'begin'   => $tag['tag'],
-                            'content' => substr($content, $start, $length),
-                            'end'     => $match[0][0],
-                            'parent'  => count($right) ? end($right)['name'] : '',
-                        ];
-
-                        $keys[$tag['name']] = $match[0][1];
-                    }
-                } else {
-                    // 标签头压入栈
-                    $right[] = [
-                        'name'   => $match[2][0],
-                        'offset' => $match[0][1],
-                        'tag'    => $match[0][0],
-                    ];
-                }
-            }
-
-            unset($right, $matches);
-
-            if ($sort) {
-                // 按block标签结束符在模板中的位置排序
-                array_multisort($keys, $result);
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * 搜索模板页面中包含的TagLib库
-     * 并返回列表
-     * @access private
-     * @param  string $content 模板内容
-     * @return array|null
-     */
-    private function getIncludeTagLib(&$content)
-    {
-        // 搜索是否有TagLib标签
-        if (preg_match($this->getRegex('taglib'), $content, $matches)) {
-            // 替换TagLib标签
-            $content = str_replace($matches[0], '', $content);
-
-            return explode(',', $matches['name']);
-        }
-    }
-
-    /**
-     * TagLib库解析
-     * @access public
-     * @param  string   $tagLib 要解析的标签库
-     * @param  string   $content 要解析的模板内容
-     * @param  boolean  $hide 是否隐藏标签库前缀
-     * @return void
-     */
-    public function parseTagLib($tagLib, &$content, $hide = false)
-    {
-        if (false !== strpos($tagLib, '\\')) {
-            // 支持指定标签库的命名空间
-            $className = $tagLib;
-            $tagLib    = substr($tagLib, strrpos($tagLib, '\\') + 1);
-        } else {
-            $className = '\\think\\template\\taglib\\' . ucwords($tagLib);
-        }
-
-        $tLib = new $className($this);
-
-        $tLib->parseTag($content, $hide ? '' : $tagLib);
-    }
-
-    /**
-     * 分析标签属性
-     * @access public
-     * @param  string   $str 属性字符串
-     * @param  string   $name 不为空时返回指定的属性名
-     * @return array
-     */
-    public function parseAttr($str, $name = null)
-    {
-        $regex = '/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is';
-        $array = [];
-
-        if (preg_match_all($regex, $str, $matches, PREG_SET_ORDER)) {
-            foreach ($matches as $match) {
-                $array[$match['name']] = $match['value'];
-            }
-            unset($matches);
-        }
-
-        if (!empty($name) && isset($array[$name])) {
-            return $array[$name];
-        }
-
-        return $array;
-    }
-
-    /**
-     * 模板标签解析
-     * 格式: {TagName:args [|content] }
-     * @access private
-     * @param  string $content 要解析的模板内容
-     * @return void
-     */
-    private function parseTag(&$content)
-    {
-        $regex = $this->getRegex('tag');
-
-        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
-            foreach ($matches as $match) {
-                $str  = stripslashes($match[1]);
-                $flag = substr($str, 0, 1);
-
-                switch ($flag) {
-                    case '$':
-                        // 解析模板变量 格式 {$varName}
-                        // 是否带有?号
-                        if (false !== $pos = strpos($str, '?')) {
-                            $array = preg_split('/([!=]={1,2}|(?<!-)[><]={0,1})/', substr($str, 0, $pos), 2, PREG_SPLIT_DELIM_CAPTURE);
-                            $name  = $array[0];
-
-                            $this->parseVar($name);
-                            //$this->parseVarFunction($name);
-
-                            $str = trim(substr($str, $pos + 1));
-                            $this->parseVar($str);
-                            $first = substr($str, 0, 1);
-
-                            if (strpos($name, ')')) {
-                                // $name为对象或是自动识别,或者含有函数
-                                if (isset($array[1])) {
-                                    $this->parseVar($array[2]);
-                                    $name .= $array[1] . $array[2];
-                                }
-
-                                switch ($first) {
-                                    case '?':
-                                        $this->parseVarFunction($name);
-                                        $str = '<?php echo (' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
-                                        break;
-                                    case '=':
-                                        $str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
-                                        break;
-                                    default:
-                                        $str = '<?php echo ' . $name . '?' . $str . '; ?>';
-                                }
-                            } else {
-                                if (isset($array[1])) {
-                                    $express = true;
-                                    $this->parseVar($array[2]);
-                                    $express = $name . $array[1] . $array[2];
-                                } else {
-                                    $express = false;
-                                }
-
-                                if (in_array($first, ['?', '=', ':'])) {
-                                    $str = trim(substr($str, 1));
-                                    if ('$' == substr($str, 0, 1)) {
-                                        $str = $this->parseVarFunction($str);
-                                    }
-                                }
-
-                                // $name为数组
-                                switch ($first) {
-                                    case '?':
-                                        // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx
-                                        $str = '<?php echo ' . ($express ?: 'isset(' . $name . ')') . ' ? ' . $this->parseVarFunction($name) . ' : ' . $str . '; ?>';
-                                        break;
-                                    case '=':
-                                        // {$varname?='xxx'} $varname为真时才输出xxx
-                                        $str = '<?php if(' . ($express ?: '!empty(' . $name . ')') . ') echo ' . $str . '; ?>';
-                                        break;
-                                    case ':':
-                                        // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
-                                        $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . ' ? ' . $this->parseVarFunction($name) . ' : ' . $str . '; ?>';
-                                        break;
-                                    default:
-                                        if (strpos($str, ':')) {
-                                            // {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b
-                                            $array = explode(':', $str, 2);
-
-                                            $array[0] = '$' == substr(trim($array[0]), 0, 1) ? $this->parseVarFunction($array[0]) : $array[0];
-                                            $array[1] = '$' == substr(trim($array[1]), 0, 1) ? $this->parseVarFunction($array[1]) : $array[1];
-
-                                            $str = implode(' : ', $array);
-                                        }
-                                        $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . ' ? ' . $str . '; ?>';
-                                }
-                            }
-                        } else {
-                            $this->parseVar($str);
-                            $this->parseVarFunction($str);
-                            $str = '<?php echo ' . $str . '; ?>';
-                        }
-                        break;
-                    case ':':
-                        // 输出某个函数的结果
-                        $str = substr($str, 1);
-                        $this->parseVar($str);
-                        $str = '<?php echo ' . $str . '; ?>';
-                        break;
-                    case '~':
-                        // 执行某个函数
-                        $str = substr($str, 1);
-                        $this->parseVar($str);
-                        $str = '<?php ' . $str . '; ?>';
-                        break;
-                    case '-':
-                    case '+':
-                        // 输出计算
-                        $this->parseVar($str);
-                        $str = '<?php echo ' . $str . '; ?>';
-                        break;
-                    case '/':
-                        // 注释标签
-                        $flag2 = substr($str, 1, 1);
-                        if ('/' == $flag2 || ('*' == $flag2 && substr(rtrim($str), -2) == '*/')) {
-                            $str = '';
-                        }
-                        break;
-                    default:
-                        // 未识别的标签直接返回
-                        $str = $this->config['tpl_begin'] . $str . $this->config['tpl_end'];
-                        break;
-                }
-
-                $content = str_replace($match[0], $str, $content);
-            }
-
-            unset($matches);
-        }
-    }
-
-    /**
-     * 模板变量解析,支持使用函数
-     * 格式: {$varname|function1|function2=arg1,arg2}
-     * @access public
-     * @param  string $varStr 变量数据
-     * @return void
-     */
-    public function parseVar(&$varStr)
-    {
-        $varStr = trim($varStr);
-
-        if (preg_match_all('/\$[a-zA-Z_](?>\w*)(?:[:\.][0-9a-zA-Z_](?>\w*))+/', $varStr, $matches, PREG_OFFSET_CAPTURE)) {
-            static $_varParseList = [];
-
-            while ($matches[0]) {
-                $match = array_pop($matches[0]);
-
-                //如果已经解析过该变量字串,则直接返回变量值
-                if (isset($_varParseList[$match[0]])) {
-                    $parseStr = $_varParseList[$match[0]];
-                } else {
-                    if (strpos($match[0], '.')) {
-                        $vars  = explode('.', $match[0]);
-                        $first = array_shift($vars);
-
-                        if ('$Think' == $first) {
-                            // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出
-                            $parseStr = $this->parseThinkVar($vars);
-                        } elseif ('$Request' == $first) {
-                            // 获取Request请求对象参数
-                            $method = array_shift($vars);
-                            if (!empty($vars)) {
-                                $params = implode('.', $vars);
-                                if ('true' != $params) {
-                                    $params = '\'' . $params . '\'';
-                                }
-                            } else {
-                                $params = '';
-                            }
-
-                            $parseStr = 'app(\'request\')->' . $method . '(' . $params . ')';
-                        } else {
-                            switch ($this->config['tpl_var_identify']) {
-                                case 'array': // 识别为数组
-                                    $parseStr = $first . '[\'' . implode('\'][\'', $vars) . '\']';
-                                    break;
-                                case 'obj': // 识别为对象
-                                    $parseStr = $first . '->' . implode('->', $vars);
-                                    break;
-                                default: // 自动判断数组或对象
-                                    $parseStr = '(is_array(' . $first . ')?' . $first . '[\'' . implode('\'][\'', $vars) . '\']:' . $first . '->' . implode('->', $vars) . ')';
-                            }
-                        }
-                    } else {
-                        $parseStr = str_replace(':', '->', $match[0]);
-                    }
-
-                    $_varParseList[$match[0]] = $parseStr;
-                }
-
-                $varStr = substr_replace($varStr, $parseStr, $match[1], strlen($match[0]));
-            }
-            unset($matches);
-        }
-    }
-
-    /**
-     * 对模板中使用了函数的变量进行解析
-     * 格式 {$varname|function1|function2=arg1,arg2}
-     * @access public
-     * @param  string    $varStr     变量字符串
-     * @param  bool      $autoescape 自动转义
-     * @return void
-     */
-    public function parseVarFunction(&$varStr, $autoescape = true)
-    {
-        if (!$autoescape && false === strpos($varStr, '|')) {
-            return $varStr;
-        } elseif ($autoescape && !preg_match('/\|(\s)?raw(\||\s)?/i', $varStr)) {
-            $varStr .= '|' . $this->config['default_filter'];
-        }
-
-        static $_varFunctionList = [];
-
-        $_key = md5($varStr);
-
-        //如果已经解析过该变量字串,则直接返回变量值
-        if (isset($_varFunctionList[$_key])) {
-            $varStr = $_varFunctionList[$_key];
-        } else {
-            $varArray = explode('|', $varStr);
-
-            // 取得变量名称
-            $name = trim(array_shift($varArray));
-
-            // 对变量使用函数
-            $length = count($varArray);
-
-            // 取得模板禁止使用函数列表
-            $template_deny_funs = explode(',', $this->config['tpl_deny_func_list']);
-
-            for ($i = 0; $i < $length; $i++) {
-                $args = explode('=', $varArray[$i], 2);
-
-                // 模板函数过滤
-                $fun = trim($args[0]);
-                if (in_array($fun, $template_deny_funs)) {
-                    continue;
-                }
-
-                switch (strtolower($fun)) {
-                    case 'raw':
-                        continue;
-                    case 'date':
-                        $name = 'date(' . $args[1] . ',!is_numeric(' . $name . ')? strtotime(' . $name . ') : ' . $name . ')';
-                        break;
-                    case 'first':
-                        $name = 'current(' . $name . ')';
-                        break;
-                    case 'last':
-                        $name = 'end(' . $name . ')';
-                        break;
-                    case 'upper':
-                        $name = 'strtoupper(' . $name . ')';
-                        break;
-                    case 'lower':
-                        $name = 'strtolower(' . $name . ')';
-                        break;
-                    case 'format':
-                        $name = 'sprintf(' . $args[1] . ',' . $name . ')';
-                        break;
-                    case 'default': // 特殊模板函数
-                        if (false === strpos($name, '(')) {
-                            $name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')';
-                        } else {
-                            $name = '(' . $name . ' ?: ' . $args[1] . ')';
-                        }
-                        break;
-                    default: // 通用模板函数
-                        if (isset($args[1])) {
-                            if (strstr($args[1], '###')) {
-                                $args[1] = str_replace('###', $name, $args[1]);
-                                $name    = "$fun($args[1])";
-                            } else {
-                                $name = "$fun($name,$args[1])";
-                            }
-                        } else {
-                            if (!empty($args[0])) {
-                                $name = "$fun($name)";
-                            }
-                        }
-                }
-            }
-
-            $_varFunctionList[$_key] = $name;
-            $varStr                  = $name;
-        }
-        return $varStr;
-    }
-
-    /**
-     * 特殊模板变量解析
-     * 格式 以 $Think. 打头的变量属于特殊模板变量
-     * @access public
-     * @param  array $vars 变量数组
-     * @return string
-     */
-    public function parseThinkVar($vars)
-    {
-        $type  = strtoupper(trim(array_shift($vars)));
-        $param = implode('.', $vars);
-
-        if ($vars) {
-            switch ($type) {
-                case 'SERVER':
-                    $parseStr = 'app(\'request\')->server(\'' . $param . '\')';
-                    break;
-                case 'GET':
-                    $parseStr = 'app(\'request\')->get(\'' . $param . '\')';
-                    break;
-                case 'POST':
-                    $parseStr = 'app(\'request\')->post(\'' . $param . '\')';
-                    break;
-                case 'COOKIE':
-                    $parseStr = 'app(\'cookie\')->get(\'' . $param . '\')';
-                    break;
-                case 'SESSION':
-                    $parseStr = 'app(\'session\')->get(\'' . $param . '\')';
-                    break;
-                case 'ENV':
-                    $parseStr = 'app(\'request\')->env(\'' . $param . '\')';
-                    break;
-                case 'REQUEST':
-                    $parseStr = 'app(\'request\')->request(\'' . $param . '\')';
-                    break;
-                case 'CONST':
-                    $parseStr = strtoupper($param);
-                    break;
-                case 'LANG':
-                    $parseStr = 'app(\'lang\')->get(\'' . $param . '\')';
-                    break;
-                case 'CONFIG':
-                    $parseStr = 'app(\'config\')->get(\'' . $param . '\')';
-                    break;
-                default:
-                    $parseStr = '\'\'';
-                    break;
-            }
-        } else {
-            switch ($type) {
-                case 'NOW':
-                    $parseStr = "date('Y-m-d g:i a',time())";
-                    break;
-                case 'VERSION':
-                    $parseStr = 'app()->version()';
-                    break;
-                case 'LDELIM':
-                    $parseStr = '\'' . ltrim($this->config['tpl_begin'], '\\') . '\'';
-                    break;
-                case 'RDELIM':
-                    $parseStr = '\'' . ltrim($this->config['tpl_end'], '\\') . '\'';
-                    break;
-                default:
-                    if (defined($type)) {
-                        $parseStr = $type;
-                    } else {
-                        $parseStr = '';
-                    }
-            }
-        }
-
-        return $parseStr;
-    }
-
-    /**
-     * 分析加载的模板文件并读取内容 支持多个模板文件读取
-     * @access private
-     * @param  string $templateName 模板文件名
-     * @return string
-     */
-    private function parseTemplateName($templateName)
-    {
-        $array    = explode(',', $templateName);
-        $parseStr = '';
-
-        foreach ($array as $templateName) {
-            if (empty($templateName)) {
-                continue;
-            }
-
-            if (0 === strpos($templateName, '$')) {
-                //支持加载变量文件名
-                $templateName = $this->get(substr($templateName, 1));
-            }
-
-            $template = $this->parseTemplateFile($templateName);
-
-            if ($template) {
-                // 获取模板文件内容
-                $parseStr .= file_get_contents($template);
-            }
-        }
-
-        return $parseStr;
-    }
-
-    /**
-     * 解析模板文件名
-     * @access private
-     * @param  string $template 文件名
-     * @return string|false
-     */
-    private function parseTemplateFile($template)
-    {
-        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
-            if (strpos($template, '@')) {
-                list($module, $template) = explode('@', $template);
-            }
-
-            if (0 !== strpos($template, '/')) {
-                $template = str_replace(['/', ':'], $this->config['view_depr'], $template);
-            } else {
-                $template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1));
-            }
-
-            if ($this->config['view_base']) {
-                $module = isset($module) ? $module : Container::get('request')->module();
-                $path   = $this->config['view_base'] . ($module ? $module . DIRECTORY_SEPARATOR : '');
-            } else {
-                $path = isset($module) ? Container::get('app')->getAppPath() . $module . DIRECTORY_SEPARATOR . basename($this->config['view_path']) . DIRECTORY_SEPARATOR : $this->config['view_path'];
-            }
-
-            $template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.');
-        }
-
-        if (is_file($template)) {
-            // 记录模板文件的更新时间
-            $this->includeFile[$template] = filemtime($template);
-
-            return $template;
-        }
-
-        throw new TemplateNotFoundException('template not exists:' . $template, $template);
-    }
-
-    /**
-     * 按标签生成正则
-     * @access private
-     * @param  string $tagName 标签名
-     * @return string
-     */
-    private function getRegex($tagName)
-    {
-        $regex = '';
-        if ('tag' == $tagName) {
-            $begin = $this->config['tpl_begin'];
-            $end   = $this->config['tpl_end'];
-
-            if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) {
-                $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
-            } else {
-                $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
-            }
-        } else {
-            $begin  = $this->config['taglib_begin'];
-            $end    = $this->config['taglib_end'];
-            $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
-
-            switch ($tagName) {
-                case 'block':
-                    if ($single) {
-                        $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P<name>[\$\w\-\/\.]+)\\1(?>[^' . $end . ']*)|\/' . $tagName . ')' . $end;
-                    } else {
-                        $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P<name>[\$\w\-\/\.]+)\\1(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end;
-                    }
-                    break;
-                case 'literal':
-                    if ($single) {
-                        $regex = '(' . $begin . $tagName . '\b(?>[^' . $end . ']*)' . $end . ')';
-                        $regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\b[^' . $end . ']*|\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)';
-                        $regex .= '(' . $begin . '\/' . $tagName . $end . ')';
-                    } else {
-                        $regex = '(' . $begin . $tagName . '\b(?>(?:(?!' . $end . ').)*)' . $end . ')';
-                        $regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\b(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)';
-                        $regex .= '(' . $begin . '\/' . $tagName . $end . ')';
-                    }
-                    break;
-                case 'restoreliteral':
-                    $regex = '<!--###literal(\d+)###-->';
-                    break;
-                case 'include':
-                    $name = 'file';
-                case 'taglib':
-                case 'layout':
-                case 'extend':
-                    if (empty($name)) {
-                        $name = 'name';
-                    }
-                    if ($single) {
-                        $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end;
-                    } else {
-                        $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end;
-                    }
-                    break;
-            }
-        }
-
-        return '/' . $regex . '/is';
-    }
-}

+ 0 - 357
thinkphp/library/think/Url.php

@@ -1,357 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class Url
-{
-    /**
-     * ROOT地址
-     * @var string
-     */
-    protected $root;
-
-    /**
-     * 绑定检查
-     * @var bool
-     */
-    protected $bindCheck;
-
-    /**
-     * 应用对象
-     * @var App
-     */
-    protected $app;
-
-    public function __construct(App $app)
-    {
-        $this->app = $app;
-
-        if (is_file($app->getRuntimePath() . 'route.php')) {
-            // 读取路由映射文件
-            $app['route']->setName(include $app->getRuntimePath() . 'route.php');
-        }
-    }
-
-    /**
-     * URL生成 支持路由反射
-     * @access public
-     * @param  string            $url 路由地址
-     * @param  string|array      $vars 参数(支持数组和字符串)a=val&b=val2... ['a'=>'val1', 'b'=>'val2']
-     * @param  string|bool       $suffix 伪静态后缀,默认为true表示获取配置值
-     * @param  boolean|string    $domain 是否显示域名 或者直接传入域名
-     * @return string
-     */
-    public function build($url = '', $vars = '', $suffix = true, $domain = false)
-    {
-        // 解析URL
-        if (0 === strpos($url, '[') && $pos = strpos($url, ']')) {
-            // [name] 表示使用路由命名标识生成URL
-            $name = substr($url, 1, $pos - 1);
-            $url  = 'name' . substr($url, $pos + 1);
-        }
-
-        if (false === strpos($url, '://') && 0 !== strpos($url, '/')) {
-            $info = parse_url($url);
-            $url  = !empty($info['path']) ? $info['path'] : '';
-
-            if (isset($info['fragment'])) {
-                // 解析锚点
-                $anchor = $info['fragment'];
-
-                if (false !== strpos($anchor, '?')) {
-                    // 解析参数
-                    list($anchor, $info['query']) = explode('?', $anchor, 2);
-                }
-
-                if (false !== strpos($anchor, '@')) {
-                    // 解析域名
-                    list($anchor, $domain) = explode('@', $anchor, 2);
-                }
-            } elseif (strpos($url, '@') && false === strpos($url, '\\')) {
-                // 解析域名
-                list($url, $domain) = explode('@', $url, 2);
-            }
-        }
-
-        // 解析参数
-        if (is_string($vars)) {
-            // aaa=1&bbb=2 转换成数组
-            parse_str($vars, $vars);
-        }
-
-        if ($url) {
-            $rule = $this->app['route']->getName(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : ''));
-
-            if (is_null($rule) && isset($info['query'])) {
-                $rule = $this->app['route']->getName($url);
-                // 解析地址里面参数 合并到vars
-                parse_str($info['query'], $params);
-                $vars = array_merge($params, $vars);
-                unset($info['query']);
-            }
-        }
-
-        if (!empty($rule) && $match = $this->getRuleUrl($rule, $vars)) {
-            // 匹配路由命名标识
-            $url = $match[0];
-
-            if (!empty($match[1])) {
-                $host = $this->app['config']->get('app_host') ?: $this->app['request']->host();
-                if ($domain || $match[1] != $host) {
-                    $domain = $match[1];
-                }
-            }
-
-            if (!is_null($match[2])) {
-                $suffix = $match[2];
-            }
-        } elseif (!empty($rule) && isset($name)) {
-            throw new \InvalidArgumentException('route name not exists:' . $name);
-        } else {
-            // 检查别名路由
-            $alias      = $this->app['route']->getAlias();
-            $matchAlias = false;
-
-            if ($alias) {
-                // 别名路由解析
-                foreach ($alias as $key => $item) {
-                    $val = $item->getRoute();
-
-                    if (0 === strpos($url, $val)) {
-                        $url        = $key . substr($url, strlen($val));
-                        $matchAlias = true;
-                        break;
-                    }
-                }
-            }
-
-            if (!$matchAlias) {
-                // 路由标识不存在 直接解析
-                $url = $this->parseUrl($url);
-            }
-
-            if (isset($info['query'])) {
-                // 解析地址里面参数 合并到vars
-                parse_str($info['query'], $params);
-                $vars = array_merge($params, $vars);
-            }
-        }
-
-        // 检测URL绑定
-        if (!$this->bindCheck) {
-            $bind = $this->app['route']->getBind($domain ?: null);
-
-            if ($bind && 0 === strpos($url, $bind)) {
-                $url = substr($url, strlen($bind) + 1);
-            }
-
-        }
-        // 还原URL分隔符
-        $depr = $this->app['config']->get('pathinfo_depr');
-        $url  = str_replace('/', $depr, $url);
-
-        // URL后缀
-        if ('/' == substr($url, -1) || '' == $url) {
-            $suffix = '';
-        } else {
-            $suffix = $this->parseSuffix($suffix);
-        }
-
-        // 锚点
-        $anchor = !empty($anchor) ? '#' . $anchor : '';
-
-        // 参数组装
-        if (!empty($vars)) {
-            // 添加参数
-            if ($this->app['config']->get('url_common_param')) {
-                $vars = http_build_query($vars);
-                $url .= $suffix . '?' . $vars . $anchor;
-            } else {
-                $paramType = $this->app['config']->get('url_param_type');
-
-                foreach ($vars as $var => $val) {
-                    if ('' !== trim($val)) {
-                        if ($paramType) {
-                            $url .= $depr . urlencode($val);
-                        } else {
-                            $url .= $depr . $var . $depr . urlencode($val);
-                        }
-                    }
-                }
-
-                $url .= $suffix . $anchor;
-            }
-        } else {
-            $url .= $suffix . $anchor;
-        }
-
-        // 检测域名
-        $domain = $this->parseDomain($url, $domain);
-
-        // URL组装
-        $url = $domain . rtrim($this->root ?: $this->app['request']->root(), '/') . '/' . ltrim($url, '/');
-
-        $this->bindCheck = false;
-
-        return $url;
-    }
-
-    // 直接解析URL地址
-    protected function parseUrl($url)
-    {
-        $request = $this->app['request'];
-
-        if (0 === strpos($url, '/')) {
-            // 直接作为路由地址解析
-            $url = substr($url, 1);
-        } elseif (false !== strpos($url, '\\')) {
-            // 解析到类
-            $url = ltrim(str_replace('\\', '/', $url), '/');
-        } elseif (0 === strpos($url, '@')) {
-            // 解析到控制器
-            $url = substr($url, 1);
-        } else {
-            // 解析到 模块/控制器/操作
-            $module     = $request->module();
-            $module     = $module ? $module . '/' : '';
-            $controller = $request->controller();
-
-            if ('' == $url) {
-                $action = $request->action();
-            } else {
-                $path       = explode('/', $url);
-                $action     = array_pop($path);
-                $controller = empty($path) ? $controller : array_pop($path);
-                $module     = empty($path) ? $module : array_pop($path) . '/';
-            }
-
-            if ($this->app['config']->get('url_convert')) {
-                $action     = strtolower($action);
-                $controller = Loader::parseName($controller);
-            }
-
-            $url = $module . $controller . '/' . $action;
-        }
-
-        return $url;
-    }
-
-    // 检测域名
-    protected function parseDomain(&$url, $domain)
-    {
-        if (!$domain) {
-            return '';
-        }
-
-        $rootDomain = $this->app['request']->rootDomain();
-        if (true === $domain) {
-
-            // 自动判断域名
-            $domain = $this->app['config']->get('app_host') ?: $this->app['request']->host();
-
-            $domains = $this->app['route']->getDomains();
-
-            if ($domains) {
-                $route_domain = array_keys($domains);
-                foreach ($route_domain as $domain_prefix) {
-                    if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) {
-                        foreach ($domains as $key => $rule) {
-                            $rule = is_array($rule) ? $rule[0] : $rule;
-                            if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) {
-                                $url    = ltrim($url, $rule);
-                                $domain = $key;
-
-                                // 生成对应子域名
-                                if (!empty($rootDomain)) {
-                                    $domain .= $rootDomain;
-                                }
-                                break;
-                            } elseif (false !== strpos($key, '*')) {
-                                if (!empty($rootDomain)) {
-                                    $domain .= $rootDomain;
-                                }
-
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        } elseif (!strpos($domain, '.')) {
-            $domain .= '.' . $rootDomain;
-        }
-
-        if (false !== strpos($domain, '://')) {
-            $scheme = '';
-        } else {
-            $scheme = $this->app['request']->isSsl() || $this->app['config']->get('is_https') ? 'https://' : 'http://';
-
-        }
-
-        return $scheme . $domain;
-    }
-
-    // 解析URL后缀
-    protected function parseSuffix($suffix)
-    {
-        if ($suffix) {
-            $suffix = true === $suffix ? $this->app['config']->get('url_html_suffix') : $suffix;
-
-            if ($pos = strpos($suffix, '|')) {
-                $suffix = substr($suffix, 0, $pos);
-            }
-        }
-
-        return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix;
-    }
-
-    // 匹配路由地址
-    public function getRuleUrl($rule, &$vars = [])
-    {
-        foreach ($rule as $item) {
-            list($url, $pattern, $domain, $suffix) = $item;
-            if (empty($pattern)) {
-                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);
-                    unset($vars[$key]);
-                    $url    = str_replace(['/?', '-?'], ['/', '-'], $url);
-                    $result = [rtrim($url, '?/-'), $domain, $suffix];
-                } elseif (2 == $val) {
-                    $url    = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
-                    $url    = str_replace(['/?', '-?'], ['/', '-'], $url);
-                    $result = [rtrim($url, '?/-'), $domain, $suffix];
-                } else {
-                    break;
-                }
-            }
-
-            if (isset($result)) {
-                return $result;
-            }
-        }
-
-        return false;
-    }
-
-    // 指定当前生成URL地址的root
-    public function root($root)
-    {
-        $this->root = $root;
-        $this->app['request']->root($root);
-    }
-}

+ 0 - 1487
thinkphp/library/think/Validate.php

@@ -1,1487 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-use think\exception\ClassNotFoundException;
-use think\validate\ValidateRule;
-
-class Validate
-{
-
-    /**
-     * 自定义验证类型
-     * @var array
-     */
-    protected static $type = [];
-
-    /**
-     * 验证类型别名
-     * @var array
-     */
-    protected $alias = [
-        '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq',
-    ];
-
-    /**
-     * 当前验证规则
-     * @var array
-     */
-    protected $rule = [];
-
-    /**
-     * 验证提示信息
-     * @var array
-     */
-    protected $message = [];
-
-    /**
-     * 验证字段描述
-     * @var array
-     */
-    protected $field = [];
-
-    /**
-     * 默认规则提示
-     * @var array
-     */
-    protected static $typeMsg = [
-        'require'     => ':attribute require',
-        'must'        => ':attribute must',
-        'number'      => ':attribute must be numeric',
-        'integer'     => ':attribute must be integer',
-        'float'       => ':attribute must be float',
-        'boolean'     => ':attribute must be bool',
-        'email'       => ':attribute not a valid email address',
-        'mobile'      => ':attribute not a valid mobile',
-        'array'       => ':attribute must be a array',
-        'accepted'    => ':attribute must be yes,on or 1',
-        'date'        => ':attribute not a valid datetime',
-        'file'        => ':attribute not a valid file',
-        'image'       => ':attribute not a valid image',
-        'alpha'       => ':attribute must be alpha',
-        'alphaNum'    => ':attribute must be alpha-numeric',
-        'alphaDash'   => ':attribute must be alpha-numeric, dash, underscore',
-        'activeUrl'   => ':attribute not a valid domain or ip',
-        'chs'         => ':attribute must be chinese',
-        'chsAlpha'    => ':attribute must be chinese or alpha',
-        'chsAlphaNum' => ':attribute must be chinese,alpha-numeric',
-        'chsDash'     => ':attribute must be chinese,alpha-numeric,underscore, dash',
-        'url'         => ':attribute not a valid url',
-        'ip'          => ':attribute not a valid ip',
-        'dateFormat'  => ':attribute must be dateFormat of :rule',
-        'in'          => ':attribute must be in :rule',
-        'notIn'       => ':attribute be notin :rule',
-        'between'     => ':attribute must between :1 - :2',
-        'notBetween'  => ':attribute not between :1 - :2',
-        'length'      => 'size of :attribute must be :rule',
-        'max'         => 'max size of :attribute must be :rule',
-        'min'         => 'min size of :attribute must be :rule',
-        'after'       => ':attribute cannot be less than :rule',
-        'before'      => ':attribute cannot exceed :rule',
-        'expire'      => ':attribute not within :rule',
-        'allowIp'     => 'access IP is not allowed',
-        'denyIp'      => 'access IP denied',
-        'confirm'     => ':attribute out of accord with :2',
-        'different'   => ':attribute cannot be same with :2',
-        'egt'         => ':attribute must greater than or equal :rule',
-        'gt'          => ':attribute must greater than :rule',
-        'elt'         => ':attribute must less than or equal :rule',
-        'lt'          => ':attribute must less than :rule',
-        'eq'          => ':attribute must equal :rule',
-        'unique'      => ':attribute has exists',
-        'regex'       => ':attribute not conform to the rules',
-        'method'      => 'invalid Request method',
-        'token'       => 'invalid token',
-        'fileSize'    => 'filesize not match',
-        'fileExt'     => 'extensions to upload is not allowed',
-        'fileMime'    => 'mimetype to upload is not allowed',
-    ];
-
-    /**
-     * 当前验证场景
-     * @var array
-     */
-    protected $currentScene = null;
-
-    /**
-     * 内置正则验证规则
-     * @var array
-     */
-    protected $regex = [
-        'alpha'       => '/^[A-Za-z]+$/',
-        'alphaNum'    => '/^[A-Za-z0-9]+$/',
-        'alphaDash'   => '/^[A-Za-z0-9\-\_]+$/',
-        'chs'         => '/^[\x{4e00}-\x{9fa5}]+$/u',
-        'chsAlpha'    => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u',
-        'chsAlphaNum' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u',
-        'chsDash'     => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u',
-        'mobile'      => '/^1[3-9][0-9]\d{8}$/',
-        'idCard'      => '/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)/',
-        'zip'         => '/\d{6}/',
-    ];
-
-    /**
-     * Filter_var 规则
-     * @var array
-     */
-    protected $filter = [
-        'email'   => FILTER_VALIDATE_EMAIL,
-        'ip'      => [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6],
-        'integer' => FILTER_VALIDATE_INT,
-        'url'     => FILTER_VALIDATE_URL,
-        'macAddr' => FILTER_VALIDATE_MAC,
-        'float'   => FILTER_VALIDATE_FLOAT,
-    ];
-
-    /**
-     * 验证场景定义
-     * @var array
-     */
-    protected $scene = [];
-
-    /**
-     * 验证失败错误信息
-     * @var array
-     */
-    protected $error = [];
-
-    /**
-     * 是否批量验证
-     * @var bool
-     */
-    protected $batch = false;
-
-    /**
-     * 场景需要验证的规则
-     * @var array
-     */
-    protected $only = [];
-
-    /**
-     * 场景需要移除的验证规则
-     * @var array
-     */
-    protected $remove = [];
-
-    /**
-     * 场景需要追加的验证规则
-     * @var array
-     */
-    protected $append = [];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $rules 验证规则
-     * @param  array $message 验证提示信息
-     * @param  array $field 验证字段描述信息
-     */
-    public function __construct(array $rules = [], array $message = [], array $field = [])
-    {
-        $this->rule    = $rules + $this->rule;
-        $this->message = array_merge($this->message, $message);
-        $this->field   = array_merge($this->field, $field);
-    }
-
-    /**
-     * 创建一个验证器类
-     * @access public
-     * @param  array $rules 验证规则
-     * @param  array $message 验证提示信息
-     * @param  array $field 验证字段描述信息
-     * @return Validate
-     */
-    public static function make(array $rules = [], array $message = [], array $field = [])
-    {
-        return new self($rules, $message, $field);
-    }
-
-    /**
-     * 添加字段验证规则
-     * @access protected
-     * @param  string|array  $name  字段名称或者规则数组
-     * @param  mixed         $rule  验证规则或者字段描述信息
-     * @return $this
-     */
-    public function rule($name, $rule = '')
-    {
-        if (is_array($name)) {
-            $this->rule = $name + $this->rule;
-            if (is_array($rule)) {
-                $this->field = array_merge($this->field, $rule);
-            }
-        } else {
-            $this->rule[$name] = $rule;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 注册扩展验证(类型)规则
-     * @access public
-     * @param  string    $type  验证规则类型
-     * @param  mixed     $callback callback方法(或闭包)
-     * @return void
-     */
-    public static function extend($type, $callback = null)
-    {
-        if (is_array($type)) {
-            self::$type = array_merge(self::$type, $type);
-        } else {
-            self::$type[$type] = $callback;
-        }
-    }
-
-    /**
-     * 设置验证规则的默认提示信息
-     * @access public
-     * @param  string|array  $type  验证规则类型名称或者数组
-     * @param  string        $msg  验证提示信息
-     * @return void
-     */
-    public static function setTypeMsg($type, $msg = null)
-    {
-        if (is_array($type)) {
-            self::$typeMsg = array_merge(self::$typeMsg, $type);
-        } else {
-            self::$typeMsg[$type] = $msg;
-        }
-    }
-
-    /**
-     * 设置提示信息
-     * @access public
-     * @param  string|array  $name  字段名称
-     * @param  string        $message 提示信息
-     * @return Validate
-     */
-    public function message($name, $message = '')
-    {
-        if (is_array($name)) {
-            $this->message = array_merge($this->message, $name);
-        } else {
-            $this->message[$name] = $message;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置验证场景
-     * @access public
-     * @param  string  $name  场景名
-     * @return $this
-     */
-    public function scene($name)
-    {
-        // 设置当前场景
-        $this->currentScene = $name;
-
-        return $this;
-    }
-
-    /**
-     * 判断是否存在某个验证场景
-     * @access public
-     * @param  string $name 场景名
-     * @return bool
-     */
-    public function hasScene($name)
-    {
-        return isset($this->scene[$name]) || method_exists($this, 'scene' . $name);
-    }
-
-    /**
-     * 设置批量验证
-     * @access public
-     * @param  bool $batch  是否批量验证
-     * @return $this
-     */
-    public function batch($batch = true)
-    {
-        $this->batch = $batch;
-
-        return $this;
-    }
-
-    /**
-     * 指定需要验证的字段列表
-     * @access public
-     * @param  array $fields  字段名
-     * @return $this
-     */
-    public function only($fields)
-    {
-        $this->only = $fields;
-
-        return $this;
-    }
-
-    /**
-     * 移除某个字段的验证规则
-     * @access public
-     * @param  string|array  $field  字段名
-     * @param  mixed         $rule   验证规则 true 移除所有规则
-     * @return $this
-     */
-    public function remove($field, $rule = true)
-    {
-        if (is_array($field)) {
-            foreach ($field as $key => $rule) {
-                if (is_int($key)) {
-                    $this->remove($rule);
-                } else {
-                    $this->remove($key, $rule);
-                }
-            }
-        } else {
-            if (is_string($rule)) {
-                $rule = explode('|', $rule);
-            }
-
-            $this->remove[$field] = $rule;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 追加某个字段的验证规则
-     * @access public
-     * @param  string|array  $field  字段名
-     * @param  mixed         $rule   验证规则
-     * @return $this
-     */
-    public function append($field, $rule = null)
-    {
-        if (is_array($field)) {
-            foreach ($field as $key => $rule) {
-                $this->append($key, $rule);
-            }
-        } else {
-            if (is_string($rule)) {
-                $rule = explode('|', $rule);
-            }
-
-            $this->append[$field] = $rule;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 数据自动验证
-     * @access public
-     * @param  array     $data  数据
-     * @param  mixed     $rules  验证规则
-     * @param  string    $scene 验证场景
-     * @return bool
-     */
-    public function check($data, $rules = [], $scene = '')
-    {
-        $this->error = [];
-
-        if (empty($rules)) {
-            // 读取验证规则
-            $rules = $this->rule;
-        }
-
-        // 获取场景定义
-        $this->getScene($scene);
-
-        foreach ($this->append as $key => $rule) {
-            if (!isset($rules[$key])) {
-                $rules[$key] = $rule;
-            }
-        }
-
-        foreach ($rules as $key => $rule) {
-            // field => 'rule1|rule2...' field => ['rule1','rule2',...]
-            if (strpos($key, '|')) {
-                // 字段|描述 用于指定属性名称
-                list($key, $title) = explode('|', $key);
-            } else {
-                $title = isset($this->field[$key]) ? $this->field[$key] : $key;
-            }
-
-            // 场景检测
-            if (!empty($this->only) && !in_array($key, $this->only)) {
-                continue;
-            }
-
-            // 获取数据 支持二维数组
-            $value = $this->getDataValue($data, $key);
-
-            // 字段验证
-            if ($rule instanceof \Closure) {
-                $result = call_user_func_array($rule, [$value, $data]);
-            } elseif ($rule instanceof ValidateRule) {
-                //  验证因子
-                $result = $this->checkItem($key, $value, $rule->getRule(), $data, $rule->getTitle() ?: $title, $rule->getMsg());
-            } else {
-                $result = $this->checkItem($key, $value, $rule, $data, $title);
-            }
-
-            if (true !== $result) {
-                // 没有返回true 则表示验证失败
-                if (!empty($this->batch)) {
-                    // 批量验证
-                    if (is_array($result)) {
-                        $this->error = array_merge($this->error, $result);
-                    } else {
-                        $this->error[$key] = $result;
-                    }
-                } else {
-                    $this->error = $result;
-                    return false;
-                }
-            }
-        }
-
-        return !empty($this->error) ? false : true;
-    }
-
-    /**
-     * 根据验证规则验证数据
-     * @access public
-     * @param  mixed     $value 字段值
-     * @param  mixed     $rules 验证规则
-     * @return bool
-     */
-    public function checkRule($value, $rules)
-    {
-        if ($rules instanceof \Closure) {
-            return call_user_func_array($rules, [$value]);
-        } elseif ($rules instanceof ValidateRule) {
-            $rules = $rules->getRule();
-        } elseif (is_string($rules)) {
-            $rules = explode('|', $rules);
-        }
-
-        foreach ($rules as $key => $rule) {
-            if ($rule instanceof \Closure) {
-                $result = call_user_func_array($rule, [$value]);
-            } else {
-                // 判断验证类型
-                list($type, $rule) = $this->getValidateType($key, $rule);
-
-                $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
-
-                $result = call_user_func_array($callback, [$value, $rule]);
-            }
-
-            if (true !== $result) {
-                return $result;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * 验证单个字段规则
-     * @access protected
-     * @param  string    $field  字段名
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rules  验证规则
-     * @param  array     $data  数据
-     * @param  string    $title  字段描述
-     * @param  array     $msg  提示信息
-     * @return mixed
-     */
-    protected function checkItem($field, $value, $rules, $data, $title = '', $msg = [])
-    {
-        if (isset($this->remove[$field]) && true === $this->remove[$field] && empty($this->append[$field])) {
-            // 字段已经移除 无需验证
-            return true;
-        }
-
-        // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]
-        if (is_string($rules)) {
-            $rules = explode('|', $rules);
-        }
-
-        if (isset($this->append[$field])) {
-            // 追加额外的验证规则
-            $rules = array_merge($rules, $this->append[$field]);
-        }
-
-        $i = 0;
-        foreach ($rules as $key => $rule) {
-            if ($rule instanceof \Closure) {
-                $result = call_user_func_array($rule, [$value, $data]);
-                $info   = is_numeric($key) ? '' : $key;
-            } else {
-                // 判断验证类型
-                list($type, $rule, $info) = $this->getValidateType($key, $rule);
-
-                if (isset($this->append[$field]) && in_array($info, $this->append[$field])) {
-
-                } elseif (isset($this->remove[$field]) && in_array($info, $this->remove[$field])) {
-                    // 规则已经移除
-                    $i++;
-                    continue;
-                }
-
-                if ('must' == $info || 0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) {
-                    // 验证类型
-                    $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
-                    // 验证数据
-                    $result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]);
-                } else {
-                    $result = true;
-                }
-            }
-
-            if (false === $result) {
-                // 验证失败 返回错误信息
-                if (!empty($msg[$i])) {
-                    $message = $msg[$i];
-                    if (is_string($message) && strpos($message, '{%') === 0) {
-                        $message = Lang::get(substr($message, 2, -1));
-                    }
-                } else {
-                    $message = $this->getRuleMsg($field, $title, $info, $rule);
-                }
-
-                return $message;
-            } elseif (true !== $result) {
-                // 返回自定义错误信息
-                if (is_string($result) && false !== strpos($result, ':')) {
-                    $result = str_replace(
-                        [':attribute', ':rule'],
-                        [$title, (string) $rule],
-                        $result);
-                }
-
-                return $result;
-            }
-            $i++;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 获取当前验证类型及规则
-     * @access public
-     * @param  mixed     $key
-     * @param  mixed     $rule
-     * @return array
-     */
-    protected function getValidateType($key, $rule)
-    {
-        // 判断验证类型
-        if (!is_numeric($key)) {
-            return [$key, $rule, $key];
-        }
-
-        if (strpos($rule, ':')) {
-            list($type, $rule) = explode(':', $rule, 2);
-            if (isset($this->alias[$type])) {
-                // 判断别名
-                $type = $this->alias[$type];
-            }
-            $info = $type;
-        } elseif (method_exists($this, $rule)) {
-            $type = $rule;
-            $info = $rule;
-            $rule = '';
-        } else {
-            $type = 'is';
-            $info = $rule;
-        }
-
-        return [$type, $rule, $info];
-    }
-
-    /**
-     * 验证是否和某个字段的值一致
-     * @access public
-     * @param  mixed     $value 字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @param  string    $field 字段名
-     * @return bool
-     */
-    public function confirm($value, $rule, $data = [], $field = '')
-    {
-        if ('' == $rule) {
-            if (strpos($field, '_confirm')) {
-                $rule = strstr($field, '_confirm', true);
-            } else {
-                $rule = $field . '_confirm';
-            }
-        }
-
-        return $this->getDataValue($data, $rule) === $value;
-    }
-
-    /**
-     * 验证是否和某个字段的值是否不同
-     * @access public
-     * @param  mixed $value 字段值
-     * @param  mixed $rule  验证规则
-     * @param  array $data  数据
-     * @return bool
-     */
-    public function different($value, $rule, $data = [])
-    {
-        return $this->getDataValue($data, $rule) != $value;
-    }
-
-    /**
-     * 验证是否大于等于某个值
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function egt($value, $rule, $data = [])
-    {
-        return $value >= $this->getDataValue($data, $rule);
-    }
-
-    /**
-     * 验证是否大于某个值
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function gt($value, $rule, $data)
-    {
-        return $value > $this->getDataValue($data, $rule);
-    }
-
-    /**
-     * 验证是否小于等于某个值
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function elt($value, $rule, $data = [])
-    {
-        return $value <= $this->getDataValue($data, $rule);
-    }
-
-    /**
-     * 验证是否小于某个值
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function lt($value, $rule, $data = [])
-    {
-        return $value < $this->getDataValue($data, $rule);
-    }
-
-    /**
-     * 验证是否等于某个值
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function eq($value, $rule)
-    {
-        return $value == $rule;
-    }
-
-    /**
-     * 必须验证
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function must($value, $rule = null)
-    {
-        return !empty($value) || '0' == $value;
-    }
-
-    /**
-     * 验证字段值是否为有效格式
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  string    $rule  验证规则
-     * @param  array     $data  验证数据
-     * @return bool
-     */
-    public function is($value, $rule, $data = [])
-    {
-        switch (Loader::parseName($rule, 1, false)) {
-            case 'require':
-                // 必须
-                $result = !empty($value) || '0' == $value;
-                break;
-            case 'accepted':
-                // 接受
-                $result = in_array($value, ['1', 'on', 'yes']);
-                break;
-            case 'date':
-                // 是否是一个有效日期
-                $result = false !== strtotime($value);
-                break;
-            case 'activeUrl':
-                // 是否为有效的网址
-                $result = checkdnsrr($value);
-                break;
-            case 'boolean':
-            case 'bool':
-                // 是否为布尔值
-                $result = in_array($value, [true, false, 0, 1, '0', '1'], true);
-                break;
-            case 'number':
-                $result = ctype_digit((string) $value);
-                break;
-            case 'array':
-                // 是否为数组
-                $result = is_array($value);
-                break;
-            case 'file':
-                $result = $value instanceof File;
-                break;
-            case 'image':
-                $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);
-                break;
-            case 'token':
-                $result = $this->token($value, '__token__', $data);
-                break;
-            default:
-                if (isset(self::$type[$rule])) {
-                    // 注册的验证规则
-                    $result = call_user_func_array(self::$type[$rule], [$value]);
-                } elseif (isset($this->filter[$rule])) {
-                    // Filter_var验证规则
-                    $result = $this->filter($value, $this->filter[$rule]);
-                } else {
-                    // 正则验证
-                    $result = $this->regex($value, $rule);
-                }
-        }
-
-        return $result;
-    }
-
-    // 判断图像类型
-    protected function getImageType($image)
-    {
-        if (function_exists('exif_imagetype')) {
-            return exif_imagetype($image);
-        }
-
-        try {
-            $info = getimagesize($image);
-            return $info ? $info[2] : false;
-        } catch (\Exception $e) {
-            return false;
-        }
-    }
-
-    /**
-     * 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function activeUrl($value, $rule = 'MX')
-    {
-        if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) {
-            $rule = 'MX';
-        }
-
-        return checkdnsrr($value, $rule);
-    }
-
-    /**
-     * 验证是否有效IP
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则 ipv4 ipv6
-     * @return bool
-     */
-    public function ip($value, $rule = 'ipv4')
-    {
-        if (!in_array($rule, ['ipv4', 'ipv6'])) {
-            $rule = 'ipv4';
-        }
-
-        return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]);
-    }
-
-    /**
-     * 验证上传文件后缀
-     * @access public
-     * @param  mixed     $file  上传文件
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function fileExt($file, $rule)
-    {
-        if (is_array($file)) {
-            foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkExt($rule)) {
-                    return false;
-                }
-            }
-            return true;
-        } elseif ($file instanceof File) {
-            return $file->checkExt($rule);
-        }
-
-        return false;
-    }
-
-    /**
-     * 验证上传文件类型
-     * @access public
-     * @param  mixed     $file  上传文件
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function fileMime($file, $rule)
-    {
-        if (is_array($file)) {
-            foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkMime($rule)) {
-                    return false;
-                }
-            }
-            return true;
-        } elseif ($file instanceof File) {
-            return $file->checkMime($rule);
-        }
-
-        return false;
-    }
-
-    /**
-     * 验证上传文件大小
-     * @access public
-     * @param  mixed     $file  上传文件
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function fileSize($file, $rule)
-    {
-        if (is_array($file)) {
-            foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkSize($rule)) {
-                    return false;
-                }
-            }
-            return true;
-        } elseif ($file instanceof File) {
-            return $file->checkSize($rule);
-        }
-
-        return false;
-    }
-
-    /**
-     * 验证图片的宽高及类型
-     * @access public
-     * @param  mixed     $file  上传文件
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function image($file, $rule)
-    {
-        if (!($file instanceof File)) {
-            return false;
-        }
-
-        if ($rule) {
-            $rule = explode(',', $rule);
-
-            list($width, $height, $type) = getimagesize($file->getRealPath());
-
-            if (isset($rule[2])) {
-                $imageType = strtolower($rule[2]);
-
-                if ('jpeg' == $imageType) {
-                    $imageType = 'jpg';
-                }
-
-                if (image_type_to_extension($type, false) != $imageType) {
-                    return false;
-                }
-            }
-
-            list($w, $h) = $rule;
-
-            return $w == $width && $h == $height;
-        }
-
-        return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]);
-    }
-
-    /**
-     * 验证请求类型
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function method($value, $rule)
-    {
-        $method = Container::get('request')->method();
-        return strtoupper($rule) == $method;
-    }
-
-    /**
-     * 验证时间和日期是否符合指定格式
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function dateFormat($value, $rule)
-    {
-        $info = date_parse_from_format($rule, $value);
-        return 0 == $info['warning_count'] && 0 == $info['error_count'];
-    }
-
-    /**
-     * 验证是否唯一
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则 格式:数据表,字段名,排除ID,主键名
-     * @param  array     $data  数据
-     * @param  string    $field  验证字段名
-     * @return bool
-     */
-    public function unique($value, $rule, $data, $field)
-    {
-        if (is_string($rule)) {
-            $rule = explode(',', $rule);
-        }
-
-        if (false !== strpos($rule[0], '\\')) {
-            // 指定模型类
-            $db = new $rule[0];
-        } else {
-            try {
-                $db = Container::get('app')->model($rule[0]);
-            } catch (ClassNotFoundException $e) {
-                $db = Db::name($rule[0]);
-            }
-        }
-
-        $key = isset($rule[1]) ? $rule[1] : $field;
-
-        if (strpos($key, '^')) {
-            // 支持多个字段验证
-            $fields = explode('^', $key);
-            foreach ($fields as $key) {
-                $map[] = [$key, '=', $data[$key]];
-            }
-        } else {
-            $map[] = [$key, '=', $data[$field]];
-        }
-
-        $pk = !empty($rule[3]) ? $rule[3] : $db->getPk();
-
-        if (is_string($pk)) {
-            if (isset($rule[2])) {
-                $map[] = [$pk, '<>', $rule[2]];
-            } elseif (isset($data[$pk])) {
-                $map[] = [$pk, '<>', $data[$pk]];
-            }
-        }
-
-        if ($db->where($map)->field($pk)->find()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 使用行为类验证
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return mixed
-     */
-    public function behavior($value, $rule, $data)
-    {
-        return Container::get('hook')->exec($rule, $data);
-    }
-
-    /**
-     * 使用filter_var方式验证
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function filter($value, $rule)
-    {
-        if (is_string($rule) && strpos($rule, ',')) {
-            list($rule, $param) = explode(',', $rule);
-        } elseif (is_array($rule)) {
-            $param = isset($rule[1]) ? $rule[1] : null;
-            $rule  = $rule[0];
-        } else {
-            $param = null;
-        }
-
-        return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);
-    }
-
-    /**
-     * 验证某个字段等于某个值的时候必须
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function requireIf($value, $rule, $data)
-    {
-        list($field, $val) = explode(',', $rule);
-
-        if ($this->getDataValue($data, $field) == $val) {
-            return !empty($value) || '0' == $value;
-        }
-
-        return true;
-    }
-
-    /**
-     * 通过回调方法验证某个字段是否必须
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function requireCallback($value, $rule, $data)
-    {
-        $result = call_user_func_array($rule, [$value, $data]);
-
-        if ($result) {
-            return !empty($value) || '0' == $value;
-        }
-
-        return true;
-    }
-
-    /**
-     * 验证某个字段有值的情况下必须
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function requireWith($value, $rule, $data)
-    {
-        $val = $this->getDataValue($data, $rule);
-
-        if (!empty($val)) {
-            return !empty($value) || '0' == $value;
-        }
-
-        return true;
-    }
-
-    /**
-     * 验证是否在范围内
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function in($value, $rule)
-    {
-        return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
-    }
-
-    /**
-     * 验证是否不在某个范围
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function notIn($value, $rule)
-    {
-        return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
-    }
-
-    /**
-     * between验证数据
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function between($value, $rule)
-    {
-        if (is_string($rule)) {
-            $rule = explode(',', $rule);
-        }
-        list($min, $max) = $rule;
-
-        return $value >= $min && $value <= $max;
-    }
-
-    /**
-     * 使用notbetween验证数据
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function notBetween($value, $rule)
-    {
-        if (is_string($rule)) {
-            $rule = explode(',', $rule);
-        }
-        list($min, $max) = $rule;
-
-        return $value < $min || $value > $max;
-    }
-
-    /**
-     * 验证数据长度
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function length($value, $rule)
-    {
-        if (is_array($value)) {
-            $length = count($value);
-        } elseif ($value instanceof File) {
-            $length = $value->getSize();
-        } else {
-            $length = mb_strlen((string) $value);
-        }
-
-        if (strpos($rule, ',')) {
-            // 长度区间
-            list($min, $max) = explode(',', $rule);
-            return $length >= $min && $length <= $max;
-        }
-
-        // 指定长度
-        return $length == $rule;
-    }
-
-    /**
-     * 验证数据最大长度
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function max($value, $rule)
-    {
-        if (is_array($value)) {
-            $length = count($value);
-        } elseif ($value instanceof File) {
-            $length = $value->getSize();
-        } else {
-            $length = mb_strlen((string) $value);
-        }
-
-        return $length <= $rule;
-    }
-
-    /**
-     * 验证数据最小长度
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function min($value, $rule)
-    {
-        if (is_array($value)) {
-            $length = count($value);
-        } elseif ($value instanceof File) {
-            $length = $value->getSize();
-        } else {
-            $length = mb_strlen((string) $value);
-        }
-
-        return $length >= $rule;
-    }
-
-    /**
-     * 验证日期
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function after($value, $rule)
-    {
-        return strtotime($value) >= strtotime($rule);
-    }
-
-    /**
-     * 验证日期
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function before($value, $rule)
-    {
-        return strtotime($value) <= strtotime($rule);
-    }
-
-    /**
-     * 验证有效期
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return bool
-     */
-    public function expire($value, $rule)
-    {
-        if (is_string($rule)) {
-            $rule = explode(',', $rule);
-        }
-
-        list($start, $end) = $rule;
-
-        if (!is_numeric($start)) {
-            $start = strtotime($start);
-        }
-
-        if (!is_numeric($end)) {
-            $end = strtotime($end);
-        }
-
-        return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end;
-    }
-
-    /**
-     * 验证IP许可
-     * @access public
-     * @param  string    $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return mixed
-     */
-    public function allowIp($value, $rule)
-    {
-        return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
-    }
-
-    /**
-     * 验证IP禁用
-     * @access public
-     * @param  string    $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @return mixed
-     */
-    public function denyIp($value, $rule)
-    {
-        return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
-    }
-
-    /**
-     * 使用正则验证数据
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则 正则规则或者预定义正则名
-     * @return bool
-     */
-    public function regex($value, $rule)
-    {
-        if (isset($this->regex[$rule])) {
-            $rule = $this->regex[$rule];
-        }
-
-        if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) {
-            // 不是正则表达式则两端补上/
-            $rule = '/^' . $rule . '$/';
-        }
-
-        return is_scalar($value) && 1 === preg_match($rule, (string) $value);
-    }
-
-    /**
-     * 验证表单令牌
-     * @access public
-     * @param  mixed     $value  字段值
-     * @param  mixed     $rule  验证规则
-     * @param  array     $data  数据
-     * @return bool
-     */
-    public function token($value, $rule, $data)
-    {
-        $rule    = !empty($rule) ? $rule : '__token__';
-        $session = Container::get('session');
-
-        if (!isset($data[$rule]) || !$session->has($rule)) {
-            // 令牌数据无效
-            return false;
-        }
-
-        // 令牌验证
-        if (isset($data[$rule]) && $session->get($rule) === $data[$rule]) {
-            // 防止重复提交
-            $session->delete($rule); // 验证完成销毁session
-            return true;
-        }
-
-        // 开启TOKEN重置
-        $session->delete($rule);
-
-        return false;
-    }
-
-    // 获取错误信息
-    public function getError()
-    {
-        return $this->error;
-    }
-
-    /**
-     * 获取数据值
-     * @access protected
-     * @param  array     $data  数据
-     * @param  string    $key  数据标识 支持二维
-     * @return mixed
-     */
-    protected function getDataValue($data, $key)
-    {
-        if (is_numeric($key)) {
-            $value = $key;
-        } elseif (strpos($key, '.')) {
-            // 支持二维数组验证
-            list($name1, $name2) = explode('.', $key);
-            $value               = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null;
-        } else {
-            $value = isset($data[$key]) ? $data[$key] : null;
-        }
-
-        return $value;
-    }
-
-    /**
-     * 获取验证规则的错误提示信息
-     * @access protected
-     * @param  string    $attribute  字段英文名
-     * @param  string    $title  字段描述名
-     * @param  string    $type  验证规则名称
-     * @param  mixed     $rule  验证规则数据
-     * @return string
-     */
-    protected function getRuleMsg($attribute, $title, $type, $rule)
-    {
-        $lang = Container::get('lang');
-
-        if (isset($this->message[$attribute . '.' . $type])) {
-            $msg = $this->message[$attribute . '.' . $type];
-        } elseif (isset($this->message[$attribute][$type])) {
-            $msg = $this->message[$attribute][$type];
-        } elseif (isset($this->message[$attribute])) {
-            $msg = $this->message[$attribute];
-        } elseif (isset(self::$typeMsg[$type])) {
-            $msg = self::$typeMsg[$type];
-        } elseif (0 === strpos($type, 'require')) {
-            $msg = self::$typeMsg['require'];
-        } else {
-            $msg = $title . $lang->get('not conform to the rules');
-        }
-
-        if (is_string($msg) && 0 === strpos($msg, '{%')) {
-            $msg = $lang->get(substr($msg, 2, -1));
-        } elseif ($lang->has($msg)) {
-            $msg = $lang->get($msg);
-        }
-
-        if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) {
-            // 变量替换
-            if (is_string($rule) && strpos($rule, ',')) {
-                $array = array_pad(explode(',', $rule), 3, '');
-            } else {
-                $array = array_pad([], 3, '');
-            }
-            $msg = str_replace(
-                [':attribute', ':rule', ':1', ':2', ':3'],
-                [$title, (string) $rule, $array[0], $array[1], $array[2]],
-                $msg);
-        }
-
-        return $msg;
-    }
-
-    /**
-     * 获取数据验证的场景
-     * @access protected
-     * @param  string $scene  验证场景
-     * @return void
-     */
-    protected function getScene($scene = '')
-    {
-        if (empty($scene)) {
-            // 读取指定场景
-            $scene = $this->currentScene;
-        }
-
-        $this->only = $this->append = $this->remove = [];
-
-        if (empty($scene)) {
-            return;
-        }
-
-        if (method_exists($this, 'scene' . $scene)) {
-            call_user_func([$this, 'scene' . $scene]);
-        } elseif (isset($this->scene[$scene])) {
-            // 如果设置了验证适用场景
-            $scene = $this->scene[$scene];
-
-            if (is_string($scene)) {
-                $scene = explode(',', $scene);
-            }
-
-            $this->only = $scene;
-        }
-    }
-
-    /**
-     * 动态方法 直接调用is方法进行验证
-     * @access public
-     * @param  string $method  方法名
-     * @param  array $args  调用参数
-     * @return bool
-     */
-    public function __call($method, $args)
-    {
-        if ('is' == strtolower(substr($method, 0, 2))) {
-            $method = substr($method, 2);
-        }
-
-        array_push($args, lcfirst($method));
-
-        return call_user_func_array([$this, 'is'], $args);
-    }
-}

+ 0 - 236
thinkphp/library/think/View.php

@@ -1,236 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think;
-
-class View
-{
-    /**
-     * 模板引擎实例
-     * @var object
-     */
-    public $engine;
-
-    /**
-     * 模板变量
-     * @var array
-     */
-    protected $data = [];
-
-    /**
-     * 内容过滤
-     * @var mixed
-     */
-    protected $filter;
-
-    /**
-     * 全局模板变量
-     * @var array
-     */
-    protected static $var = [];
-
-    /**
-     * 初始化
-     * @access public
-     * @param  mixed $engine  模板引擎参数
-     * @return $this
-     */
-    public function init($engine = [])
-    {
-        // 初始化模板引擎
-        $this->engine($engine);
-
-        return $this;
-    }
-
-    /**
-     * 模板变量静态赋值
-     * @access public
-     * @param  mixed $name  变量名
-     * @param  mixed $value 变量值
-     * @return $this
-     */
-    public function share($name, $value = '')
-    {
-        if (is_array($name)) {
-            self::$var = array_merge(self::$var, $name);
-        } else {
-            self::$var[$name] = $value;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 模板变量赋值
-     * @access public
-     * @param  mixed $name  变量名
-     * @param  mixed $value 变量值
-     * @return $this
-     */
-    public function assign($name, $value = '')
-    {
-        if (is_array($name)) {
-            $this->data = array_merge($this->data, $name);
-        } else {
-            $this->data[$name] = $value;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置当前模板解析的引擎
-     * @access public
-     * @param  array|string $options 引擎参数
-     * @return $this
-     */
-    public function engine($options = [])
-    {
-        if (is_string($options)) {
-            $type    = $options;
-            $options = [];
-        } else {
-            $type = !empty($options['type']) ? $options['type'] : 'Think';
-        }
-
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\view\\driver\\' . ucfirst($type);
-
-        if (isset($options['type'])) {
-            unset($options['type']);
-        }
-
-        $this->engine = new $class($options);
-
-        return $this;
-    }
-
-    /**
-     * 配置模板引擎
-     * @access public
-     * @param  string|array  $name 参数名
-     * @param  mixed         $value 参数值
-     * @return $this
-     */
-    public function config($name, $value = null)
-    {
-        $this->engine->config($name, $value);
-
-        return $this;
-    }
-
-    /**
-     * 检查模板是否存在
-     * @access public
-     * @param  string|array  $name 参数名
-     * @return bool
-     */
-    public function exists($name)
-    {
-        return $this->engine->exists($name);
-    }
-
-    /**
-     * 视图过滤
-     * @access public
-     * @param Callable  $filter 过滤方法或闭包
-     * @return $this
-     */
-    public function filter($filter)
-    {
-        $this->filter = $filter;
-        return $this;
-    }
-
-    /**
-     * 解析和获取模板内容 用于输出
-     * @access public
-     * @param  string    $template 模板文件名或者内容
-     * @param  array     $vars     模板输出变量
-     * @param  array     $config     模板参数
-     * @param  bool      $renderContent     是否渲染内容
-     * @return string
-     * @throws \Exception
-     */
-    public function fetch($template = '', $vars = [], $config = [], $renderContent = false)
-    {
-        // 模板变量
-        $vars = array_merge(self::$var, $this->data, $vars);
-
-        // 页面缓存
-        ob_start();
-        ob_implicit_flush(0);
-
-        // 渲染输出
-        try {
-            $method = $renderContent ? 'display' : 'fetch';
-            $this->engine->$method($template, $vars, $config);
-        } catch (\Exception $e) {
-            ob_end_clean();
-            throw $e;
-        }
-
-        // 获取并清空缓存
-        $content = ob_get_clean();
-
-        if ($this->filter) {
-            $content = call_user_func_array($this->filter, [$content]);
-        }
-
-        return $content;
-    }
-
-    /**
-     * 渲染内容输出
-     * @access public
-     * @param  string $content 内容
-     * @param  array  $vars    模板输出变量
-     * @param  array  $config  模板参数
-     * @return mixed
-     */
-    public function display($content, $vars = [], $config = [])
-    {
-        return $this->fetch($content, $vars, $config, true);
-    }
-
-    /**
-     * 模板变量赋值
-     * @access public
-     * @param  string    $name  变量名
-     * @param  mixed     $value 变量值
-     */
-    public function __set($name, $value)
-    {
-        $this->data[$name] = $value;
-    }
-
-    /**
-     * 取得模板显示变量的值
-     * @access protected
-     * @param  string $name 模板变量
-     * @return mixed
-     */
-    public function __get($name)
-    {
-        return $this->data[$name];
-    }
-
-    /**
-     * 检测模板变量是否设置
-     * @access public
-     * @param  string $name 模板变量名
-     * @return bool
-     */
-    public function __isset($name)
-    {
-        return isset($this->data[$name]);
-    }
-}

+ 0 - 353
thinkphp/library/think/cache/Driver.php

@@ -1,353 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache;
-
-use think\Container;
-
-/**
- * 缓存基础类
- */
-abstract class Driver
-{
-    /**
-     * 驱动句柄
-     * @var object
-     */
-    protected $handler = null;
-
-    /**
-     * 缓存读取次数
-     * @var integer
-     */
-    protected $readTimes = 0;
-
-    /**
-     * 缓存写入次数
-     * @var integer
-     */
-    protected $writeTimes = 0;
-
-    /**
-     * 缓存参数
-     * @var array
-     */
-    protected $options = [];
-
-    /**
-     * 缓存标签
-     * @var string
-     */
-    protected $tag;
-
-    /**
-     * 序列化方法
-     * @var array
-     */
-    protected static $serialize = ['serialize', 'unserialize', 'think_serialize:', 16];
-
-    /**
-     * 判断缓存是否存在
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    abstract public function has($name);
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    abstract public function get($name, $default = false);
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  mixed     $value  存储数据
-     * @param  int       $expire  有效时间 0为永久
-     * @return boolean
-     */
-    abstract public function set($name, $value, $expire = null);
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    abstract public function inc($name, $step = 1);
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    abstract public function dec($name, $step = 1);
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    abstract public function rm($name);
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    abstract public function clear($tag = null);
-
-    /**
-     * 获取有效期
-     * @access protected
-     * @param  integer|\DateTime $expire 有效期
-     * @return integer
-     */
-    protected function getExpireTime($expire)
-    {
-        if ($expire instanceof \DateTime) {
-            $expire = $expire->getTimestamp() - time();
-        }
-
-        return $expire;
-    }
-
-    /**
-     * 获取实际的缓存标识
-     * @access protected
-     * @param  string $name 缓存名
-     * @return string
-     */
-    protected function getCacheKey($name)
-    {
-        return $this->options['prefix'] . $name;
-    }
-
-    /**
-     * 读取缓存并删除
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return mixed
-     */
-    public function pull($name)
-    {
-        $result = $this->get($name, false);
-
-        if ($result) {
-            $this->rm($name);
-            return $result;
-        } else {
-            return;
-        }
-    }
-
-    /**
-     * 如果不存在则写入缓存
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  mixed     $value  存储数据
-     * @param  int       $expire  有效时间 0为永久
-     * @return mixed
-     */
-    public function remember($name, $value, $expire = null)
-    {
-        if (!$this->has($name)) {
-            $time = time();
-            while ($time + 5 > time() && $this->has($name . '_lock')) {
-                // 存在锁定则等待
-                usleep(200000);
-            }
-
-            try {
-                // 锁定
-                $this->set($name . '_lock', true);
-
-                if ($value instanceof \Closure) {
-                    // 获取缓存数据
-                    $value = Container::getInstance()->invokeFunction($value);
-                }
-
-                // 缓存数据
-                $this->set($name, $value, $expire);
-
-                // 解锁
-                $this->rm($name . '_lock');
-            } catch (\Exception $e) {
-                $this->rm($name . '_lock');
-                throw $e;
-            } catch (\throwable $e) {
-                $this->rm($name . '_lock');
-                throw $e;
-            }
-        } else {
-            $value = $this->get($name);
-        }
-
-        return $value;
-    }
-
-    /**
-     * 缓存标签
-     * @access public
-     * @param  string        $name 标签名
-     * @param  string|array  $keys 缓存标识
-     * @param  bool          $overlay 是否覆盖
-     * @return $this
-     */
-    public function tag($name, $keys = null, $overlay = false)
-    {
-        if (is_null($name)) {
-
-        } elseif (is_null($keys)) {
-            $this->tag = $name;
-        } else {
-            $key = 'tag_' . md5($name);
-
-            if (is_string($keys)) {
-                $keys = explode(',', $keys);
-            }
-
-            $keys = array_map([$this, 'getCacheKey'], $keys);
-
-            if ($overlay) {
-                $value = $keys;
-            } else {
-                $value = array_unique(array_merge($this->getTagItem($name), $keys));
-            }
-
-            $this->set($key, implode(',', $value), 0);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 更新标签
-     * @access protected
-     * @param  string $name 缓存标识
-     * @return void
-     */
-    protected function setTagItem($name)
-    {
-        if ($this->tag) {
-            $key       = 'tag_' . md5($this->tag);
-            $prev      = $this->tag;
-            $this->tag = null;
-
-            if ($this->has($key)) {
-                $value   = explode(',', $this->get($key));
-                $value[] = $name;
-                $value   = implode(',', array_unique($value));
-            } else {
-                $value = $name;
-            }
-
-            $this->set($key, $value, 0);
-            $this->tag = $prev;
-        }
-    }
-
-    /**
-     * 获取标签包含的缓存标识
-     * @access protected
-     * @param  string $tag 缓存标签
-     * @return array
-     */
-    protected function getTagItem($tag)
-    {
-        $key   = 'tag_' . md5($tag);
-        $value = $this->get($key);
-
-        if ($value) {
-            return array_filter(explode(',', $value));
-        } else {
-            return [];
-        }
-    }
-
-    /**
-     * 序列化数据
-     * @access protected
-     * @param  mixed $data
-     * @return string
-     */
-    protected function serialize($data)
-    {
-        if (is_scalar($data) || !$this->options['serialize']) {
-            return $data;
-        }
-
-        $serialize = self::$serialize[0];
-
-        return self::$serialize[2] . $serialize($data);
-    }
-
-    /**
-     * 反序列化数据
-     * @access protected
-     * @param  string $data
-     * @return mixed
-     */
-    protected function unserialize($data)
-    {
-        if ($this->options['serialize'] && 0 === strpos($data, self::$serialize[2])) {
-            $unserialize = self::$serialize[1];
-
-            return $unserialize(substr($data, self::$serialize[3]));
-        } else {
-            return $data;
-        }
-    }
-
-    /**
-     * 注册序列化机制
-     * @access public
-     * @param  callable $serialize      序列化方法
-     * @param  callable $unserialize    反序列化方法
-     * @param  string   $prefix         序列化前缀标识
-     * @return $this
-     */
-    public static function registerSerialize($serialize, $unserialize, $prefix = 'think_serialize:')
-    {
-        self::$serialize = [$serialize, $unserialize, $prefix, strlen($prefix)];
-    }
-
-    /**
-     * 返回句柄对象,可执行其它高级方法
-     *
-     * @access public
-     * @return object
-     */
-    public function handler()
-    {
-        return $this->handler;
-    }
-
-    public function getReadTimes()
-    {
-        return $this->readTimes;
-    }
-
-    public function getWriteTimes()
-    {
-        return $this->writeTimes;
-    }
-}

+ 0 - 305
thinkphp/library/think/cache/driver/File.php

@@ -1,305 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-use think\Container;
-
-/**
- * 文件类型缓存类
- * @author    liu21st <liu21st@gmail.com>
- */
-class File extends Driver
-{
-    protected $options = [
-        'expire'        => 0,
-        'cache_subdir'  => true,
-        'prefix'        => '',
-        'path'          => '',
-        'hash_type'     => 'md5',
-        'data_compress' => false,
-        'serialize'     => true,
-    ];
-
-    protected $expire;
-
-    /**
-     * 架构函数
-     * @param array $options
-     */
-    public function __construct($options = [])
-    {
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        if (empty($this->options['path'])) {
-            $this->options['path'] = Container::get('app')->getRuntimePath() . 'cache' . DIRECTORY_SEPARATOR;
-        } elseif (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) {
-            $this->options['path'] .= DIRECTORY_SEPARATOR;
-        }
-
-        $this->init();
-    }
-
-    /**
-     * 初始化检查
-     * @access private
-     * @return boolean
-     */
-    private function init()
-    {
-        // 创建项目缓存目录
-        try {
-            if (!is_dir($this->options['path']) && mkdir($this->options['path'], 0755, true)) {
-                return true;
-            }
-        } catch (\Exception $e) {
-        }
-
-        return false;
-    }
-
-    /**
-     * 取得变量的存储文件名
-     * @access protected
-     * @param  string $name 缓存变量名
-     * @param  bool   $auto 是否自动创建目录
-     * @return string
-     */
-    protected function getCacheKey($name, $auto = false)
-    {
-        $name = hash($this->options['hash_type'], $name);
-
-        if ($this->options['cache_subdir']) {
-            // 使用子目录
-            $name = substr($name, 0, 2) . DIRECTORY_SEPARATOR . substr($name, 2);
-        }
-
-        if ($this->options['prefix']) {
-            $name = $this->options['prefix'] . DIRECTORY_SEPARATOR . $name;
-        }
-
-        $filename = $this->options['path'] . $name . '.php';
-        $dir      = dirname($filename);
-
-        if ($auto && !is_dir($dir)) {
-            try {
-                mkdir($dir, 0755, true);
-            } catch (\Exception $e) {
-            }
-        }
-
-        return $filename;
-    }
-
-    /**
-     * 判断缓存是否存在
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        return $this->get($name) ? true : false;
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $filename = $this->getCacheKey($name);
-
-        if (!is_file($filename)) {
-            return $default;
-        }
-
-        $content      = file_get_contents($filename);
-        $this->expire = null;
-
-        if (false !== $content) {
-            $expire = (int) substr($content, 8, 12);
-            if (0 != $expire && time() > filemtime($filename) + $expire) {
-                //缓存过期删除缓存文件
-                $this->unlink($filename);
-                return $default;
-            }
-
-            $this->expire = $expire;
-            $content      = substr($content, 32);
-
-            if ($this->options['data_compress'] && function_exists('gzcompress')) {
-                //启用数据压缩
-                $content = gzuncompress($content);
-            }
-            return $this->unserialize($content);
-        } else {
-            return $default;
-        }
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string        $name 缓存变量名
-     * @param  mixed         $value  存储数据
-     * @param  int|\DateTime $expire  有效时间 0为永久
-     * @return boolean
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        $expire   = $this->getExpireTime($expire);
-        $filename = $this->getCacheKey($name, true);
-
-        if ($this->tag && !is_file($filename)) {
-            $first = true;
-        }
-
-        $data = $this->serialize($value);
-
-        if ($this->options['data_compress'] && function_exists('gzcompress')) {
-            //数据压缩
-            $data = gzcompress($data, 3);
-        }
-
-        $data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
-        $result = file_put_contents($filename, $data);
-
-        if ($result) {
-            isset($first) && $this->setTagItem($filename);
-            clearstatcache();
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value  = $this->get($name) + $step;
-            $expire = $this->expire;
-        } else {
-            $value  = $step;
-            $expire = 0;
-        }
-
-        return $this->set($name, $value, $expire) ? $value : false;
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value  = $this->get($name) - $step;
-            $expire = $this->expire;
-        } else {
-            $value  = -$step;
-            $expire = 0;
-        }
-
-        return $this->set($name, $value, $expire) ? $value : false;
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        try {
-            return $this->unlink($this->getCacheKey($name));
-        } catch (\Exception $e) {
-        }
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-            foreach ($keys as $key) {
-                $this->unlink($key);
-            }
-            $this->rm('tag_' . md5($tag));
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DIRECTORY_SEPARATOR : '') . '*');
-
-        foreach ($files as $path) {
-            if (is_dir($path)) {
-                $matches = glob($path . DIRECTORY_SEPARATOR . '*.php');
-                if (is_array($matches)) {
-                    array_map('unlink', $matches);
-                }
-                rmdir($path);
-            } else {
-                unlink($path);
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * 判断文件是否存在后,删除
-     * @access private
-     * @param  string $path
-     * @return bool
-     * @author byron sampson <xiaobo.sun@qq.com>
-     * @return boolean
-     */
-    private function unlink($path)
-    {
-        return is_file($path) && unlink($path);
-    }
-
-}

+ 0 - 209
thinkphp/library/think/cache/driver/Lite.php

@@ -1,209 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-/**
- * 文件类型缓存类
- * @author    liu21st <liu21st@gmail.com>
- */
-class Lite extends Driver
-{
-    protected $options = [
-        'prefix' => '',
-        'path'   => '',
-        'expire' => 0, // 等于 10*365*24*3600(10年)
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     *
-     * @param  array $options
-     */
-    public function __construct($options = [])
-    {
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        if (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) {
-            $this->options['path'] .= DIRECTORY_SEPARATOR;
-        }
-
-    }
-
-    /**
-     * 取得变量的存储文件名
-     * @access protected
-     * @param  string $name 缓存变量名
-     * @return string
-     */
-    protected function getCacheKey($name)
-    {
-        return $this->options['path'] . $this->options['prefix'] . md5($name) . '.php';
-    }
-
-    /**
-     * 判断缓存是否存在
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return mixed
-     */
-    public function has($name)
-    {
-        return $this->get($name) ? true : false;
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $filename = $this->getCacheKey($name);
-
-        if (is_file($filename)) {
-            // 判断是否过期
-            $mtime = filemtime($filename);
-
-            if ($mtime < time()) {
-                // 清除已经过期的文件
-                unlink($filename);
-                return $default;
-            }
-
-            return include $filename;
-        } else {
-            return $default;
-        }
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string        $name  缓存变量名
-     * @param  mixed         $value 存储数据
-     * @param  int|\DateTime $expire 有效时间 0为永久
-     * @return bool
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($expire instanceof \DateTime) {
-            $expire = $expire->getTimestamp();
-        } else {
-            $expire = 0 === $expire ? 10 * 365 * 24 * 3600 : $expire;
-            $expire = time() + $expire;
-        }
-
-        $filename = $this->getCacheKey($name);
-
-        if ($this->tag && !is_file($filename)) {
-            $first = true;
-        }
-
-        $ret = file_put_contents($filename, ("<?php return " . var_export($value, true) . ";"));
-
-        // 通过设置修改时间实现有效期
-        if ($ret) {
-            isset($first) && $this->setTagItem($filename);
-            touch($filename, $expire);
-        }
-
-        return $ret;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value = $this->get($name) + $step;
-        } else {
-            $value = $step;
-        }
-
-        return $this->set($name, $value, 0) ? $value : false;
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value = $this->get($name) - $step;
-        } else {
-            $value = -$step;
-        }
-
-        return $this->set($name, $value, 0) ? $value : false;
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        return unlink($this->getCacheKey($name));
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return bool
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-            foreach ($keys as $key) {
-                unlink($key);
-            }
-
-            $this->rm('tag_' . md5($tag));
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        array_map("unlink", glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DIRECTORY_SEPARATOR : '') . '*.php'));
-    }
-}

+ 0 - 203
thinkphp/library/think/cache/driver/Memcache.php

@@ -1,203 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-class Memcache extends Driver
-{
-    protected $options = [
-        'host'       => '127.0.0.1',
-        'port'       => 11211,
-        'expire'     => 0,
-        'timeout'    => 0, // 超时时间(单位:毫秒)
-        'persistent' => true,
-        'prefix'     => '',
-        'serialize'  => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     * @throws \BadFunctionCallException
-     */
-    public function __construct($options = [])
-    {
-        if (!extension_loaded('memcache')) {
-            throw new \BadFunctionCallException('not support: memcache');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        $this->handler = new \Memcache;
-
-        // 支持集群
-        $hosts = explode(',', $this->options['host']);
-        $ports = explode(',', $this->options['port']);
-
-        if (empty($ports[0])) {
-            $ports[0] = 11211;
-        }
-
-        // 建立连接
-        foreach ((array) $hosts as $i => $host) {
-            $port = isset($ports[$i]) ? $ports[$i] : $ports[0];
-            $this->options['timeout'] > 0 ?
-            $this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) :
-            $this->handler->addServer($host, $port, $this->options['persistent'], 1);
-        }
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        $key = $this->getCacheKey($name);
-
-        return $this->handler->get($key) ? true : false;
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $result = $this->handler->get($this->getCacheKey($name));
-
-        return false !== $result ? $this->unserialize($result) : $default;
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string        $name 缓存变量名
-     * @param  mixed         $value  存储数据
-     * @param  int|DateTime  $expire  有效时间(秒)
-     * @return bool
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($this->tag && !$this->has($name)) {
-            $first = true;
-        }
-
-        $key    = $this->getCacheKey($name);
-        $expire = $this->getExpireTime($expire);
-        $value  = $this->serialize($value);
-
-        if ($this->handler->set($key, $value, 0, $expire)) {
-            isset($first) && $this->setTagItem($key);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        if ($this->handler->get($key)) {
-            return $this->handler->increment($key, $step);
-        }
-
-        return $this->handler->set($key, $step);
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key   = $this->getCacheKey($name);
-        $value = $this->handler->get($key) - $step;
-        $res   = $this->handler->set($key, $value);
-
-        return !$res ? false : $value;
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string       $name 缓存变量名
-     * @param  bool|false   $ttl
-     * @return bool
-     */
-    public function rm($name, $ttl = false)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return false === $ttl ?
-        $this->handler->delete($key) :
-        $this->handler->delete($key, $ttl);
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return bool
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-            foreach ($keys as $key) {
-                $this->handler->delete($key);
-            }
-
-            $this->rm('tag_' . md5($tag));
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        return $this->handler->flush();
-    }
-}

+ 0 - 216
thinkphp/library/think/cache/driver/Memcached.php

@@ -1,216 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-class Memcached extends Driver
-{
-    protected $options = [
-        'host'      => '127.0.0.1',
-        'port'      => 11211,
-        'expire'    => 0,
-        'timeout'   => 0, // 超时时间(单位:毫秒)
-        'prefix'    => '',
-        'username'  => '', //账号
-        'password'  => '', //密码
-        'option'    => [],
-        'serialize' => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     */
-    public function __construct($options = [])
-    {
-        if (!extension_loaded('memcached')) {
-            throw new \BadFunctionCallException('not support: memcached');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        $this->handler = new \Memcached;
-
-        if (!empty($this->options['option'])) {
-            $this->handler->setOptions($this->options['option']);
-        }
-
-        // 设置连接超时时间(单位:毫秒)
-        if ($this->options['timeout'] > 0) {
-            $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']);
-        }
-
-        // 支持集群
-        $hosts = explode(',', $this->options['host']);
-        $ports = explode(',', $this->options['port']);
-        if (empty($ports[0])) {
-            $ports[0] = 11211;
-        }
-
-        // 建立连接
-        $servers = [];
-        foreach ((array) $hosts as $i => $host) {
-            $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];
-        }
-
-        $this->handler->addServers($servers);
-
-        if ('' != $this->options['username']) {
-            $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
-            $this->handler->setSaslAuthData($this->options['username'], $this->options['password']);
-        }
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        $key = $this->getCacheKey($name);
-
-        return $this->handler->get($key) ? true : false;
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $result = $this->handler->get($this->getCacheKey($name));
-
-        return false !== $result ? $this->unserialize($result) : $default;
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string            $name 缓存变量名
-     * @param  mixed             $value  存储数据
-     * @param  integer|\DateTime $expire  有效时间(秒)
-     * @return bool
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($this->tag && !$this->has($name)) {
-            $first = true;
-        }
-
-        $key    = $this->getCacheKey($name);
-        $expire = $this->getExpireTime($expire);
-        $value  = $this->serialize($value);
-
-        if ($this->handler->set($key, $value, $expire)) {
-            isset($first) && $this->setTagItem($key);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        if ($this->handler->get($key)) {
-            return $this->handler->increment($key, $step);
-        }
-
-        return $this->handler->set($key, $step);
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key   = $this->getCacheKey($name);
-        $value = $this->handler->get($key) - $step;
-        $res   = $this->handler->set($key, $value);
-
-        return !$res ? false : $value;
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string       $name 缓存变量名
-     * @param  bool|false   $ttl
-     * @return bool
-     */
-    public function rm($name, $ttl = false)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return false === $ttl ?
-        $this->handler->delete($key) :
-        $this->handler->delete($key, $ttl);
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return bool
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-
-            $this->handler->deleteMulti($keys);
-            $this->rm('tag_' . md5($tag));
-
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        return $this->handler->flush();
-    }
-}

+ 0 - 206
thinkphp/library/think/cache/driver/Redis.php

@@ -1,206 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-/**
- * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好
- * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动
- *
- * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis
- * @author    尘缘 <130775@qq.com>
- */
-class Redis extends Driver
-{
-    protected $options = [
-        'host'       => '127.0.0.1',
-        'port'       => 6379,
-        'password'   => '',
-        'select'     => 0,
-        'timeout'    => 0,
-        'expire'     => 0,
-        'persistent' => false,
-        'prefix'     => '',
-        'serialize'  => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     */
-    public function __construct($options = [])
-    {
-        if (!extension_loaded('redis')) {
-            throw new \BadFunctionCallException('not support: redis');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        $this->handler = new \Redis;
-
-        if ($this->options['persistent']) {
-            $this->handler->pconnect($this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']);
-        } else {
-            $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']);
-        }
-
-        if ('' != $this->options['password']) {
-            $this->handler->auth($this->options['password']);
-        }
-
-        if (0 != $this->options['select']) {
-            $this->handler->select($this->options['select']);
-        }
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        return $this->handler->exists($this->getCacheKey($name));
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $value = $this->handler->get($this->getCacheKey($name));
-
-        if (is_null($value) || false === $value) {
-            return $default;
-        }
-
-        return $this->unserialize($value);
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string            $name 缓存变量名
-     * @param  mixed             $value  存储数据
-     * @param  integer|\DateTime $expire  有效时间(秒)
-     * @return boolean
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($this->tag && !$this->has($name)) {
-            $first = true;
-        }
-
-        $key    = $this->getCacheKey($name);
-        $expire = $this->getExpireTime($expire);
-
-        $value = $this->serialize($value);
-
-        if ($expire) {
-            $result = $this->handler->setex($key, $expire, $value);
-        } else {
-            $result = $this->handler->set($key, $value);
-        }
-
-        isset($first) && $this->setTagItem($key);
-
-        return $result;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return $this->handler->incrby($key, $step);
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return $this->handler->decrby($key, $step);
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        return $this->handler->delete($this->getCacheKey($name));
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-
-            foreach ($keys as $key) {
-                $this->handler->delete($key);
-            }
-
-            $this->rm('tag_' . md5($tag));
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        return $this->handler->flushDB();
-    }
-
-}

+ 0 - 233
thinkphp/library/think/cache/driver/Sqlite.php

@@ -1,233 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-/**
- * Sqlite缓存驱动
- * @author    liu21st <liu21st@gmail.com>
- */
-class Sqlite extends Driver
-{
-    protected $options = [
-        'db'         => ':memory:',
-        'table'      => 'sharedmemory',
-        'prefix'     => '',
-        'expire'     => 0,
-        'persistent' => false,
-        'serialize'  => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     * @throws \BadFunctionCallException
-     */
-    public function __construct($options = [])
-    {
-        if (!extension_loaded('sqlite')) {
-            throw new \BadFunctionCallException('not support: sqlite');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-
-        $func = $this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open';
-
-        $this->handler = $func($this->options['db']);
-    }
-
-    /**
-     * 获取实际的缓存标识
-     * @access public
-     * @param  string $name 缓存名
-     * @return string
-     */
-    protected function getCacheKey($name)
-    {
-        return $this->options['prefix'] . sqlite_escape_string($name);
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        $name = $this->getCacheKey($name);
-
-        $sql    = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . time() . ') LIMIT 1';
-        $result = sqlite_query($this->handler, $sql);
-
-        return sqlite_num_rows($result);
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $name = $this->getCacheKey($name);
-
-        $sql = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . time() . ') LIMIT 1';
-
-        $result = sqlite_query($this->handler, $sql);
-
-        if (sqlite_num_rows($result)) {
-            $content = sqlite_fetch_single($result);
-            if (function_exists('gzcompress')) {
-                //启用数据压缩
-                $content = gzuncompress($content);
-            }
-
-            return $this->unserialize($content);
-        }
-
-        return $default;
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string            $name 缓存变量名
-     * @param  mixed             $value  存储数据
-     * @param  integer|\DateTime $expire  有效时间(秒)
-     * @return boolean
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        $name = $this->getCacheKey($name);
-
-        $value = sqlite_escape_string($this->serialize($value));
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($expire instanceof \DateTime) {
-            $expire = $expire->getTimestamp();
-        } else {
-            $expire = (0 == $expire) ? 0 : (time() + $expire); //缓存有效期为0表示永久缓存
-        }
-
-        if (function_exists('gzcompress')) {
-            //数据压缩
-            $value = gzcompress($value, 3);
-        }
-
-        if ($this->tag) {
-            $tag       = $this->tag;
-            $this->tag = null;
-        } else {
-            $tag = '';
-        }
-
-        $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value, expire, tag) VALUES (\'' . $name . '\', \'' . $value . '\', \'' . $expire . '\', \'' . $tag . '\')';
-
-        if (sqlite_query($this->handler, $sql)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value = $this->get($name) + $step;
-        } else {
-            $value = $step;
-        }
-
-        return $this->set($name, $value, 0) ? $value : false;
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        if ($this->has($name)) {
-            $value = $this->get($name) - $step;
-        } else {
-            $value = -$step;
-        }
-
-        return $this->set($name, $value, 0) ? $value : false;
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        $name = $this->getCacheKey($name);
-
-        $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\'';
-        sqlite_query($this->handler, $sql);
-
-        return true;
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            $name = sqlite_escape_string($tag);
-            $sql  = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\'' . $name . '\'';
-            sqlite_query($this->handler, $sql);
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        $sql = 'DELETE FROM ' . $this->options['table'];
-
-        sqlite_query($this->handler, $sql);
-
-        return true;
-    }
-}

+ 0 - 174
thinkphp/library/think/cache/driver/Wincache.php

@@ -1,174 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-/**
- * Wincache缓存驱动
- * @author    liu21st <liu21st@gmail.com>
- */
-class Wincache extends Driver
-{
-    protected $options = [
-        'prefix'    => '',
-        'expire'    => 0,
-        'serialize' => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     * @throws \BadFunctionCallException
-     */
-    public function __construct($options = [])
-    {
-        if (!function_exists('wincache_ucache_info')) {
-            throw new \BadFunctionCallException('not support: WinCache');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        $this->readTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return wincache_ucache_exists($key);
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return wincache_ucache_exists($key) ? $this->unserialize(wincache_ucache_get($key)) : $default;
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string            $name 缓存变量名
-     * @param  mixed             $value  存储数据
-     * @param  integer|\DateTime $expire  有效时间(秒)
-     * @return boolean
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        $key    = $this->getCacheKey($name);
-        $expire = $this->getExpireTime($expire);
-        $value  = $this->serialize($value);
-
-        if ($this->tag && !$this->has($name)) {
-            $first = true;
-        }
-
-        if (wincache_ucache_set($key, $value, $expire)) {
-            isset($first) && $this->setTagItem($key);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return wincache_ucache_inc($key, $step);
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return wincache_ucache_dec($key, $step);
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        return wincache_ucache_delete($this->getCacheKey($name));
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            $keys = $this->getTagItem($tag);
-            foreach ($keys as $key) {
-                wincache_ucache_delete($key);
-            }
-            $this->rm('tag_' . md5($tag));
-            return true;
-        } else {
-            $this->writeTimes++;
-            return wincache_ucache_clear();
-        }
-    }
-
-}

+ 0 - 177
thinkphp/library/think/cache/driver/Xcache.php

@@ -1,177 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\cache\driver;
-
-use think\cache\Driver;
-
-/**
- * Xcache缓存驱动
- * @author    liu21st <liu21st@gmail.com>
- */
-class Xcache extends Driver
-{
-    protected $options = [
-        'prefix'    => '',
-        'expire'    => 0,
-        'serialize' => true,
-    ];
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  array $options 缓存参数
-     * @throws \BadFunctionCallException
-     */
-    public function __construct($options = [])
-    {
-        if (!function_exists('xcache_info')) {
-            throw new \BadFunctionCallException('not support: Xcache');
-        }
-
-        if (!empty($options)) {
-            $this->options = array_merge($this->options, $options);
-        }
-    }
-
-    /**
-     * 判断缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return bool
-     */
-    public function has($name)
-    {
-        $key = $this->getCacheKey($name);
-
-        return xcache_isset($key);
-    }
-
-    /**
-     * 读取缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function get($name, $default = false)
-    {
-        $this->readTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return xcache_isset($key) ? $this->unserialize(xcache_get($key)) : $default;
-    }
-
-    /**
-     * 写入缓存
-     * @access public
-     * @param  string            $name 缓存变量名
-     * @param  mixed             $value  存储数据
-     * @param  integer|\DateTime $expire  有效时间(秒)
-     * @return boolean
-     */
-    public function set($name, $value, $expire = null)
-    {
-        $this->writeTimes++;
-
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        if ($this->tag && !$this->has($name)) {
-            $first = true;
-        }
-
-        $key    = $this->getCacheKey($name);
-        $expire = $this->getExpireTime($expire);
-        $value  = $this->serialize($value);
-
-        if (xcache_set($key, $value, $expire)) {
-            isset($first) && $this->setTagItem($key);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 自增缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function inc($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return xcache_inc($key, $step);
-    }
-
-    /**
-     * 自减缓存(针对数值缓存)
-     * @access public
-     * @param  string    $name 缓存变量名
-     * @param  int       $step 步长
-     * @return false|int
-     */
-    public function dec($name, $step = 1)
-    {
-        $this->writeTimes++;
-
-        $key = $this->getCacheKey($name);
-
-        return xcache_dec($key, $step);
-    }
-
-    /**
-     * 删除缓存
-     * @access public
-     * @param  string $name 缓存变量名
-     * @return boolean
-     */
-    public function rm($name)
-    {
-        $this->writeTimes++;
-
-        return xcache_unset($this->getCacheKey($name));
-    }
-
-    /**
-     * 清除缓存
-     * @access public
-     * @param  string $tag 标签名
-     * @return boolean
-     */
-    public function clear($tag = null)
-    {
-        if ($tag) {
-            // 指定标签清除
-            $keys = $this->getTagItem($tag);
-            foreach ($keys as $key) {
-                xcache_unset($key);
-            }
-            $this->rm('tag_' . md5($tag));
-            return true;
-        }
-
-        $this->writeTimes++;
-
-        if (function_exists('xcache_unset_by_prefix')) {
-            return xcache_unset_by_prefix($this->options['prefix']);
-        } else {
-            return false;
-        }
-    }
-}

+ 0 - 24
thinkphp/library/think/config/driver/Ini.php

@@ -1,24 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\config\driver;
-
-class Ini
-{
-    public function parse($config)
-    {
-        if (is_file($config)) {
-            return parse_ini_file($config, true);
-        } else {
-            return parse_ini_string($config, true);
-        }
-    }
-}

+ 0 - 26
thinkphp/library/think/config/driver/Json.php

@@ -1,26 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\config\driver;
-
-class Json
-{
-    public function parse($config)
-    {
-        if (is_file($config)) {
-            $config = file_get_contents($config);
-        }
-
-        $result = json_decode($config, true);
-
-        return $result;
-    }
-}

+ 0 - 33
thinkphp/library/think/config/driver/Xml.php

@@ -1,33 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\config\driver;
-
-class Xml
-{
-    public function parse($config)
-    {
-        if (is_file($config)) {
-            $content = simplexml_load_file($config);
-        } else {
-            $content = simplexml_load_string($config);
-        }
-
-        $result = (array) $content;
-        foreach ($result as $key => $val) {
-            if (is_object($val)) {
-                $result[$key] = (array) $val;
-            }
-        }
-
-        return $result;
-    }
-}

+ 0 - 470
thinkphp/library/think/console/Command.php

@@ -1,470 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console;
-
-use think\Console;
-use think\console\input\Argument;
-use think\console\input\Definition;
-use think\console\input\Option;
-
-class Command
-{
-
-    /** @var  Console */
-    private $console;
-    private $name;
-    private $aliases = [];
-    private $definition;
-    private $help;
-    private $description;
-    private $ignoreValidationErrors          = false;
-    private $consoleDefinitionMerged         = false;
-    private $consoleDefinitionMergedWithArgs = false;
-    private $code;
-    private $synopsis = [];
-    private $usages   = [];
-
-    /** @var  Input */
-    protected $input;
-
-    /** @var  Output */
-    protected $output;
-
-    /**
-     * 构造方法
-     * @param string|null $name 命令名称,如果没有设置则比如在 configure() 里设置
-     * @throws \LogicException
-     * @api
-     */
-    public function __construct($name = null)
-    {
-        $this->definition = new Definition();
-
-        if (null !== $name) {
-            $this->setName($name);
-        }
-
-        $this->configure();
-
-        if (!$this->name) {
-            throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
-        }
-    }
-
-    /**
-     * 忽略验证错误
-     */
-    public function ignoreValidationErrors()
-    {
-        $this->ignoreValidationErrors = true;
-    }
-
-    /**
-     * 设置控制台
-     * @param Console $console
-     */
-    public function setConsole(Console $console = null)
-    {
-        $this->console = $console;
-    }
-
-    /**
-     * 获取控制台
-     * @return Console
-     * @api
-     */
-    public function getConsole()
-    {
-        return $this->console;
-    }
-
-    /**
-     * 是否有效
-     * @return bool
-     */
-    public function isEnabled()
-    {
-        return true;
-    }
-
-    /**
-     * 配置指令
-     */
-    protected function configure()
-    {
-    }
-
-    /**
-     * 执行指令
-     * @param Input  $input
-     * @param Output $output
-     * @return null|int
-     * @throws \LogicException
-     * @see setCode()
-     */
-    protected function execute(Input $input, Output $output)
-    {
-        throw new \LogicException('You must override the execute() method in the concrete command class.');
-    }
-
-    /**
-     * 用户验证
-     * @param Input  $input
-     * @param Output $output
-     */
-    protected function interact(Input $input, Output $output)
-    {
-    }
-
-    /**
-     * 初始化
-     * @param Input  $input  An InputInterface instance
-     * @param Output $output An OutputInterface instance
-     */
-    protected function initialize(Input $input, Output $output)
-    {
-    }
-
-    /**
-     * 执行
-     * @param Input  $input
-     * @param Output $output
-     * @return int
-     * @throws \Exception
-     * @see setCode()
-     * @see execute()
-     */
-    public function run(Input $input, Output $output)
-    {
-        $this->input  = $input;
-        $this->output = $output;
-
-        $this->getSynopsis(true);
-        $this->getSynopsis(false);
-
-        $this->mergeConsoleDefinition();
-
-        try {
-            $input->bind($this->definition);
-        } catch (\Exception $e) {
-            if (!$this->ignoreValidationErrors) {
-                throw $e;
-            }
-        }
-
-        $this->initialize($input, $output);
-
-        if ($input->isInteractive()) {
-            $this->interact($input, $output);
-        }
-
-        $input->validate();
-
-        if ($this->code) {
-            $statusCode = call_user_func($this->code, $input, $output);
-        } else {
-            $statusCode = $this->execute($input, $output);
-        }
-
-        return is_numeric($statusCode) ? (int) $statusCode : 0;
-    }
-
-    /**
-     * 设置执行代码
-     * @param callable $code callable(InputInterface $input, OutputInterface $output)
-     * @return Command
-     * @throws \InvalidArgumentException
-     * @see execute()
-     */
-    public function setCode(callable $code)
-    {
-        if (!is_callable($code)) {
-            throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
-        }
-
-        if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
-            $r = new \ReflectionFunction($code);
-            if (null === $r->getClosureThis()) {
-                $code = \Closure::bind($code, $this);
-            }
-        }
-
-        $this->code = $code;
-
-        return $this;
-    }
-
-    /**
-     * 合并参数定义
-     * @param bool $mergeArgs
-     */
-    public function mergeConsoleDefinition($mergeArgs = true)
-    {
-        if (null === $this->console
-            || (true === $this->consoleDefinitionMerged
-                && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs))
-        ) {
-            return;
-        }
-
-        if ($mergeArgs) {
-            $currentArguments = $this->definition->getArguments();
-            $this->definition->setArguments($this->console->getDefinition()->getArguments());
-            $this->definition->addArguments($currentArguments);
-        }
-
-        $this->definition->addOptions($this->console->getDefinition()->getOptions());
-
-        $this->consoleDefinitionMerged = true;
-        if ($mergeArgs) {
-            $this->consoleDefinitionMergedWithArgs = true;
-        }
-    }
-
-    /**
-     * 设置参数定义
-     * @param array|Definition $definition
-     * @return Command
-     * @api
-     */
-    public function setDefinition($definition)
-    {
-        if ($definition instanceof Definition) {
-            $this->definition = $definition;
-        } else {
-            $this->definition->setDefinition($definition);
-        }
-
-        $this->consoleDefinitionMerged = false;
-
-        return $this;
-    }
-
-    /**
-     * 获取参数定义
-     * @return Definition
-     * @api
-     */
-    public function getDefinition()
-    {
-        return $this->definition;
-    }
-
-    /**
-     * 获取当前指令的参数定义
-     * @return Definition
-     */
-    public function getNativeDefinition()
-    {
-        return $this->getDefinition();
-    }
-
-    /**
-     * 添加参数
-     * @param string $name        名称
-     * @param int    $mode        类型
-     * @param string $description 描述
-     * @param mixed  $default     默认值
-     * @return Command
-     */
-    public function addArgument($name, $mode = null, $description = '', $default = null)
-    {
-        $this->definition->addArgument(new Argument($name, $mode, $description, $default));
-
-        return $this;
-    }
-
-    /**
-     * 添加选项
-     * @param string $name        选项名称
-     * @param string $shortcut    别名
-     * @param int    $mode        类型
-     * @param string $description 描述
-     * @param mixed  $default     默认值
-     * @return Command
-     */
-    public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
-    {
-        $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default));
-
-        return $this;
-    }
-
-    /**
-     * 设置指令名称
-     * @param string $name
-     * @return Command
-     * @throws \InvalidArgumentException
-     */
-    public function setName($name)
-    {
-        $this->validateName($name);
-
-        $this->name = $name;
-
-        return $this;
-    }
-
-    /**
-     * 获取指令名称
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * 设置描述
-     * @param string $description
-     * @return Command
-     */
-    public function setDescription($description)
-    {
-        $this->description = $description;
-
-        return $this;
-    }
-
-    /**
-     *  获取描述
-     * @return string
-     */
-    public function getDescription()
-    {
-        return $this->description;
-    }
-
-    /**
-     * 设置帮助信息
-     * @param string $help
-     * @return Command
-     */
-    public function setHelp($help)
-    {
-        $this->help = $help;
-
-        return $this;
-    }
-
-    /**
-     * 获取帮助信息
-     * @return string
-     */
-    public function getHelp()
-    {
-        return $this->help;
-    }
-
-    /**
-     * 描述信息
-     * @return string
-     */
-    public function getProcessedHelp()
-    {
-        $name = $this->name;
-
-        $placeholders = [
-            '%command.name%',
-            '%command.full_name%',
-        ];
-        $replacements = [
-            $name,
-            $_SERVER['PHP_SELF'] . ' ' . $name,
-        ];
-
-        return str_replace($placeholders, $replacements, $this->getHelp());
-    }
-
-    /**
-     * 设置别名
-     * @param string[] $aliases
-     * @return Command
-     * @throws \InvalidArgumentException
-     */
-    public function setAliases($aliases)
-    {
-        if (!is_array($aliases) && !$aliases instanceof \Traversable) {
-            throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
-        }
-
-        foreach ($aliases as $alias) {
-            $this->validateName($alias);
-        }
-
-        $this->aliases = $aliases;
-
-        return $this;
-    }
-
-    /**
-     * 获取别名
-     * @return array
-     */
-    public function getAliases()
-    {
-        return $this->aliases;
-    }
-
-    /**
-     * 获取简介
-     * @param bool $short 是否简单的
-     * @return string
-     */
-    public function getSynopsis($short = false)
-    {
-        $key = $short ? 'short' : 'long';
-
-        if (!isset($this->synopsis[$key])) {
-            $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
-        }
-
-        return $this->synopsis[$key];
-    }
-
-    /**
-     * 添加用法介绍
-     * @param string $usage
-     * @return $this
-     */
-    public function addUsage($usage)
-    {
-        if (0 !== strpos($usage, $this->name)) {
-            $usage = sprintf('%s %s', $this->name, $usage);
-        }
-
-        $this->usages[] = $usage;
-
-        return $this;
-    }
-
-    /**
-     * 获取用法介绍
-     * @return array
-     */
-    public function getUsages()
-    {
-        return $this->usages;
-    }
-
-    /**
-     * 验证指令名称
-     * @param string $name
-     * @throws \InvalidArgumentException
-     */
-    private function validateName($name)
-    {
-        if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
-            throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
-        }
-    }
-}

+ 0 - 464
thinkphp/library/think/console/Input.php

@@ -1,464 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console;
-
-use think\console\input\Argument;
-use think\console\input\Definition;
-use think\console\input\Option;
-
-class Input
-{
-
-    /**
-     * @var Definition
-     */
-    protected $definition;
-
-    /**
-     * @var Option[]
-     */
-    protected $options = [];
-
-    /**
-     * @var Argument[]
-     */
-    protected $arguments = [];
-
-    protected $interactive = true;
-
-    private $tokens;
-    private $parsed;
-
-    public function __construct($argv = null)
-    {
-        if (null === $argv) {
-            $argv = $_SERVER['argv'];
-            // 去除命令名
-            array_shift($argv);
-        }
-
-        $this->tokens = $argv;
-
-        $this->definition = new Definition();
-    }
-
-    protected function setTokens(array $tokens)
-    {
-        $this->tokens = $tokens;
-    }
-
-    /**
-     * 绑定实例
-     * @param Definition $definition A InputDefinition instance
-     */
-    public function bind(Definition $definition)
-    {
-        $this->arguments  = [];
-        $this->options    = [];
-        $this->definition = $definition;
-
-        $this->parse();
-    }
-
-    /**
-     * 解析参数
-     */
-    protected function parse()
-    {
-        $parseOptions = true;
-        $this->parsed = $this->tokens;
-        while (null !== $token = array_shift($this->parsed)) {
-            if ($parseOptions && '' == $token) {
-                $this->parseArgument($token);
-            } elseif ($parseOptions && '--' == $token) {
-                $parseOptions = false;
-            } elseif ($parseOptions && 0 === strpos($token, '--')) {
-                $this->parseLongOption($token);
-            } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
-                $this->parseShortOption($token);
-            } else {
-                $this->parseArgument($token);
-            }
-        }
-    }
-
-    /**
-     * 解析短选项
-     * @param string $token 当前的指令.
-     */
-    private function parseShortOption($token)
-    {
-        $name = substr($token, 1);
-
-        if (strlen($name) > 1) {
-            if ($this->definition->hasShortcut($name[0])
-                && $this->definition->getOptionForShortcut($name[0])->acceptValue()
-            ) {
-                $this->addShortOption($name[0], substr($name, 1));
-            } else {
-                $this->parseShortOptionSet($name);
-            }
-        } else {
-            $this->addShortOption($name, null);
-        }
-    }
-
-    /**
-     * 解析短选项
-     * @param string $name 当前指令
-     * @throws \RuntimeException
-     */
-    private function parseShortOptionSet($name)
-    {
-        $len = strlen($name);
-        for ($i = 0; $i < $len; ++$i) {
-            if (!$this->definition->hasShortcut($name[$i])) {
-                throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
-            }
-
-            $option = $this->definition->getOptionForShortcut($name[$i]);
-            if ($option->acceptValue()) {
-                $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
-
-                break;
-            } else {
-                $this->addLongOption($option->getName(), null);
-            }
-        }
-    }
-
-    /**
-     * 解析完整选项
-     * @param string $token 当前指令
-     */
-    private function parseLongOption($token)
-    {
-        $name = substr($token, 2);
-
-        if (false !== $pos = strpos($name, '=')) {
-            $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
-        } else {
-            $this->addLongOption($name, null);
-        }
-    }
-
-    /**
-     * 解析参数
-     * @param string $token 当前指令
-     * @throws \RuntimeException
-     */
-    private function parseArgument($token)
-    {
-        $c = count($this->arguments);
-
-        if ($this->definition->hasArgument($c)) {
-            $arg = $this->definition->getArgument($c);
-
-            $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
-
-        } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
-            $arg = $this->definition->getArgument($c - 1);
-
-            $this->arguments[$arg->getName()][] = $token;
-        } else {
-            throw new \RuntimeException('Too many arguments.');
-        }
-    }
-
-    /**
-     * 添加一个短选项的值
-     * @param string $shortcut 短名称
-     * @param mixed  $value    值
-     * @throws \RuntimeException
-     */
-    private function addShortOption($shortcut, $value)
-    {
-        if (!$this->definition->hasShortcut($shortcut)) {
-            throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
-        }
-
-        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
-    }
-
-    /**
-     * 添加一个完整选项的值
-     * @param string $name  选项名
-     * @param mixed  $value 值
-     * @throws \RuntimeException
-     */
-    private function addLongOption($name, $value)
-    {
-        if (!$this->definition->hasOption($name)) {
-            throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
-        }
-
-        $option = $this->definition->getOption($name);
-
-        if (false === $value) {
-            $value = null;
-        }
-
-        if (null !== $value && !$option->acceptValue()) {
-            throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value));
-        }
-
-        if (null === $value && $option->acceptValue() && count($this->parsed)) {
-            $next = array_shift($this->parsed);
-            if (isset($next[0]) && '-' !== $next[0]) {
-                $value = $next;
-            } elseif (empty($next)) {
-                $value = '';
-            } else {
-                array_unshift($this->parsed, $next);
-            }
-        }
-
-        if (null === $value) {
-            if ($option->isValueRequired()) {
-                throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
-            }
-
-            if (!$option->isArray()) {
-                $value = $option->isValueOptional() ? $option->getDefault() : true;
-            }
-        }
-
-        if ($option->isArray()) {
-            $this->options[$name][] = $value;
-        } else {
-            $this->options[$name] = $value;
-        }
-    }
-
-    /**
-     * 获取第一个参数
-     * @return string|null
-     */
-    public function getFirstArgument()
-    {
-        foreach ($this->tokens as $token) {
-            if ($token && '-' === $token[0]) {
-                continue;
-            }
-
-            return $token;
-        }
-        return;
-    }
-
-    /**
-     * 检查原始参数是否包含某个值
-     * @param string|array $values 需要检查的值
-     * @return bool
-     */
-    public function hasParameterOption($values)
-    {
-        $values = (array) $values;
-
-        foreach ($this->tokens as $token) {
-            foreach ($values as $value) {
-                if ($token === $value || 0 === strpos($token, $value . '=')) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * 获取原始选项的值
-     * @param string|array $values  需要检查的值
-     * @param mixed        $default 默认值
-     * @return mixed The option value
-     */
-    public function getParameterOption($values, $default = false)
-    {
-        $values = (array) $values;
-        $tokens = $this->tokens;
-
-        while (0 < count($tokens)) {
-            $token = array_shift($tokens);
-
-            foreach ($values as $value) {
-                if ($token === $value || 0 === strpos($token, $value . '=')) {
-                    if (false !== $pos = strpos($token, '=')) {
-                        return substr($token, $pos + 1);
-                    }
-
-                    return array_shift($tokens);
-                }
-            }
-        }
-
-        return $default;
-    }
-
-    /**
-     * 验证输入
-     * @throws \RuntimeException
-     */
-    public function validate()
-    {
-        if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {
-            throw new \RuntimeException('Not enough arguments.');
-        }
-    }
-
-    /**
-     * 检查输入是否是交互的
-     * @return bool
-     */
-    public function isInteractive()
-    {
-        return $this->interactive;
-    }
-
-    /**
-     * 设置输入的交互
-     * @param bool
-     */
-    public function setInteractive($interactive)
-    {
-        $this->interactive = (bool) $interactive;
-    }
-
-    /**
-     * 获取所有的参数
-     * @return Argument[]
-     */
-    public function getArguments()
-    {
-        return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
-    }
-
-    /**
-     * 根据名称获取参数
-     * @param string $name 参数名
-     * @return mixed
-     * @throws \InvalidArgumentException
-     */
-    public function getArgument($name)
-    {
-        if (!$this->definition->hasArgument($name)) {
-            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
-        }
-
-        return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)
-            ->getDefault();
-    }
-
-    /**
-     * 设置参数的值
-     * @param string $name  参数名
-     * @param string $value 值
-     * @throws \InvalidArgumentException
-     */
-    public function setArgument($name, $value)
-    {
-        if (!$this->definition->hasArgument($name)) {
-            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
-        }
-
-        $this->arguments[$name] = $value;
-    }
-
-    /**
-     * 检查是否存在某个参数
-     * @param string|int $name 参数名或位置
-     * @return bool
-     */
-    public function hasArgument($name)
-    {
-        return $this->definition->hasArgument($name);
-    }
-
-    /**
-     * 获取所有的选项
-     * @return Option[]
-     */
-    public function getOptions()
-    {
-        return array_merge($this->definition->getOptionDefaults(), $this->options);
-    }
-
-    /**
-     * 获取选项值
-     * @param string $name 选项名称
-     * @return mixed
-     * @throws \InvalidArgumentException
-     */
-    public function getOption($name)
-    {
-        if (!$this->definition->hasOption($name)) {
-            throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
-        }
-
-        return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
-    }
-
-    /**
-     * 设置选项值
-     * @param string      $name  选项名
-     * @param string|bool $value 值
-     * @throws \InvalidArgumentException
-     */
-    public function setOption($name, $value)
-    {
-        if (!$this->definition->hasOption($name)) {
-            throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
-        }
-
-        $this->options[$name] = $value;
-    }
-
-    /**
-     * 是否有某个选项
-     * @param string $name 选项名
-     * @return bool
-     */
-    public function hasOption($name)
-    {
-        return $this->definition->hasOption($name) && isset($this->options[$name]);
-    }
-
-    /**
-     * 转义指令
-     * @param string $token
-     * @return string
-     */
-    public function escapeToken($token)
-    {
-        return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
-    }
-
-    /**
-     * 返回传递给命令的参数的字符串
-     * @return string
-     */
-    public function __toString()
-    {
-        $tokens = array_map(function ($token) {
-            if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
-                return $match[1] . $this->escapeToken($match[2]);
-            }
-
-            if ($token && '-' !== $token[0]) {
-                return $this->escapeToken($token);
-            }
-
-            return $token;
-        }, $this->tokens);
-
-        return implode(' ', $tokens);
-    }
-}

+ 0 - 19
thinkphp/library/think/console/LICENSE

@@ -1,19 +0,0 @@
-Copyright (c) 2004-2016 Fabien Potencier
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

+ 0 - 222
thinkphp/library/think/console/Output.php

@@ -1,222 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console;
-
-use Exception;
-use think\console\output\Ask;
-use think\console\output\Descriptor;
-use think\console\output\driver\Buffer;
-use think\console\output\driver\Console;
-use think\console\output\driver\Nothing;
-use think\console\output\Question;
-use think\console\output\question\Choice;
-use think\console\output\question\Confirmation;
-
-/**
- * Class Output
- * @package think\console
- *
- * @see     \think\console\output\driver\Console::setDecorated
- * @method void setDecorated($decorated)
- *
- * @see     \think\console\output\driver\Buffer::fetch
- * @method string fetch()
- *
- * @method void info($message)
- * @method void error($message)
- * @method void comment($message)
- * @method void warning($message)
- * @method void highlight($message)
- * @method void question($message)
- */
-class Output
-{
-    const VERBOSITY_QUIET        = 0;
-    const VERBOSITY_NORMAL       = 1;
-    const VERBOSITY_VERBOSE      = 2;
-    const VERBOSITY_VERY_VERBOSE = 3;
-    const VERBOSITY_DEBUG        = 4;
-
-    const OUTPUT_NORMAL = 0;
-    const OUTPUT_RAW    = 1;
-    const OUTPUT_PLAIN  = 2;
-
-    private $verbosity = self::VERBOSITY_NORMAL;
-
-    /** @var Buffer|Console|Nothing */
-    private $handle = null;
-
-    protected $styles = [
-        'info',
-        'error',
-        'comment',
-        'question',
-        'highlight',
-        'warning'
-    ];
-
-    public function __construct($driver = 'console')
-    {
-        $class = '\\think\\console\\output\\driver\\' . ucwords($driver);
-
-        $this->handle = new $class($this);
-    }
-
-    public function ask(Input $input, $question, $default = null, $validator = null)
-    {
-        $question = new Question($question, $default);
-        $question->setValidator($validator);
-
-        return $this->askQuestion($input, $question);
-    }
-
-    public function askHidden(Input $input, $question, $validator = null)
-    {
-        $question = new Question($question);
-
-        $question->setHidden(true);
-        $question->setValidator($validator);
-
-        return $this->askQuestion($input, $question);
-    }
-
-    public function confirm(Input $input, $question, $default = true)
-    {
-        return $this->askQuestion($input, new Confirmation($question, $default));
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function choice(Input $input, $question, array $choices, $default = null)
-    {
-        if (null !== $default) {
-            $values  = array_flip($choices);
-            $default = $values[$default];
-        }
-
-        return $this->askQuestion($input, new Choice($question, $choices, $default));
-    }
-
-    protected function askQuestion(Input $input, Question $question)
-    {
-        $ask    = new Ask($input, $this, $question);
-        $answer = $ask->run();
-
-        if ($input->isInteractive()) {
-            $this->newLine();
-        }
-
-        return $answer;
-    }
-
-    protected function block($style, $message)
-    {
-        $this->writeln("<{$style}>{$message}</$style>");
-    }
-
-    /**
-     * 输出空行
-     * @param int $count
-     */
-    public function newLine($count = 1)
-    {
-        $this->write(str_repeat(PHP_EOL, $count));
-    }
-
-    /**
-     * 输出信息并换行
-     * @param string $messages
-     * @param int    $type
-     */
-    public function writeln($messages, $type = self::OUTPUT_NORMAL)
-    {
-        $this->write($messages, true, $type);
-    }
-
-    /**
-     * 输出信息
-     * @param string $messages
-     * @param bool   $newline
-     * @param int    $type
-     */
-    public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
-    {
-        $this->handle->write($messages, $newline, $type);
-    }
-
-    public function renderException(\Exception $e)
-    {
-        $this->handle->renderException($e);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function setVerbosity($level)
-    {
-        $this->verbosity = (int) $level;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getVerbosity()
-    {
-        return $this->verbosity;
-    }
-
-    public function isQuiet()
-    {
-        return self::VERBOSITY_QUIET === $this->verbosity;
-    }
-
-    public function isVerbose()
-    {
-        return self::VERBOSITY_VERBOSE <= $this->verbosity;
-    }
-
-    public function isVeryVerbose()
-    {
-        return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
-    }
-
-    public function isDebug()
-    {
-        return self::VERBOSITY_DEBUG <= $this->verbosity;
-    }
-
-    public function describe($object, array $options = [])
-    {
-        $descriptor = new Descriptor();
-        $options    = array_merge([
-            'raw_text' => false,
-        ], $options);
-
-        $descriptor->describe($this, $object, $options);
-    }
-
-    public function __call($method, $args)
-    {
-        if (in_array($method, $this->styles)) {
-            array_unshift($args, $method);
-            return call_user_func_array([$this, 'block'], $args);
-        }
-
-        if ($this->handle && method_exists($this->handle, $method)) {
-            return call_user_func_array([$this->handle, $method], $args);
-        } else {
-            throw new Exception('method not exists:' . __CLASS__ . '->' . $method);
-        }
-    }
-
-}

+ 0 - 1
thinkphp/library/think/console/bin/README.md

@@ -1 +0,0 @@
-console 工具使用 hiddeninput.exe 在 windows 上隐藏密码输入,该二进制文件由第三方提供,相关源码和其他细节可以在 [Hidden Input](https://github.com/Seldaek/hidden-input) 找到。

BIN
thinkphp/library/think/console/bin/hiddeninput.exe


+ 0 - 60
thinkphp/library/think/console/command/Build.php

@@ -1,60 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Option;
-use think\console\Output;
-use think\facade\App;
-use think\facade\Build as AppBuild;
-
-class Build extends Command
-{
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function configure()
-    {
-        $this->setName('build')
-            ->setDefinition([
-                new Option('config', null, Option::VALUE_OPTIONAL, "build.php path"),
-                new Option('module', null, Option::VALUE_OPTIONAL, "module name"),
-            ])
-            ->setDescription('Build Application Dirs');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        if ($input->hasOption('module')) {
-            AppBuild::module($input->getOption('module'));
-            $output->writeln("Successed");
-            return;
-        }
-
-        if ($input->hasOption('config')) {
-            $build = include $input->getOption('config');
-        } else {
-            $build = include App::getAppPath() . 'build.php';
-        }
-
-        if (empty($build)) {
-            $output->writeln("Build Config Is Empty");
-            return;
-        }
-
-        AppBuild::run($build);
-        $output->writeln("Successed");
-
-    }
-}

+ 0 - 45
thinkphp/library/think/console/command/Clear.php

@@ -1,45 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Option;
-use think\console\Output;
-use think\facade\App;
-
-class Clear extends Command
-{
-    protected function configure()
-    {
-        // 指令配置
-        $this
-            ->setName('clear')
-            ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null)
-            ->setDescription('Clear runtime file');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        $path  = $input->getOption('path') ?: App::getRuntimePath();
-        $files = scandir($path);
-        if ($files) {
-            foreach ($files as $file) {
-                if ('.' != $file && '..' != $file && is_dir($path . $file)) {
-                    array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*'));
-                } elseif ('.gitignore' != $file && is_file($path . $file)) {
-                    unlink($path . $file);
-                }
-            }
-        }
-        $output->writeln("<info>Clear Successed</info>");
-    }
-}

+ 0 - 69
thinkphp/library/think/console/command/Help.php

@@ -1,69 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Argument as InputArgument;
-use think\console\input\Option as InputOption;
-use think\console\Output;
-
-class Help extends Command
-{
-
-    private $command;
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function configure()
-    {
-        $this->ignoreValidationErrors();
-
-        $this->setName('help')->setDefinition([
-            new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
-            new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
-        ])->setDescription('Displays help for a command')->setHelp(<<<EOF
-The <info>%command.name%</info> command displays help for a given command:
-
-  <info>php %command.full_name% list</info>
-
-To display the list of available commands, please use the <info>list</info> command.
-EOF
-        );
-    }
-
-    /**
-     * Sets the command.
-     * @param Command $command The command to set
-     */
-    public function setCommand(Command $command)
-    {
-        $this->command = $command;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function execute(Input $input, Output $output)
-    {
-        if (null === $this->command) {
-            $this->command = $this->getConsole()->find($input->getArgument('command_name'));
-        }
-
-        $output->describe($this->command, [
-            'raw_text' => $input->getOption('raw'),
-        ]);
-
-        $this->command = null;
-    }
-}

+ 0 - 74
thinkphp/library/think/console/command/Lists.php

@@ -1,74 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\Output;
-use think\console\input\Argument as InputArgument;
-use think\console\input\Option as InputOption;
-use think\console\input\Definition as InputDefinition;
-
-class Lists extends Command
-{
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function configure()
-    {
-        $this->setName('list')->setDefinition($this->createDefinition())->setDescription('Lists commands')->setHelp(<<<EOF
-The <info>%command.name%</info> command lists all commands:
-
-  <info>php %command.full_name%</info>
-
-You can also display the commands for a specific namespace:
-
-  <info>php %command.full_name% test</info>
-
-It's also possible to get raw list of commands (useful for embedding command runner):
-
-  <info>php %command.full_name% --raw</info>
-EOF
-        );
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getNativeDefinition()
-    {
-        return $this->createDefinition();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function execute(Input $input, Output $output)
-    {
-        $output->describe($this->getConsole(), [
-            'raw_text'  => $input->getOption('raw'),
-            'namespace' => $input->getArgument('namespace'),
-        ]);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    private function createDefinition()
-    {
-        return new InputDefinition([
-            new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
-            new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list')
-        ]);
-    }
-}

+ 0 - 111
thinkphp/library/think/console/command/Make.php

@@ -1,111 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 刘志淳 <chun@engineer.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Argument;
-use think\console\Output;
-use think\facade\App;
-use think\facade\Config;
-use think\facade\Env;
-
-abstract class Make extends Command
-{
-
-    protected $type;
-
-    abstract protected function getStub();
-
-    protected function configure()
-    {
-        $this->addArgument('name', Argument::REQUIRED, "The name of the class");
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-
-        $name = trim($input->getArgument('name'));
-
-        $classname = $this->getClassName($name);
-
-        $pathname = $this->getPathName($classname);
-
-        if (is_file($pathname)) {
-            $output->writeln('<error>' . $this->type . ' already exists!</error>');
-            return false;
-        }
-
-        if (!is_dir(dirname($pathname))) {
-            mkdir(strtolower(dirname($pathname)), 0755, true);
-        }
-
-        file_put_contents($pathname, $this->buildClass($classname));
-
-        $output->writeln('<info>' . $this->type . ' created successfully.</info>');
-
-    }
-
-    protected function buildClass($name)
-    {
-        $stub = file_get_contents($this->getStub());
-
-        $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
-
-        $class = str_replace($namespace . '\\', '', $name);
-
-        return str_replace(['{%className%}', '{%namespace%}', '{%app_namespace%}'], [
-            $class,
-            $namespace,
-            App::getNamespace(),
-        ], $stub);
-
-    }
-
-    protected function getPathName($name)
-    {
-        $name = str_replace(App::getNamespace() . '\\', '', $name);
-
-        return Env::get('app_path') . ltrim(str_replace('\\', '/', $name), '/') . '.php';
-    }
-
-    protected function getClassName($name)
-    {
-        $appNamespace = App::getNamespace();
-
-        if (strpos($name, $appNamespace . '\\') !== false) {
-            return $name;
-        }
-
-        if (Config::get('app_multi_module')) {
-            if (strpos($name, '/')) {
-                list($module, $name) = explode('/', $name, 2);
-            } else {
-                $module = 'common';
-            }
-        } else {
-            $module = null;
-        }
-
-        if (strpos($name, '/') !== false) {
-            $name = str_replace('/', '\\', $name);
-        }
-
-        return $this->getNamespace($appNamespace, $module) . '\\' . $name;
-    }
-
-    protected function getNamespace($appNamespace, $module)
-    {
-        return $module ? ($appNamespace . '\\' . $module) : $appNamespace;
-    }
-
-}

+ 0 - 54
thinkphp/library/think/console/command/RunServer.php

@@ -1,54 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: Slince <taosikai@yeah.net>
-// +----------------------------------------------------------------------
-namespace think\console\command;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Option;
-use think\console\Output;
-use think\facade\App;
-
-class RunServer extends Command
-{
-
-    public function configure()
-    {
-        $this->setName('run')
-            ->addOption('host', 'H', Option::VALUE_OPTIONAL,
-                'The host to server the application on', '127.0.0.1')
-            ->addOption('port', 'p', Option::VALUE_OPTIONAL,
-                'The port to server the application on', 8000)
-            ->addOption('root', 'r', Option::VALUE_OPTIONAL,
-                'The document root of the application', App::getRootPath() . 'public')
-            ->setDescription('PHP Built-in Server for ThinkPHP');
-    }
-
-    public function execute(Input $input, Output $output)
-    {
-        $host = $input->getOption('host');
-        $port = $input->getOption('port');
-        $root = $input->getOption('root');
-
-        $command = sprintf(
-            'php -S %s:%d -t %s %s',
-            $host,
-            $port,
-            escapeshellarg($root),
-            escapeshellarg($root . DIRECTORY_SEPARATOR . 'router.php')
-        );
-
-        $output->writeln(sprintf('ThinkPHP Development server is started On <http://%s:%s/>', $host, $port));
-        $output->writeln(sprintf('You can exit with <info>`CTRL-C`</info>'));
-        $output->writeln(sprintf('Document root is: %s', $root));
-        passthru($command);
-    }
-
-}

+ 0 - 57
thinkphp/library/think/console/command/make/Controller.php

@@ -1,57 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 刘志淳 <chun@engineer.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command\make;
-
-use think\console\command\Make;
-use think\console\input\Option;
-use think\facade\Config;
-
-class Controller extends Make
-{
-
-    protected $type = "Controller";
-
-    protected function configure()
-    {
-        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 $stubPath . 'controller.stub';
-    }
-
-    protected function getClassName($name)
-    {
-        return parent::getClassName($name) . (Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '');
-    }
-
-    protected function getNamespace($appNamespace, $module)
-    {
-        return parent::getNamespace($appNamespace, $module) . '\controller';
-    }
-
-}

+ 0 - 36
thinkphp/library/think/console/command/make/Middleware.php

@@ -1,36 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 刘志淳 <chun@engineer.com>
-// +----------------------------------------------------------------------
-
-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';
-    }
-}

+ 0 - 36
thinkphp/library/think/console/command/make/Model.php

@@ -1,36 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: 刘志淳 <chun@engineer.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\command\make;
-
-use think\console\command\Make;
-
-class Model extends Make
-{
-    protected $type = "Model";
-
-    protected function configure()
-    {
-        parent::configure();
-        $this->setName('make:model')
-            ->setDescription('Create a new model class');
-    }
-
-    protected function getStub()
-    {
-        return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'model.stub';
-    }
-
-    protected function getNamespace($appNamespace, $module)
-    {
-        return parent::getNamespace($appNamespace, $module) . '\model';
-    }
-}

+ 0 - 64
thinkphp/library/think/console/command/make/stubs/controller.api.stub

@@ -1,64 +0,0 @@
-<?php
-
-namespace {%namespace%};
-
-use think\Controller;
-use think\Request;
-
-class {%className%} extends Controller
-{
-    /**
-     * 显示资源列表
-     *
-     * @return \think\Response
-     */
-    public function index()
-    {
-        //
-    }
-
-    /**
-     * 保存新建的资源
-     *
-     * @param  \think\Request  $request
-     * @return \think\Response
-     */
-    public function save(Request $request)
-    {
-        //
-    }
-
-    /**
-     * 显示指定的资源
-     *
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function read($id)
-    {
-        //
-    }
-
-    /**
-     * 保存更新的资源
-     *
-     * @param  \think\Request  $request
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function update(Request $request, $id)
-    {
-        //
-    }
-
-    /**
-     * 删除指定资源
-     *
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function delete($id)
-    {
-        //
-    }
-}

+ 0 - 10
thinkphp/library/think/console/command/make/stubs/controller.plain.stub

@@ -1,10 +0,0 @@
-<?php
-
-namespace {%namespace%};
-
-use think\Controller;
-
-class {%className%} extends Controller
-{
-    //
-}

+ 0 - 85
thinkphp/library/think/console/command/make/stubs/controller.stub

@@ -1,85 +0,0 @@
-<?php
-
-namespace {%namespace%};
-
-use think\Controller;
-use think\Request;
-
-class {%className%} extends Controller
-{
-    /**
-     * 显示资源列表
-     *
-     * @return \think\Response
-     */
-    public function index()
-    {
-        //
-    }
-
-    /**
-     * 显示创建资源表单页.
-     *
-     * @return \think\Response
-     */
-    public function create()
-    {
-        //
-    }
-
-    /**
-     * 保存新建的资源
-     *
-     * @param  \think\Request  $request
-     * @return \think\Response
-     */
-    public function save(Request $request)
-    {
-        //
-    }
-
-    /**
-     * 显示指定的资源
-     *
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function read($id)
-    {
-        //
-    }
-
-    /**
-     * 显示编辑资源表单页.
-     *
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function edit($id)
-    {
-        //
-    }
-
-    /**
-     * 保存更新的资源
-     *
-     * @param  \think\Request  $request
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function update(Request $request, $id)
-    {
-        //
-    }
-
-    /**
-     * 删除指定资源
-     *
-     * @param  int  $id
-     * @return \think\Response
-     */
-    public function delete($id)
-    {
-        //
-    }
-}

+ 0 - 10
thinkphp/library/think/console/command/make/stubs/middleware.stub

@@ -1,10 +0,0 @@
-<?php
-
-namespace {%namespace%};
-
-class {%className%}
-{
-    public function handle($request, \Closure $next)
-    {
-    }
-}

+ 0 - 10
thinkphp/library/think/console/command/make/stubs/model.stub

@@ -1,10 +0,0 @@
-<?php
-
-namespace {%namespace%};
-
-use think\Model;
-
-class {%className%} extends Model
-{
-    //
-}

+ 0 - 280
thinkphp/library/think/console/command/optimize/Autoload.php

@@ -1,280 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-namespace think\console\command\optimize;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\Output;
-use think\Container;
-
-class Autoload extends Command
-{
-
-    protected function configure()
-    {
-        $this->setName('optimize:autoload')
-            ->setDescription('Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-
-        $classmapFile = <<<EOF
-<?php
-/**
- * 类库映射
- */
-
-return [
-
-EOF;
-        $app              = Container::get('app');
-        $namespacesToScan = [
-            $app->getNamespace() . '\\' => realpath(rtrim($app->getAppPath())),
-            'think\\'                   => $app->getAppPath() . 'library/think',
-            'traits\\'                  => $app->getAppPath() . 'library/traits',
-            ''                          => realpath(rtrim($app->getRootPath() . 'extend')),
-        ];
-
-        krsort($namespacesToScan);
-        $classMap = [];
-        foreach ($namespacesToScan as $namespace => $dir) {
-
-            if (!is_dir($dir)) {
-                continue;
-            }
-
-            $namespaceFilter = '' === $namespace ? null : $namespace;
-            $classMap        = $this->addClassMapCode($dir, $namespaceFilter, $classMap);
-        }
-
-        ksort($classMap);
-        foreach ($classMap as $class => $code) {
-            $classmapFile .= '    ' . var_export($class, true) . ' => ' . $code;
-        }
-        $classmapFile .= "];\n";
-        $runtimePath = $app->getRuntimePath();
-        if (!is_dir($runtimePath)) {
-            @mkdir($runtimePath, 0755, true);
-        }
-
-        file_put_contents($runtimePath . 'classmap.php', $classmapFile);
-
-        $output->writeln('<info>Succeed!</info>');
-    }
-
-    protected function addClassMapCode($dir, $namespace, $classMap)
-    {
-        foreach ($this->createMap($dir, $namespace) as $class => $path) {
-
-            $pathCode = $this->getPathCode($path) . ",\n";
-
-            if (!isset($classMap[$class])) {
-                $classMap[$class] = $pathCode;
-            } elseif ($classMap[$class] !== $pathCode && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($classMap[$class] . ' ' . $path, '\\', '/'))) {
-                $this->output->writeln(
-                    '<warning>Warning: Ambiguous class resolution, "' . $class . '"' .
-                    ' was found in both "' . str_replace(["',\n"], [
-                        '',
-                    ], $classMap[$class]) . '" and "' . $path . '", the first will be used.</warning>'
-                );
-            }
-        }
-        return $classMap;
-    }
-
-    protected function getPathCode($path)
-    {
-        $baseDir    = '';
-        $app        = Container::get('app');
-        $appPath    = $this->normalizePath(realpath($app->getAppPath()));
-        $libPath    = $this->normalizePath(realpath($app->getThinkPath() . 'library'));
-        $extendPath = $this->normalizePath(realpath($app->getRootPath() . 'extend'));
-        $path       = $this->normalizePath($path);
-
-        if (strpos($path, $libPath . '/') === 0) {
-            $path    = substr($path, strlen($app->getThinkPath() . 'library'));
-            $baseDir = "'" . $libPath . "/'";
-        } elseif (strpos($path, $appPath . '/') === 0) {
-            $path    = substr($path, strlen($appPath) + 1);
-            $baseDir = "'" . $appPath . "/'";
-        } elseif (strpos($path, $extendPath . '/') === 0) {
-            $path    = substr($path, strlen($extendPath) + 1);
-            $baseDir = "'" . $extendPath . "/'";
-        }
-
-        if (false !== $path) {
-            $baseDir .= " . ";
-        }
-
-        return $baseDir . ((false !== $path) ? var_export($path, true) : "");
-    }
-
-    protected function normalizePath($path)
-    {
-        $parts    = [];
-        $path     = strtr($path, '\\', '/');
-        $prefix   = '';
-        $absolute = false;
-
-        if (preg_match('{^([0-9a-z]+:(?://(?:[a-z]:)?)?)}i', $path, $match)) {
-            $prefix = $match[1];
-            $path   = substr($path, strlen($prefix));
-        }
-
-        if (substr($path, 0, 1) === '/') {
-            $absolute = true;
-            $path     = substr($path, 1);
-        }
-
-        $up = false;
-        foreach (explode('/', $path) as $chunk) {
-            if ('..' === $chunk && ($absolute || $up)) {
-                array_pop($parts);
-                $up = !(empty($parts) || '..' === end($parts));
-            } elseif ('.' !== $chunk && '' !== $chunk) {
-                $parts[] = $chunk;
-                $up      = '..' !== $chunk;
-            }
-        }
-
-        return $prefix . ($absolute ? '/' : '') . implode('/', $parts);
-    }
-
-    protected function createMap($path, $namespace = null)
-    {
-        if (is_string($path)) {
-            if (is_file($path)) {
-                $path = [new \SplFileInfo($path)];
-            } elseif (is_dir($path)) {
-
-                $objects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
-
-                $path = [];
-
-                /** @var \SplFileInfo $object */
-                foreach ($objects as $object) {
-                    if ($object->isFile() && $object->getExtension() == 'php') {
-                        $path[] = $object;
-                    }
-                }
-            } else {
-                throw new \RuntimeException(
-                    'Could not scan for classes inside "' . $path .
-                    '" which does not appear to be a file nor a folder'
-                );
-            }
-        }
-
-        $map = [];
-
-        /** @var \SplFileInfo $file */
-        foreach ($path as $file) {
-            $filePath = $file->getRealPath();
-
-            if (pathinfo($filePath, PATHINFO_EXTENSION) != 'php') {
-                continue;
-            }
-
-            $classes = $this->findClasses($filePath);
-
-            foreach ($classes as $class) {
-                if (null !== $namespace && 0 !== strpos($class, $namespace)) {
-                    continue;
-                }
-
-                if (!isset($map[$class])) {
-                    $map[$class] = $filePath;
-                } elseif ($map[$class] !== $filePath && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($map[$class] . ' ' . $filePath, '\\', '/'))) {
-                    $this->output->writeln(
-                        '<warning>Warning: Ambiguous class resolution, "' . $class . '"' .
-                        ' was found in both "' . $map[$class] . '" and "' . $filePath . '", the first will be used.</warning>'
-                    );
-                }
-            }
-        }
-
-        return $map;
-    }
-
-    protected function findClasses($path)
-    {
-        $extraTypes = '|trait';
-
-        $contents = @php_strip_whitespace($path);
-        if (!$contents) {
-            if (!file_exists($path)) {
-                $message = 'File at "%s" does not exist, check your classmap definitions';
-            } elseif (!is_readable($path)) {
-                $message = 'File at "%s" is not readable, check its permissions';
-            } elseif ('' === trim(file_get_contents($path))) {
-                return [];
-            } else {
-                $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';
-            }
-            $error = error_get_last();
-            if (isset($error['message'])) {
-                $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];
-            }
-            throw new \RuntimeException(sprintf($message, $path));
-        }
-
-        if (!preg_match('{\b(?:class|interface' . $extraTypes . ')\s}i', $contents)) {
-            return [];
-        }
-
-        // strip heredocs/nowdocs
-        $contents = preg_replace('{<<<\s*(\'?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)\\2(?=\r\n|\n|\r|;)}s', 'null', $contents);
-        // strip strings
-        $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);
-        // strip leading non-php code if needed
-        if (substr($contents, 0, 2) !== '<?') {
-            $contents = preg_replace('{^.+?<\?}s', '<?', $contents, 1, $replacements);
-            if (0 === $replacements) {
-                return [];
-            }
-        }
-        // strip non-php blocks in the file
-        $contents = preg_replace('{\?>.+<\?}s', '?><?', $contents);
-        // strip trailing non-php code if needed
-        $pos = strrpos($contents, '?>');
-        if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {
-            $contents = substr($contents, 0, $pos);
-        }
-
-        preg_match_all('{
-            (?:
-                 \b(?<![\$:>])(?P<type>class|interface' . $extraTypes . ') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)
-               | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]
-            )
-        }ix', $contents, $matches);
-
-        $classes   = [];
-        $namespace = '';
-
-        for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {
-            if (!empty($matches['ns'][$i])) {
-                $namespace = str_replace([' ', "\t", "\r", "\n"], '', $matches['nsname'][$i]) . '\\';
-            } else {
-                $name = $matches['name'][$i];
-                if (':' === $name[0]) {
-                    $name = 'xhp' . substr(str_replace(['-', ':'], ['_', '__'], $name), 1);
-                } elseif ('enum' === $matches['type'][$i]) {
-                    $name = rtrim($name, ':');
-                }
-                $classes[] = ltrim($namespace . $name, '\\');
-            }
-        }
-
-        return $classes;
-    }
-
-}

+ 0 - 110
thinkphp/library/think/console/command/optimize/Config.php

@@ -1,110 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2017 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-namespace think\console\command\optimize;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Argument;
-use think\console\Output;
-use think\Container;
-use think\facade\App;
-
-class Config extends Command
-{
-    /** @var  Output */
-    protected $output;
-
-    protected function configure()
-    {
-        $this->setName('optimize:config')
-            ->addArgument('module', Argument::OPTIONAL, 'Build module config cache .')
-            ->setDescription('Build config and common file cache.');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        if ($input->getArgument('module')) {
-            $module = $input->getArgument('module') . DIRECTORY_SEPARATOR;
-        } else {
-            $module = '';
-        }
-
-        $content     = '<?php ' . PHP_EOL . $this->buildCacheContent($module);
-        $runtimePath = App::getRuntimePath();
-        if (!is_dir($runtimePath . $module)) {
-            @mkdir($runtimePath . $module, 0755, true);
-        }
-
-        file_put_contents($runtimePath . $module . 'init.php', $content);
-
-        $output->writeln('<info>Succeed!</info>');
-    }
-
-    protected function buildCacheContent($module)
-    {
-        $content = '// This cache file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL;
-        $path    = realpath(App::getAppPath() . $module) . DIRECTORY_SEPARATOR;
-        if ($module) {
-            $configPath = is_dir($path . 'config') ? $path . 'config' : App::getConfigPath() . $module;
-        } else {
-            $configPath = App::getConfigPath();
-        }
-        $ext    = App::getConfigExt();
-        $config = Container::get('config');
-
-        $files = is_dir($configPath) ? scandir($configPath) : [];
-
-        foreach ($files as $file) {
-            if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $ext) {
-                $filename = $configPath . DIRECTORY_SEPARATOR . $file;
-                $config->load($filename, pathinfo($file, PATHINFO_FILENAME));
-            }
-        }
-
-        // 加载行为扩展文件
-        if (is_file($path . 'tags.php')) {
-            $tags = include $path . 'tags.php';
-            if (is_array($tags)) {
-                $content .= PHP_EOL . '\think\facade\Hook::import(' . (var_export($tags, true)) . ');' . PHP_EOL;
-            }
-        }
-
-        // 加载公共文件
-        if (is_file($path . 'common.php')) {
-            $common = substr(php_strip_whitespace($path . 'common.php'), 6);
-            if ($common) {
-                $content .= PHP_EOL . $common . PHP_EOL;
-            }
-        }
-
-        if ('' == $module) {
-            $content .= PHP_EOL . substr(php_strip_whitespace(App::getThinkPath() . 'helper.php'), 6) . PHP_EOL;
-
-            if (is_file($path . 'middleware.php')) {
-                $middleware = include $path . 'middleware.php';
-                if (is_array($middleware)) {
-                    $content .= PHP_EOL . '\think\Container::get("middleware")->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\facade\Config::set(' . var_export($config->get(), true) . ');' . PHP_EOL;
-
-        return $content;
-    }
-}

+ 0 - 68
thinkphp/library/think/console/command/optimize/Route.php

@@ -1,68 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-namespace think\console\command\optimize;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\Output;
-use think\Container;
-
-class Route extends Command
-{
-    /** @var  Output */
-    protected $output;
-
-    protected function configure()
-    {
-        $this->setName('optimize:route')
-            ->setDescription('Build route cache.');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        $filename = Container::get('app')->getRuntimePath() . 'route.php';
-        if (is_file($filename)) {
-            unlink($filename);
-        }
-        file_put_contents($filename, $this->buildRouteCache());
-        $output->writeln('<info>Succeed!</info>');
-    }
-
-    protected function buildRouteCache()
-    {
-        Container::get('route')->setName([]);
-        Container::get('route')->lazy(false);
-        // 路由检测
-        $path = Container::get('app')->getRoutePath();
-
-        $files = is_dir($path) ? scandir($path) : [];
-
-        foreach ($files as $file) {
-            if (strpos($file, '.php')) {
-                $filename = $path . DIRECTORY_SEPARATOR . $file;
-                // 导入路由配置
-                $rules = include $filename;
-                if (is_array($rules)) {
-                    Container::get('route')->import($rules);
-                }
-            }
-        }
-
-        if (Container::get('config')->get('route_annotation')) {
-            include Container::get('build')->buildRoute();
-        }
-
-        $content = '<?php ' . PHP_EOL . 'return ';
-        $content .= var_export(Container::get('route')->getName(), true) . ';';
-        return $content;
-    }
-
-}

+ 0 - 121
thinkphp/library/think/console/command/optimize/Schema.php

@@ -1,121 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-namespace think\console\command\optimize;
-
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Option;
-use think\console\Output;
-use think\Db;
-use think\facade\App;
-
-class Schema extends Command
-{
-    /** @var  Output */
-    protected $output;
-
-    protected function configure()
-    {
-        $this->setName('optimize:schema')
-            ->addOption('db', null, Option::VALUE_REQUIRED, 'db name .')
-            ->addOption('table', null, Option::VALUE_REQUIRED, 'table name .')
-            ->addOption('module', null, Option::VALUE_REQUIRED, 'module name .')
-            ->setDescription('Build database schema cache.');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        if (!is_dir(App::getRuntimePath() . 'schema')) {
-            @mkdir(App::getRuntimePath() . 'schema', 0755, true);
-        }
-
-        if ($input->hasOption('module')) {
-            $module = $input->getOption('module');
-            // 读取模型
-            $path      = App::getAppPath() . $module . DIRECTORY_SEPARATOR . 'model';
-            $list      = is_dir($path) ? scandir($path) : [];
-            $namespace = App::getNamespace();
-
-            foreach ($list as $file) {
-                if (0 === strpos($file, '.')) {
-                    continue;
-                }
-                $class = '\\' . $namespace . '\\' . $module . '\\model\\' . pathinfo($file, PATHINFO_FILENAME);
-                $this->buildModelSchema($class);
-            }
-
-            $output->writeln('<info>Succeed!</info>');
-            return;
-        } elseif ($input->hasOption('table')) {
-            $table = $input->getOption('table');
-            if (!strpos($table, '.')) {
-                $dbName = Db::getConfig('database');
-            }
-
-            $tables[] = $table;
-        } elseif ($input->hasOption('db')) {
-            $dbName = $input->getOption('db');
-            $tables = Db::getConnection()->getTables($dbName);
-        } elseif (!\think\facade\Config::get('app_multi_module')) {
-            $namespace = App::getNamespace();
-            $path      = App::getAppPath() . 'model';
-            $list      = is_dir($path) ? scandir($path) : [];
-
-            foreach ($list as $file) {
-                if (0 === strpos($file, '.')) {
-                    continue;
-                }
-                $class = '\\' . $namespace . '\\model\\' . pathinfo($file, PATHINFO_FILENAME);
-                $this->buildModelSchema($class);
-            }
-
-            $output->writeln('<info>Succeed!</info>');
-            return;
-        } else {
-            $tables = Db::getConnection()->getTables();
-        }
-
-        $db = isset($dbName) ? $dbName . '.' : '';
-        $this->buildDataBaseSchema($tables, $db);
-
-        $output->writeln('<info>Succeed!</info>');
-    }
-
-    protected function buildModelSchema($class)
-    {
-        $reflect = new \ReflectionClass($class);
-        if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) {
-            $table   = $class::getTable();
-            $dbName  = $class::getConfig('database');
-            $content = '<?php ' . PHP_EOL . 'return ';
-            $info    = $class::getConnection()->getFields($table);
-            $content .= var_export($info, true) . ';';
-
-            file_put_contents(App::getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR . $dbName . '.' . $table . '.php', $content);
-        }
-    }
-
-    protected function buildDataBaseSchema($tables, $db)
-    {
-        if ('' == $db) {
-            $dbName = Db::getConfig('database') . '.';
-        } else {
-            $dbName = $db;
-        }
-
-        foreach ($tables as $table) {
-            $content = '<?php ' . PHP_EOL . 'return ';
-            $info    = Db::getConnection()->getFields($db . $table);
-            $content .= var_export($info, true) . ';';
-            file_put_contents(App::getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR . $dbName . $table . '.php', $content);
-        }
-    }
-}

+ 0 - 115
thinkphp/library/think/console/input/Argument.php

@@ -1,115 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\input;
-
-class Argument
-{
-
-    const REQUIRED = 1;
-    const OPTIONAL = 2;
-    const IS_ARRAY = 4;
-
-    private $name;
-    private $mode;
-    private $default;
-    private $description;
-
-    /**
-     * 构造方法
-     * @param string $name        参数名
-     * @param int    $mode        参数类型: self::REQUIRED 或者 self::OPTIONAL
-     * @param string $description 描述
-     * @param mixed  $default     默认值 (仅 self::OPTIONAL 类型有效)
-     * @throws \InvalidArgumentException
-     */
-    public function __construct($name, $mode = null, $description = '', $default = null)
-    {
-        if (null === $mode) {
-            $mode = self::OPTIONAL;
-        } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
-            throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
-        }
-
-        $this->name        = $name;
-        $this->mode        = $mode;
-        $this->description = $description;
-
-        $this->setDefault($default);
-    }
-
-    /**
-     * 获取参数名
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * 是否必须
-     * @return bool
-     */
-    public function isRequired()
-    {
-        return self::REQUIRED === (self::REQUIRED & $this->mode);
-    }
-
-    /**
-     * 该参数是否接受数组
-     * @return bool
-     */
-    public function isArray()
-    {
-        return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
-    }
-
-    /**
-     * 设置默认值
-     * @param mixed $default 默认值
-     * @throws \LogicException
-     */
-    public function setDefault($default = null)
-    {
-        if (self::REQUIRED === $this->mode && null !== $default) {
-            throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
-        }
-
-        if ($this->isArray()) {
-            if (null === $default) {
-                $default = [];
-            } elseif (!is_array($default)) {
-                throw new \LogicException('A default value for an array argument must be an array.');
-            }
-        }
-
-        $this->default = $default;
-    }
-
-    /**
-     * 获取默认值
-     * @return mixed
-     */
-    public function getDefault()
-    {
-        return $this->default;
-    }
-
-    /**
-     * 获取描述
-     * @return string
-     */
-    public function getDescription()
-    {
-        return $this->description;
-    }
-}

+ 0 - 375
thinkphp/library/think/console/input/Definition.php

@@ -1,375 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\input;
-
-class Definition
-{
-
-    /**
-     * @var Argument[]
-     */
-    private $arguments;
-
-    private $requiredCount;
-    private $hasAnArrayArgument = false;
-    private $hasOptional;
-
-    /**
-     * @var Option[]
-     */
-    private $options;
-    private $shortcuts;
-
-    /**
-     * 构造方法
-     * @param array $definition
-     * @api
-     */
-    public function __construct(array $definition = [])
-    {
-        $this->setDefinition($definition);
-    }
-
-    /**
-     * 设置指令的定义
-     * @param array $definition 定义的数组
-     */
-    public function setDefinition(array $definition)
-    {
-        $arguments = [];
-        $options   = [];
-        foreach ($definition as $item) {
-            if ($item instanceof Option) {
-                $options[] = $item;
-            } else {
-                $arguments[] = $item;
-            }
-        }
-
-        $this->setArguments($arguments);
-        $this->setOptions($options);
-    }
-
-    /**
-     * 设置参数
-     * @param Argument[] $arguments 参数数组
-     */
-    public function setArguments($arguments = [])
-    {
-        $this->arguments          = [];
-        $this->requiredCount      = 0;
-        $this->hasOptional        = false;
-        $this->hasAnArrayArgument = false;
-        $this->addArguments($arguments);
-    }
-
-    /**
-     * 添加参数
-     * @param Argument[] $arguments 参数数组
-     * @api
-     */
-    public function addArguments($arguments = [])
-    {
-        if (null !== $arguments) {
-            foreach ($arguments as $argument) {
-                $this->addArgument($argument);
-            }
-        }
-    }
-
-    /**
-     * 添加一个参数
-     * @param Argument $argument 参数
-     * @throws \LogicException
-     */
-    public function addArgument(Argument $argument)
-    {
-        if (isset($this->arguments[$argument->getName()])) {
-            throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
-        }
-
-        if ($this->hasAnArrayArgument) {
-            throw new \LogicException('Cannot add an argument after an array argument.');
-        }
-
-        if ($argument->isRequired() && $this->hasOptional) {
-            throw new \LogicException('Cannot add a required argument after an optional one.');
-        }
-
-        if ($argument->isArray()) {
-            $this->hasAnArrayArgument = true;
-        }
-
-        if ($argument->isRequired()) {
-            ++$this->requiredCount;
-        } else {
-            $this->hasOptional = true;
-        }
-
-        $this->arguments[$argument->getName()] = $argument;
-    }
-
-    /**
-     * 根据名称或者位置获取参数
-     * @param string|int $name 参数名或者位置
-     * @return Argument 参数
-     * @throws \InvalidArgumentException
-     */
-    public function getArgument($name)
-    {
-        if (!$this->hasArgument($name)) {
-            throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
-        }
-
-        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
-
-        return $arguments[$name];
-    }
-
-    /**
-     * 根据名称或位置检查是否具有某个参数
-     * @param string|int $name 参数名或者位置
-     * @return bool
-     * @api
-     */
-    public function hasArgument($name)
-    {
-        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
-
-        return isset($arguments[$name]);
-    }
-
-    /**
-     * 获取所有的参数
-     * @return Argument[] 参数数组
-     */
-    public function getArguments()
-    {
-        return $this->arguments;
-    }
-
-    /**
-     * 获取参数数量
-     * @return int
-     */
-    public function getArgumentCount()
-    {
-        return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
-    }
-
-    /**
-     * 获取必填的参数的数量
-     * @return int
-     */
-    public function getArgumentRequiredCount()
-    {
-        return $this->requiredCount;
-    }
-
-    /**
-     * 获取参数默认值
-     * @return array
-     */
-    public function getArgumentDefaults()
-    {
-        $values = [];
-        foreach ($this->arguments as $argument) {
-            $values[$argument->getName()] = $argument->getDefault();
-        }
-
-        return $values;
-    }
-
-    /**
-     * 设置选项
-     * @param Option[] $options 选项数组
-     */
-    public function setOptions($options = [])
-    {
-        $this->options   = [];
-        $this->shortcuts = [];
-        $this->addOptions($options);
-    }
-
-    /**
-     * 添加选项
-     * @param Option[] $options 选项数组
-     * @api
-     */
-    public function addOptions($options = [])
-    {
-        foreach ($options as $option) {
-            $this->addOption($option);
-        }
-    }
-
-    /**
-     * 添加一个选项
-     * @param Option $option 选项
-     * @throws \LogicException
-     * @api
-     */
-    public function addOption(Option $option)
-    {
-        if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
-            throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
-        }
-
-        if ($option->getShortcut()) {
-            foreach (explode('|', $option->getShortcut()) as $shortcut) {
-                if (isset($this->shortcuts[$shortcut])
-                    && !$option->equals($this->options[$this->shortcuts[$shortcut]])
-                ) {
-                    throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
-                }
-            }
-        }
-
-        $this->options[$option->getName()] = $option;
-        if ($option->getShortcut()) {
-            foreach (explode('|', $option->getShortcut()) as $shortcut) {
-                $this->shortcuts[$shortcut] = $option->getName();
-            }
-        }
-    }
-
-    /**
-     * 根据名称获取选项
-     * @param string $name 选项名
-     * @return Option
-     * @throws \InvalidArgumentException
-     * @api
-     */
-    public function getOption($name)
-    {
-        if (!$this->hasOption($name)) {
-            throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
-        }
-
-        return $this->options[$name];
-    }
-
-    /**
-     * 根据名称检查是否有这个选项
-     * @param string $name 选项名
-     * @return bool
-     * @api
-     */
-    public function hasOption($name)
-    {
-        return isset($this->options[$name]);
-    }
-
-    /**
-     * 获取所有选项
-     * @return Option[]
-     * @api
-     */
-    public function getOptions()
-    {
-        return $this->options;
-    }
-
-    /**
-     * 根据名称检查某个选项是否有短名称
-     * @param string $name 短名称
-     * @return bool
-     */
-    public function hasShortcut($name)
-    {
-        return isset($this->shortcuts[$name]);
-    }
-
-    /**
-     * 根据短名称获取选项
-     * @param string $shortcut 短名称
-     * @return Option
-     */
-    public function getOptionForShortcut($shortcut)
-    {
-        return $this->getOption($this->shortcutToName($shortcut));
-    }
-
-    /**
-     * 获取所有选项的默认值
-     * @return array
-     */
-    public function getOptionDefaults()
-    {
-        $values = [];
-        foreach ($this->options as $option) {
-            $values[$option->getName()] = $option->getDefault();
-        }
-
-        return $values;
-    }
-
-    /**
-     * 根据短名称获取选项名
-     * @param string $shortcut 短名称
-     * @return string
-     * @throws \InvalidArgumentException
-     */
-    private function shortcutToName($shortcut)
-    {
-        if (!isset($this->shortcuts[$shortcut])) {
-            throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
-        }
-
-        return $this->shortcuts[$shortcut];
-    }
-
-    /**
-     * 获取该指令的介绍
-     * @param bool $short 是否简洁介绍
-     * @return string
-     */
-    public function getSynopsis($short = false)
-    {
-        $elements = [];
-
-        if ($short && $this->getOptions()) {
-            $elements[] = '[options]';
-        } elseif (!$short) {
-            foreach ($this->getOptions() as $option) {
-                $value = '';
-                if ($option->acceptValue()) {
-                    $value = sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', strtoupper($option->getName()), $option->isValueOptional() ? ']' : '');
-                }
-
-                $shortcut   = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
-                $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
-            }
-        }
-
-        if (count($elements) && $this->getArguments()) {
-            $elements[] = '[--]';
-        }
-
-        foreach ($this->getArguments() as $argument) {
-            $element = '<' . $argument->getName() . '>';
-            if (!$argument->isRequired()) {
-                $element = '[' . $element . ']';
-            } elseif ($argument->isArray()) {
-                $element .= ' (' . $element . ')';
-            }
-
-            if ($argument->isArray()) {
-                $element .= '...';
-            }
-
-            $elements[] = $element;
-        }
-
-        return implode(' ', $elements);
-    }
-}

+ 0 - 190
thinkphp/library/think/console/input/Option.php

@@ -1,190 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\input;
-
-class Option
-{
-
-    const VALUE_NONE     = 1;
-    const VALUE_REQUIRED = 2;
-    const VALUE_OPTIONAL = 4;
-    const VALUE_IS_ARRAY = 8;
-
-    private $name;
-    private $shortcut;
-    private $mode;
-    private $default;
-    private $description;
-
-    /**
-     * 构造方法
-     * @param string       $name        选项名
-     * @param string|array $shortcut    短名称,多个用|隔开或者使用数组
-     * @param int          $mode        选项类型(可选类型为 self::VALUE_*)
-     * @param string       $description 描述
-     * @param mixed        $default     默认值 (类型为 self::VALUE_REQUIRED 或者 self::VALUE_NONE 的时候必须为null)
-     * @throws \InvalidArgumentException
-     */
-    public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
-    {
-        if (0 === strpos($name, '--')) {
-            $name = substr($name, 2);
-        }
-
-        if (empty($name)) {
-            throw new \InvalidArgumentException('An option name cannot be empty.');
-        }
-
-        if (empty($shortcut)) {
-            $shortcut = null;
-        }
-
-        if (null !== $shortcut) {
-            if (is_array($shortcut)) {
-                $shortcut = implode('|', $shortcut);
-            }
-            $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
-            $shortcuts = array_filter($shortcuts);
-            $shortcut  = implode('|', $shortcuts);
-
-            if (empty($shortcut)) {
-                throw new \InvalidArgumentException('An option shortcut cannot be empty.');
-            }
-        }
-
-        if (null === $mode) {
-            $mode = self::VALUE_NONE;
-        } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
-            throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
-        }
-
-        $this->name        = $name;
-        $this->shortcut    = $shortcut;
-        $this->mode        = $mode;
-        $this->description = $description;
-
-        if ($this->isArray() && !$this->acceptValue()) {
-            throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
-        }
-
-        $this->setDefault($default);
-    }
-
-    /**
-     * 获取短名称
-     * @return string
-     */
-    public function getShortcut()
-    {
-        return $this->shortcut;
-    }
-
-    /**
-     * 获取选项名
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * 是否可以设置值
-     * @return bool 类型不是 self::VALUE_NONE 的时候返回true,其他均返回false
-     */
-    public function acceptValue()
-    {
-        return $this->isValueRequired() || $this->isValueOptional();
-    }
-
-    /**
-     * 是否必须
-     * @return bool 类型是 self::VALUE_REQUIRED 的时候返回true,其他均返回false
-     */
-    public function isValueRequired()
-    {
-        return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
-    }
-
-    /**
-     * 是否可选
-     * @return bool 类型是 self::VALUE_OPTIONAL 的时候返回true,其他均返回false
-     */
-    public function isValueOptional()
-    {
-        return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
-    }
-
-    /**
-     * 选项值是否接受数组
-     * @return bool 类型是 self::VALUE_IS_ARRAY 的时候返回true,其他均返回false
-     */
-    public function isArray()
-    {
-        return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
-    }
-
-    /**
-     * 设置默认值
-     * @param mixed $default 默认值
-     * @throws \LogicException
-     */
-    public function setDefault($default = null)
-    {
-        if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
-            throw new \LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
-        }
-
-        if ($this->isArray()) {
-            if (null === $default) {
-                $default = [];
-            } elseif (!is_array($default)) {
-                throw new \LogicException('A default value for an array option must be an array.');
-            }
-        }
-
-        $this->default = $this->acceptValue() ? $default : false;
-    }
-
-    /**
-     * 获取默认值
-     * @return mixed
-     */
-    public function getDefault()
-    {
-        return $this->default;
-    }
-
-    /**
-     * 获取描述文字
-     * @return string
-     */
-    public function getDescription()
-    {
-        return $this->description;
-    }
-
-    /**
-     * 检查所给选项是否是当前这个
-     * @param Option $option
-     * @return bool
-     */
-    public function equals(Option $option)
-    {
-        return $option->getName() === $this->getName()
-        && $option->getShortcut() === $this->getShortcut()
-        && $option->getDefault() === $this->getDefault()
-        && $option->isArray() === $this->isArray()
-        && $option->isValueRequired() === $this->isValueRequired()
-        && $option->isValueOptional() === $this->isValueOptional();
-    }
-}

+ 0 - 340
thinkphp/library/think/console/output/Ask.php

@@ -1,340 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output;
-
-use think\console\Input;
-use think\console\Output;
-use think\console\output\question\Choice;
-use think\console\output\question\Confirmation;
-
-class Ask
-{
-    private static $stty;
-
-    private static $shell;
-
-    /** @var  Input */
-    protected $input;
-
-    /** @var  Output */
-    protected $output;
-
-    /** @var  Question */
-    protected $question;
-
-    public function __construct(Input $input, Output $output, Question $question)
-    {
-        $this->input    = $input;
-        $this->output   = $output;
-        $this->question = $question;
-    }
-
-    public function run()
-    {
-        if (!$this->input->isInteractive()) {
-            return $this->question->getDefault();
-        }
-
-        if (!$this->question->getValidator()) {
-            return $this->doAsk();
-        }
-
-        $that = $this;
-
-        $interviewer = function () use ($that) {
-            return $that->doAsk();
-        };
-
-        return $this->validateAttempts($interviewer);
-    }
-
-    protected function doAsk()
-    {
-        $this->writePrompt();
-
-        $inputStream  = STDIN;
-        $autocomplete = $this->question->getAutocompleterValues();
-
-        if (null === $autocomplete || !$this->hasSttyAvailable()) {
-            $ret = false;
-            if ($this->question->isHidden()) {
-                try {
-                    $ret = trim($this->getHiddenResponse($inputStream));
-                } catch (\RuntimeException $e) {
-                    if (!$this->question->isHiddenFallback()) {
-                        throw $e;
-                    }
-                }
-            }
-
-            if (false === $ret) {
-                $ret = fgets($inputStream, 4096);
-                if (false === $ret) {
-                    throw new \RuntimeException('Aborted');
-                }
-                $ret = trim($ret);
-            }
-        } else {
-            $ret = trim($this->autocomplete($inputStream));
-        }
-
-        $ret = strlen($ret) > 0 ? $ret : $this->question->getDefault();
-
-        if ($normalizer = $this->question->getNormalizer()) {
-            return $normalizer($ret);
-        }
-
-        return $ret;
-    }
-
-    private function autocomplete($inputStream)
-    {
-        $autocomplete = $this->question->getAutocompleterValues();
-        $ret          = '';
-
-        $i          = 0;
-        $ofs        = -1;
-        $matches    = $autocomplete;
-        $numMatches = count($matches);
-
-        $sttyMode = shell_exec('stty -g');
-
-        shell_exec('stty -icanon -echo');
-
-        while (!feof($inputStream)) {
-            $c = fread($inputStream, 1);
-
-            if ("\177" === $c) {
-                if (0 === $numMatches && 0 !== $i) {
-                    --$i;
-                    $this->output->write("\033[1D");
-                }
-
-                if ($i === 0) {
-                    $ofs        = -1;
-                    $matches    = $autocomplete;
-                    $numMatches = count($matches);
-                } else {
-                    $numMatches = 0;
-                }
-
-                $ret = substr($ret, 0, $i);
-            } elseif ("\033" === $c) {
-                $c .= fread($inputStream, 2);
-
-                if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
-                    if ('A' === $c[2] && -1 === $ofs) {
-                        $ofs = 0;
-                    }
-
-                    if (0 === $numMatches) {
-                        continue;
-                    }
-
-                    $ofs += ('A' === $c[2]) ? -1 : 1;
-                    $ofs = ($numMatches + $ofs) % $numMatches;
-                }
-            } elseif (ord($c) < 32) {
-                if ("\t" === $c || "\n" === $c) {
-                    if ($numMatches > 0 && -1 !== $ofs) {
-                        $ret = $matches[$ofs];
-                        $this->output->write(substr($ret, $i));
-                        $i = strlen($ret);
-                    }
-
-                    if ("\n" === $c) {
-                        $this->output->write($c);
-                        break;
-                    }
-
-                    $numMatches = 0;
-                }
-
-                continue;
-            } else {
-                $this->output->write($c);
-                $ret .= $c;
-                ++$i;
-
-                $numMatches = 0;
-                $ofs        = 0;
-
-                foreach ($autocomplete as $value) {
-                    if (0 === strpos($value, $ret) && $i !== strlen($value)) {
-                        $matches[$numMatches++] = $value;
-                    }
-                }
-            }
-
-            $this->output->write("\033[K");
-
-            if ($numMatches > 0 && -1 !== $ofs) {
-                $this->output->write("\0337");
-                $this->output->highlight(substr($matches[$ofs], $i));
-                $this->output->write("\0338");
-            }
-        }
-
-        shell_exec(sprintf('stty %s', $sttyMode));
-
-        return $ret;
-    }
-
-    protected function getHiddenResponse($inputStream)
-    {
-        if ('\\' === DIRECTORY_SEPARATOR) {
-            $exe = __DIR__ . '/../bin/hiddeninput.exe';
-
-            $value = rtrim(shell_exec($exe));
-            $this->output->writeln('');
-
-            if (isset($tmpExe)) {
-                unlink($tmpExe);
-            }
-
-            return $value;
-        }
-
-        if ($this->hasSttyAvailable()) {
-            $sttyMode = shell_exec('stty -g');
-
-            shell_exec('stty -echo');
-            $value = fgets($inputStream, 4096);
-            shell_exec(sprintf('stty %s', $sttyMode));
-
-            if (false === $value) {
-                throw new \RuntimeException('Aborted');
-            }
-
-            $value = trim($value);
-            $this->output->writeln('');
-
-            return $value;
-        }
-
-        if (false !== $shell = $this->getShell()) {
-            $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
-            $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
-            $value   = rtrim(shell_exec($command));
-            $this->output->writeln('');
-
-            return $value;
-        }
-
-        throw new \RuntimeException('Unable to hide the response.');
-    }
-
-    protected function validateAttempts($interviewer)
-    {
-        /** @var \Exception $error */
-        $error    = null;
-        $attempts = $this->question->getMaxAttempts();
-        while (null === $attempts || $attempts--) {
-            if (null !== $error) {
-                $this->output->error($error->getMessage());
-            }
-
-            try {
-                return call_user_func($this->question->getValidator(), $interviewer());
-            } catch (\Exception $error) {
-            }
-        }
-
-        throw $error;
-    }
-
-    /**
-     * 显示问题的提示信息
-     */
-    protected function writePrompt()
-    {
-        $text    = $this->question->getQuestion();
-        $default = $this->question->getDefault();
-
-        switch (true) {
-            case null === $default:
-                $text = sprintf(' <info>%s</info>:', $text);
-
-                break;
-
-            case $this->question instanceof Confirmation:
-                $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');
-
-                break;
-
-            case $this->question instanceof Choice && $this->question->isMultiselect():
-                $choices = $this->question->getChoices();
-                $default = explode(',', $default);
-
-                foreach ($default as $key => $value) {
-                    $default[$key] = $choices[trim($value)];
-                }
-
-                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, implode(', ', $default));
-
-                break;
-
-            case $this->question instanceof Choice:
-                $choices = $this->question->getChoices();
-                $text    = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $choices[$default]);
-
-                break;
-
-            default:
-                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $default);
-        }
-
-        $this->output->writeln($text);
-
-        if ($this->question instanceof Choice) {
-            $width = max(array_map('strlen', array_keys($this->question->getChoices())));
-
-            foreach ($this->question->getChoices() as $key => $value) {
-                $this->output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value));
-            }
-        }
-
-        $this->output->write(' > ');
-    }
-
-    private function getShell()
-    {
-        if (null !== self::$shell) {
-            return self::$shell;
-        }
-
-        self::$shell = false;
-
-        if (file_exists('/usr/bin/env')) {
-            $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
-            foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) {
-                if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
-                    self::$shell = $sh;
-                    break;
-                }
-            }
-        }
-
-        return self::$shell;
-    }
-
-    private function hasSttyAvailable()
-    {
-        if (null !== self::$stty) {
-            return self::$stty;
-        }
-
-        exec('stty 2>&1', $output, $exitcode);
-
-        return self::$stty = $exitcode === 0;
-    }
-}

+ 0 - 319
thinkphp/library/think/console/output/Descriptor.php

@@ -1,319 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output;
-
-use think\Console;
-use think\console\Command;
-use think\console\input\Argument as InputArgument;
-use think\console\input\Definition as InputDefinition;
-use think\console\input\Option as InputOption;
-use think\console\Output;
-use think\console\output\descriptor\Console as ConsoleDescription;
-
-class Descriptor
-{
-
-    /**
-     * @var Output
-     */
-    protected $output;
-
-    /**
-     * {@inheritdoc}
-     */
-    public function describe(Output $output, $object, array $options = [])
-    {
-        $this->output = $output;
-
-        switch (true) {
-            case $object instanceof InputArgument:
-                $this->describeInputArgument($object, $options);
-                break;
-            case $object instanceof InputOption:
-                $this->describeInputOption($object, $options);
-                break;
-            case $object instanceof InputDefinition:
-                $this->describeInputDefinition($object, $options);
-                break;
-            case $object instanceof Command:
-                $this->describeCommand($object, $options);
-                break;
-            case $object instanceof Console:
-                $this->describeConsole($object, $options);
-                break;
-            default:
-                throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
-        }
-    }
-
-    /**
-     * 输出内容
-     * @param string $content
-     * @param bool   $decorated
-     */
-    protected function write($content, $decorated = false)
-    {
-        $this->output->write($content, false, $decorated ? Output::OUTPUT_NORMAL : Output::OUTPUT_RAW);
-    }
-
-    /**
-     * 描述参数
-     * @param InputArgument $argument
-     * @param array         $options
-     * @return string|mixed
-     */
-    protected function describeInputArgument(InputArgument $argument, array $options = [])
-    {
-        if (null !== $argument->getDefault()
-            && (!is_array($argument->getDefault())
-                || count($argument->getDefault()))
-        ) {
-            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
-        } else {
-            $default = '';
-        }
-
-        $totalWidth   = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
-        $spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
-
-        $this->writeText(sprintf("  <info>%s</info>%s%s%s", $argument->getName(), str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + <info> + </info> + 2 spaces
-            preg_replace('/\s*\R\s*/', PHP_EOL . str_repeat(' ', $totalWidth + 17), $argument->getDescription()), $default), $options);
-    }
-
-    /**
-     * 描述选项
-     * @param InputOption $option
-     * @param array       $options
-     * @return string|mixed
-     */
-    protected function describeInputOption(InputOption $option, array $options = [])
-    {
-        if ($option->acceptValue() && null !== $option->getDefault()
-            && (!is_array($option->getDefault())
-                || count($option->getDefault()))
-        ) {
-            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
-        } else {
-            $default = '';
-        }
-
-        $value = '';
-        if ($option->acceptValue()) {
-            $value = '=' . strtoupper($option->getName());
-
-            if ($option->isValueOptional()) {
-                $value = '[' . $value . ']';
-            }
-        }
-
-        $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]);
-        $synopsis   = sprintf('%s%s', $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ', sprintf('--%s%s', $option->getName(), $value));
-
-        $spacingWidth = $totalWidth - strlen($synopsis) + 2;
-
-        $this->writeText(sprintf("  <info>%s</info>%s%s%s%s", $synopsis, str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + <info> + </info> + 2 spaces
-            preg_replace('/\s*\R\s*/', "\n" . str_repeat(' ', $totalWidth + 17), $option->getDescription()), $default, $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''), $options);
-    }
-
-    /**
-     * 描述输入
-     * @param InputDefinition $definition
-     * @param array           $options
-     * @return string|mixed
-     */
-    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
-    {
-        $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
-        foreach ($definition->getArguments() as $argument) {
-            $totalWidth = max($totalWidth, strlen($argument->getName()));
-        }
-
-        if ($definition->getArguments()) {
-            $this->writeText('<comment>Arguments:</comment>', $options);
-            $this->writeText("\n");
-            foreach ($definition->getArguments() as $argument) {
-                $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth]));
-                $this->writeText("\n");
-            }
-        }
-
-        if ($definition->getArguments() && $definition->getOptions()) {
-            $this->writeText("\n");
-        }
-
-        if ($definition->getOptions()) {
-            $laterOptions = [];
-
-            $this->writeText('<comment>Options:</comment>', $options);
-            foreach ($definition->getOptions() as $option) {
-                if (strlen($option->getShortcut()) > 1) {
-                    $laterOptions[] = $option;
-                    continue;
-                }
-                $this->writeText("\n");
-                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
-            }
-            foreach ($laterOptions as $option) {
-                $this->writeText("\n");
-                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
-            }
-        }
-    }
-
-    /**
-     * 描述指令
-     * @param Command $command
-     * @param array   $options
-     * @return string|mixed
-     */
-    protected function describeCommand(Command $command, array $options = [])
-    {
-        $command->getSynopsis(true);
-        $command->getSynopsis(false);
-        $command->mergeConsoleDefinition(false);
-
-        $this->writeText('<comment>Usage:</comment>', $options);
-        foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) {
-            $this->writeText("\n");
-            $this->writeText('  ' . $usage, $options);
-        }
-        $this->writeText("\n");
-
-        $definition = $command->getNativeDefinition();
-        if ($definition->getOptions() || $definition->getArguments()) {
-            $this->writeText("\n");
-            $this->describeInputDefinition($definition, $options);
-            $this->writeText("\n");
-        }
-
-        if ($help = $command->getProcessedHelp()) {
-            $this->writeText("\n");
-            $this->writeText('<comment>Help:</comment>', $options);
-            $this->writeText("\n");
-            $this->writeText(' ' . str_replace("\n", "\n ", $help), $options);
-            $this->writeText("\n");
-        }
-    }
-
-    /**
-     * 描述控制台
-     * @param Console $console
-     * @param array   $options
-     * @return string|mixed
-     */
-    protected function describeConsole(Console $console, array $options = [])
-    {
-        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
-        $description        = new ConsoleDescription($console, $describedNamespace);
-
-        if (isset($options['raw_text']) && $options['raw_text']) {
-            $width = $this->getColumnWidth($description->getCommands());
-
-            foreach ($description->getCommands() as $command) {
-                $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options);
-                $this->writeText("\n");
-            }
-        } else {
-            if ('' != $help = $console->getHelp()) {
-                $this->writeText("$help\n\n", $options);
-            }
-
-            $this->writeText("<comment>Usage:</comment>\n", $options);
-            $this->writeText("  command [options] [arguments]\n\n", $options);
-
-            $this->describeInputDefinition(new InputDefinition($console->getDefinition()->getOptions()), $options);
-
-            $this->writeText("\n");
-            $this->writeText("\n");
-
-            $width = $this->getColumnWidth($description->getCommands());
-
-            if ($describedNamespace) {
-                $this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
-            } else {
-                $this->writeText('<comment>Available commands:</comment>', $options);
-            }
-
-            // add commands by namespace
-            foreach ($description->getNamespaces() as $namespace) {
-                if (!$describedNamespace && ConsoleDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
-                    $this->writeText("\n");
-                    $this->writeText(' <comment>' . $namespace['id'] . '</comment>', $options);
-                }
-
-                foreach ($namespace['commands'] as $name) {
-                    $this->writeText("\n");
-                    $spacingWidth = $width - strlen($name);
-                    $this->writeText(sprintf("  <info>%s</info>%s%s", $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)
-                            ->getDescription()), $options);
-                }
-            }
-
-            $this->writeText("\n");
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    private function writeText($content, array $options = [])
-    {
-        $this->write(isset($options['raw_text'])
-            && $options['raw_text'] ? strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : true);
-    }
-
-    /**
-     * 格式化
-     * @param mixed $default
-     * @return string
-     */
-    private function formatDefaultValue($default)
-    {
-        return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
-    }
-
-    /**
-     * @param Command[] $commands
-     * @return int
-     */
-    private function getColumnWidth(array $commands)
-    {
-        $width = 0;
-        foreach ($commands as $command) {
-            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
-        }
-
-        return $width + 2;
-    }
-
-    /**
-     * @param InputOption[] $options
-     * @return int
-     */
-    private function calculateTotalWidthForOptions($options)
-    {
-        $totalWidth = 0;
-        foreach ($options as $option) {
-            $nameLength = 4 + strlen($option->getName()) + 2; // - + shortcut + , + whitespace + name + --
-
-            if ($option->acceptValue()) {
-                $valueLength = 1 + strlen($option->getName()); // = + value
-                $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]
-
-                $nameLength += $valueLength;
-            }
-            $totalWidth = max($totalWidth, $nameLength);
-        }
-
-        return $totalWidth;
-    }
-}

+ 0 - 198
thinkphp/library/think/console/output/Formatter.php

@@ -1,198 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-namespace think\console\output;
-
-use think\console\output\formatter\Stack as StyleStack;
-use think\console\output\formatter\Style;
-
-class Formatter
-{
-
-    private $decorated = false;
-    private $styles    = [];
-    private $styleStack;
-
-    /**
-     * 转义
-     * @param string $text
-     * @return string
-     */
-    public static function escape($text)
-    {
-        return preg_replace('/([^\\\\]?)</is', '$1\\<', $text);
-    }
-
-    /**
-     * 初始化命令行输出格式
-     */
-    public function __construct()
-    {
-        $this->setStyle('error', new Style('white', 'red'));
-        $this->setStyle('info', new Style('green'));
-        $this->setStyle('comment', new Style('yellow'));
-        $this->setStyle('question', new Style('black', 'cyan'));
-        $this->setStyle('highlight', new Style('red'));
-        $this->setStyle('warning', new Style('black', 'yellow'));
-
-        $this->styleStack = new StyleStack();
-    }
-
-    /**
-     * 设置外观标识
-     * @param bool $decorated 是否美化文字
-     */
-    public function setDecorated($decorated)
-    {
-        $this->decorated = (bool) $decorated;
-    }
-
-    /**
-     * 获取外观标识
-     * @return bool
-     */
-    public function isDecorated()
-    {
-        return $this->decorated;
-    }
-
-    /**
-     * 添加一个新样式
-     * @param string $name  样式名
-     * @param Style  $style 样式实例
-     */
-    public function setStyle($name, Style $style)
-    {
-        $this->styles[strtolower($name)] = $style;
-    }
-
-    /**
-     * 是否有这个样式
-     * @param string $name
-     * @return bool
-     */
-    public function hasStyle($name)
-    {
-        return isset($this->styles[strtolower($name)]);
-    }
-
-    /**
-     * 获取样式
-     * @param string $name
-     * @return Style
-     * @throws \InvalidArgumentException
-     */
-    public function getStyle($name)
-    {
-        if (!$this->hasStyle($name)) {
-            throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name));
-        }
-
-        return $this->styles[strtolower($name)];
-    }
-
-    /**
-     * 使用所给的样式格式化文字
-     * @param string $message 文字
-     * @return string
-     */
-    public function format($message)
-    {
-        $offset   = 0;
-        $output   = '';
-        $tagRegex = '[a-z][a-z0-9_=;-]*';
-        preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE);
-        foreach ($matches[0] as $i => $match) {
-            $pos  = $match[1];
-            $text = $match[0];
-
-            if (0 != $pos && '\\' == $message[$pos - 1]) {
-                continue;
-            }
-
-            $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
-            $offset = $pos + strlen($text);
-
-            if ($open = '/' != $text[1]) {
-                $tag = $matches[1][$i][0];
-            } else {
-                $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
-            }
-
-            if (!$open && !$tag) {
-                // </>
-                $this->styleStack->pop();
-            } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
-                $output .= $this->applyCurrentStyle($text);
-            } elseif ($open) {
-                $this->styleStack->push($style);
-            } else {
-                $this->styleStack->pop($style);
-            }
-        }
-
-        $output .= $this->applyCurrentStyle(substr($message, $offset));
-
-        return str_replace('\\<', '<', $output);
-    }
-
-    /**
-     * @return StyleStack
-     */
-    public function getStyleStack()
-    {
-        return $this->styleStack;
-    }
-
-    /**
-     * 根据字符串创建新的样式实例
-     * @param string $string
-     * @return Style|bool
-     */
-    private function createStyleFromString($string)
-    {
-        if (isset($this->styles[$string])) {
-            return $this->styles[$string];
-        }
-
-        if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
-            return false;
-        }
-
-        $style = new Style();
-        foreach ($matches as $match) {
-            array_shift($match);
-
-            if ('fg' == $match[0]) {
-                $style->setForeground($match[1]);
-            } elseif ('bg' == $match[0]) {
-                $style->setBackground($match[1]);
-            } else {
-                try {
-                    $style->setOption($match[1]);
-                } catch (\InvalidArgumentException $e) {
-                    return false;
-                }
-            }
-        }
-
-        return $style;
-    }
-
-    /**
-     * 从堆栈应用样式到文字
-     * @param string $text 文字
-     * @return string
-     */
-    private function applyCurrentStyle($text)
-    {
-        return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
-    }
-}

+ 0 - 211
thinkphp/library/think/console/output/Question.php

@@ -1,211 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output;
-
-class Question
-{
-
-    private $question;
-    private $attempts;
-    private $hidden         = false;
-    private $hiddenFallback = true;
-    private $autocompleterValues;
-    private $validator;
-    private $default;
-    private $normalizer;
-
-    /**
-     * 构造方法
-     * @param string $question 问题
-     * @param mixed  $default  默认答案
-     */
-    public function __construct($question, $default = null)
-    {
-        $this->question = $question;
-        $this->default  = $default;
-    }
-
-    /**
-     * 获取问题
-     * @return string
-     */
-    public function getQuestion()
-    {
-        return $this->question;
-    }
-
-    /**
-     * 获取默认答案
-     * @return mixed
-     */
-    public function getDefault()
-    {
-        return $this->default;
-    }
-
-    /**
-     * 是否隐藏答案
-     * @return bool
-     */
-    public function isHidden()
-    {
-        return $this->hidden;
-    }
-
-    /**
-     * 隐藏答案
-     * @param bool $hidden
-     * @return Question
-     */
-    public function setHidden($hidden)
-    {
-        if ($this->autocompleterValues) {
-            throw new \LogicException('A hidden question cannot use the autocompleter.');
-        }
-
-        $this->hidden = (bool) $hidden;
-
-        return $this;
-    }
-
-    /**
-     * 不能被隐藏是否撤销
-     * @return bool
-     */
-    public function isHiddenFallback()
-    {
-        return $this->hiddenFallback;
-    }
-
-    /**
-     * 设置不能被隐藏的时候的操作
-     * @param bool $fallback
-     * @return Question
-     */
-    public function setHiddenFallback($fallback)
-    {
-        $this->hiddenFallback = (bool) $fallback;
-
-        return $this;
-    }
-
-    /**
-     * 获取自动完成
-     * @return null|array|\Traversable
-     */
-    public function getAutocompleterValues()
-    {
-        return $this->autocompleterValues;
-    }
-
-    /**
-     * 设置自动完成的值
-     * @param null|array|\Traversable $values
-     * @return Question
-     * @throws \InvalidArgumentException
-     * @throws \LogicException
-     */
-    public function setAutocompleterValues($values)
-    {
-        if (is_array($values) && $this->isAssoc($values)) {
-            $values = array_merge(array_keys($values), array_values($values));
-        }
-
-        if (null !== $values && !is_array($values)) {
-            if (!$values instanceof \Traversable || $values instanceof \Countable) {
-                throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
-            }
-        }
-
-        if ($this->hidden) {
-            throw new \LogicException('A hidden question cannot use the autocompleter.');
-        }
-
-        $this->autocompleterValues = $values;
-
-        return $this;
-    }
-
-    /**
-     * 设置答案的验证器
-     * @param null|callable $validator
-     * @return Question The current instance
-     */
-    public function setValidator($validator)
-    {
-        $this->validator = $validator;
-
-        return $this;
-    }
-
-    /**
-     * 获取验证器
-     * @return null|callable
-     */
-    public function getValidator()
-    {
-        return $this->validator;
-    }
-
-    /**
-     * 设置最大重试次数
-     * @param null|int $attempts
-     * @return Question
-     * @throws \InvalidArgumentException
-     */
-    public function setMaxAttempts($attempts)
-    {
-        if (null !== $attempts && $attempts < 1) {
-            throw new \InvalidArgumentException('Maximum number of attempts must be a positive value.');
-        }
-
-        $this->attempts = $attempts;
-
-        return $this;
-    }
-
-    /**
-     * 获取最大重试次数
-     * @return null|int
-     */
-    public function getMaxAttempts()
-    {
-        return $this->attempts;
-    }
-
-    /**
-     * 设置响应的回调
-     * @param string|\Closure $normalizer
-     * @return Question
-     */
-    public function setNormalizer($normalizer)
-    {
-        $this->normalizer = $normalizer;
-
-        return $this;
-    }
-
-    /**
-     * 获取响应回调
-     * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
-     * @return string|\Closure
-     */
-    public function getNormalizer()
-    {
-        return $this->normalizer;
-    }
-
-    protected function isAssoc($array)
-    {
-        return (bool) count(array_filter(array_keys($array), 'is_string'));
-    }
-}

+ 0 - 149
thinkphp/library/think/console/output/descriptor/Console.php

@@ -1,149 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\descriptor;
-
-use think\Console as ThinkConsole;
-use think\console\Command;
-
-class Console
-{
-
-    const GLOBAL_NAMESPACE = '_global';
-
-    /**
-     * @var ThinkConsole
-     */
-    private $console;
-
-    /**
-     * @var null|string
-     */
-    private $namespace;
-
-    /**
-     * @var array
-     */
-    private $namespaces;
-
-    /**
-     * @var Command[]
-     */
-    private $commands;
-
-    /**
-     * @var Command[]
-     */
-    private $aliases;
-
-    /**
-     * 构造方法
-     * @param ThinkConsole $console
-     * @param string|null  $namespace
-     */
-    public function __construct(ThinkConsole $console, $namespace = null)
-    {
-        $this->console   = $console;
-        $this->namespace = $namespace;
-    }
-
-    /**
-     * @return array
-     */
-    public function getNamespaces()
-    {
-        if (null === $this->namespaces) {
-            $this->inspectConsole();
-        }
-
-        return $this->namespaces;
-    }
-
-    /**
-     * @return Command[]
-     */
-    public function getCommands()
-    {
-        if (null === $this->commands) {
-            $this->inspectConsole();
-        }
-
-        return $this->commands;
-    }
-
-    /**
-     * @param string $name
-     * @return Command
-     * @throws \InvalidArgumentException
-     */
-    public function getCommand($name)
-    {
-        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
-            throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name));
-        }
-
-        return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
-    }
-
-    private function inspectConsole()
-    {
-        $this->commands   = [];
-        $this->namespaces = [];
-
-        $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null);
-        foreach ($this->sortCommands($all) as $namespace => $commands) {
-            $names = [];
-
-            /** @var Command $command */
-            foreach ($commands as $name => $command) {
-                if (!$command->getName()) {
-                    continue;
-                }
-
-                if ($command->getName() === $name) {
-                    $this->commands[$name] = $command;
-                } else {
-                    $this->aliases[$name] = $command;
-                }
-
-                $names[] = $name;
-            }
-
-            $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
-        }
-    }
-
-    /**
-     * @param array $commands
-     * @return array
-     */
-    private function sortCommands(array $commands)
-    {
-        $namespacedCommands = [];
-        foreach ($commands as $name => $command) {
-            $key = $this->console->extractNamespace($name, 1);
-            if (!$key) {
-                $key = self::GLOBAL_NAMESPACE;
-            }
-
-            $namespacedCommands[$key][$name] = $command;
-        }
-        ksort($namespacedCommands);
-
-        foreach ($namespacedCommands as &$commandsSet) {
-            ksort($commandsSet);
-        }
-        // unset reference to keep scope clear
-        unset($commandsSet);
-
-        return $namespacedCommands;
-    }
-}

+ 0 - 52
thinkphp/library/think/console/output/driver/Buffer.php

@@ -1,52 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\driver;
-
-use think\console\Output;
-
-class Buffer
-{
-    /**
-     * @var string
-     */
-    private $buffer = '';
-
-    public function __construct(Output $output)
-    {
-        // do nothing
-    }
-
-    public function fetch()
-    {
-        $content      = $this->buffer;
-        $this->buffer = '';
-        return $content;
-    }
-
-    public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL)
-    {
-        $messages = (array) $messages;
-
-        foreach ($messages as $message) {
-            $this->buffer .= $message;
-        }
-        if ($newline) {
-            $this->buffer .= "\n";
-        }
-    }
-
-    public function renderException(\Exception $e)
-    {
-        // do nothing
-    }
-
-}

+ 0 - 368
thinkphp/library/think/console/output/driver/Console.php

@@ -1,368 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\driver;
-
-use think\console\Output;
-use think\console\output\Formatter;
-
-class Console
-{
-
-    /** @var  Resource */
-    private $stdout;
-
-    /** @var  Formatter */
-    private $formatter;
-
-    private $terminalDimensions;
-
-    /** @var  Output */
-    private $output;
-
-    public function __construct(Output $output)
-    {
-        $this->output    = $output;
-        $this->formatter = new Formatter();
-        $this->stdout    = $this->openOutputStream();
-        $decorated       = $this->hasColorSupport($this->stdout);
-        $this->formatter->setDecorated($decorated);
-    }
-
-    public function setDecorated($decorated)
-    {
-        $this->formatter->setDecorated($decorated);
-    }
-
-    public function write($messages, $newline = false, $type = Output::OUTPUT_NORMAL, $stream = null)
-    {
-        if (Output::VERBOSITY_QUIET === $this->output->getVerbosity()) {
-            return;
-        }
-
-        $messages = (array) $messages;
-
-        foreach ($messages as $message) {
-            switch ($type) {
-                case Output::OUTPUT_NORMAL:
-                    $message = $this->formatter->format($message);
-                    break;
-                case Output::OUTPUT_RAW:
-                    break;
-                case Output::OUTPUT_PLAIN:
-                    $message = strip_tags($this->formatter->format($message));
-                    break;
-                default:
-                    throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));
-            }
-
-            $this->doWrite($message, $newline, $stream);
-        }
-    }
-
-    public function renderException(\Exception $e)
-    {
-        $stderr    = $this->openErrorStream();
-        $decorated = $this->hasColorSupport($stderr);
-        $this->formatter->setDecorated($decorated);
-
-        do {
-            $title = sprintf('  [%s]  ', get_class($e));
-
-            $len = $this->stringWidth($title);
-
-            $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
-
-            if (defined('HHVM_VERSION') && $width > 1 << 31) {
-                $width = 1 << 31;
-            }
-            $lines = [];
-            foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
-                foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
-
-                    $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $line)) + 4;
-                    $lines[]    = [$line, $lineLength];
-
-                    $len = max($lineLength, $len);
-                }
-            }
-
-            $messages   = ['', ''];
-            $messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));
-            $messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title))));
-            foreach ($lines as $line) {
-                $messages[] = sprintf('<error>  %s  %s</error>', $line[0], str_repeat(' ', $len - $line[1]));
-            }
-            $messages[] = $emptyLine;
-            $messages[] = '';
-            $messages[] = '';
-
-            $this->write($messages, true, Output::OUTPUT_NORMAL, $stderr);
-
-            if (Output::VERBOSITY_VERBOSE <= $this->output->getVerbosity()) {
-                $this->write('<comment>Exception trace:</comment>', true, Output::OUTPUT_NORMAL, $stderr);
-
-                // exception related properties
-                $trace = $e->getTrace();
-                array_unshift($trace, [
-                    'function' => '',
-                    'file'     => $e->getFile() !== null ? $e->getFile() : 'n/a',
-                    'line'     => $e->getLine() !== null ? $e->getLine() : 'n/a',
-                    'args'     => [],
-                ]);
-
-                for ($i = 0, $count = count($trace); $i < $count; ++$i) {
-                    $class    = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
-                    $type     = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
-                    $function = $trace[$i]['function'];
-                    $file     = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
-                    $line     = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
-
-                    $this->write(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line), true, Output::OUTPUT_NORMAL, $stderr);
-                }
-
-                $this->write('', true, Output::OUTPUT_NORMAL, $stderr);
-                $this->write('', true, Output::OUTPUT_NORMAL, $stderr);
-            }
-        } while ($e = $e->getPrevious());
-
-    }
-
-    /**
-     * 获取终端宽度
-     * @return int|null
-     */
-    protected function getTerminalWidth()
-    {
-        $dimensions = $this->getTerminalDimensions();
-
-        return $dimensions[0];
-    }
-
-    /**
-     * 获取终端高度
-     * @return int|null
-     */
-    protected function getTerminalHeight()
-    {
-        $dimensions = $this->getTerminalDimensions();
-
-        return $dimensions[1];
-    }
-
-    /**
-     * 获取当前终端的尺寸
-     * @return array
-     */
-    public function getTerminalDimensions()
-    {
-        if ($this->terminalDimensions) {
-            return $this->terminalDimensions;
-        }
-
-        if ('\\' === DIRECTORY_SEPARATOR) {
-            if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
-                return [(int) $matches[1], (int) $matches[2]];
-            }
-            if (preg_match('/^(\d+)x(\d+)$/', $this->getMode(), $matches)) {
-                return [(int) $matches[1], (int) $matches[2]];
-            }
-        }
-
-        if ($sttyString = $this->getSttyColumns()) {
-            if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
-                return [(int) $matches[2], (int) $matches[1]];
-            }
-            if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
-                return [(int) $matches[2], (int) $matches[1]];
-            }
-        }
-
-        return [null, null];
-    }
-
-    /**
-     * 获取stty列数
-     * @return string
-     */
-    private function getSttyColumns()
-    {
-        if (!function_exists('proc_open')) {
-            return;
-        }
-
-        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-        $process        = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
-        if (is_resource($process)) {
-            $info = stream_get_contents($pipes[1]);
-            fclose($pipes[1]);
-            fclose($pipes[2]);
-            proc_close($process);
-
-            return $info;
-        }
-        return;
-    }
-
-    /**
-     * 获取终端模式
-     * @return string <width>x<height> 或 null
-     */
-    private function getMode()
-    {
-        if (!function_exists('proc_open')) {
-            return;
-        }
-
-        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
-        $process        = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
-        if (is_resource($process)) {
-            $info = stream_get_contents($pipes[1]);
-            fclose($pipes[1]);
-            fclose($pipes[2]);
-            proc_close($process);
-
-            if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
-                return $matches[2] . 'x' . $matches[1];
-            }
-        }
-        return;
-    }
-
-    private function stringWidth($string)
-    {
-        if (!function_exists('mb_strwidth')) {
-            return strlen($string);
-        }
-
-        if (false === $encoding = mb_detect_encoding($string)) {
-            return strlen($string);
-        }
-
-        return mb_strwidth($string, $encoding);
-    }
-
-    private function splitStringByWidth($string, $width)
-    {
-        if (!function_exists('mb_strwidth')) {
-            return str_split($string, $width);
-        }
-
-        if (false === $encoding = mb_detect_encoding($string)) {
-            return str_split($string, $width);
-        }
-
-        $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
-        $lines      = [];
-        $line       = '';
-        foreach (preg_split('//u', $utf8String) as $char) {
-            if (mb_strwidth($line . $char, 'utf8') <= $width) {
-                $line .= $char;
-                continue;
-            }
-            $lines[] = str_pad($line, $width);
-            $line    = $char;
-        }
-        if (strlen($line)) {
-            $lines[] = count($lines) ? str_pad($line, $width) : $line;
-        }
-
-        mb_convert_variables($encoding, 'utf8', $lines);
-
-        return $lines;
-    }
-
-    private function isRunningOS400()
-    {
-        $checks = [
-            function_exists('php_uname') ? php_uname('s') : '',
-            getenv('OSTYPE'),
-            PHP_OS,
-        ];
-        return false !== stripos(implode(';', $checks), 'OS400');
-    }
-
-    /**
-     * 当前环境是否支持写入控制台输出到stdout.
-     *
-     * @return bool
-     */
-    protected function hasStdoutSupport()
-    {
-        return false === $this->isRunningOS400();
-    }
-
-    /**
-     * 当前环境是否支持写入控制台输出到stderr.
-     *
-     * @return bool
-     */
-    protected function hasStderrSupport()
-    {
-        return false === $this->isRunningOS400();
-    }
-
-    /**
-     * @return resource
-     */
-    private function openOutputStream()
-    {
-        if (!$this->hasStdoutSupport()) {
-            return fopen('php://output', 'w');
-        }
-        return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w');
-    }
-
-    /**
-     * @return resource
-     */
-    private function openErrorStream()
-    {
-        return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w');
-    }
-
-    /**
-     * 将消息写入到输出。
-     * @param string $message 消息
-     * @param bool   $newline 是否另起一行
-     * @param null   $stream
-     */
-    protected function doWrite($message, $newline, $stream = null)
-    {
-        if (null === $stream) {
-            $stream = $this->stdout;
-        }
-        if (false === @fwrite($stream, $message . ($newline ? PHP_EOL : ''))) {
-            throw new \RuntimeException('Unable to write output.');
-        }
-
-        fflush($stream);
-    }
-
-    /**
-     * 是否支持着色
-     * @param $stream
-     * @return bool
-     */
-    protected function hasColorSupport($stream)
-    {
-        if (DIRECTORY_SEPARATOR === '\\') {
-            return
-            '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR . '.' . PHP_WINDOWS_VERSION_MINOR . '.' . PHP_WINDOWS_VERSION_BUILD
-            || false !== getenv('ANSICON')
-            || 'ON' === getenv('ConEmuANSI')
-            || 'xterm' === getenv('TERM');
-        }
-
-        return function_exists('posix_isatty') && @posix_isatty($stream);
-    }
-
-}

+ 0 - 33
thinkphp/library/think/console/output/driver/Nothing.php

@@ -1,33 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\driver;
-
-use think\console\Output;
-
-class Nothing
-{
-
-    public function __construct(Output $output)
-    {
-        // do nothing
-    }
-
-    public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL)
-    {
-        // do nothing
-    }
-
-    public function renderException(\Exception $e)
-    {
-        // do nothing
-    }
-}

+ 0 - 116
thinkphp/library/think/console/output/formatter/Stack.php

@@ -1,116 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\formatter;
-
-class Stack
-{
-
-    /**
-     * @var Style[]
-     */
-    private $styles;
-
-    /**
-     * @var Style
-     */
-    private $emptyStyle;
-
-    /**
-     * 构造方法
-     * @param Style|null $emptyStyle
-     */
-    public function __construct(Style $emptyStyle = null)
-    {
-        $this->emptyStyle = $emptyStyle ?: new Style();
-        $this->reset();
-    }
-
-    /**
-     * 重置堆栈
-     */
-    public function reset()
-    {
-        $this->styles = [];
-    }
-
-    /**
-     * 推一个样式进入堆栈
-     * @param Style $style
-     */
-    public function push(Style $style)
-    {
-        $this->styles[] = $style;
-    }
-
-    /**
-     * 从堆栈中弹出一个样式
-     * @param Style|null $style
-     * @return Style
-     * @throws \InvalidArgumentException
-     */
-    public function pop(Style $style = null)
-    {
-        if (empty($this->styles)) {
-            return $this->emptyStyle;
-        }
-
-        if (null === $style) {
-            return array_pop($this->styles);
-        }
-
-        /**
-         * @var int   $index
-         * @var Style $stackedStyle
-         */
-        foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
-            if ($style->apply('') === $stackedStyle->apply('')) {
-                $this->styles = array_slice($this->styles, 0, $index);
-
-                return $stackedStyle;
-            }
-        }
-
-        throw new \InvalidArgumentException('Incorrectly nested style tag found.');
-    }
-
-    /**
-     * 计算堆栈的当前样式。
-     * @return Style
-     */
-    public function getCurrent()
-    {
-        if (empty($this->styles)) {
-            return $this->emptyStyle;
-        }
-
-        return $this->styles[count($this->styles) - 1];
-    }
-
-    /**
-     * @param Style $emptyStyle
-     * @return Stack
-     */
-    public function setEmptyStyle(Style $emptyStyle)
-    {
-        $this->emptyStyle = $emptyStyle;
-
-        return $this;
-    }
-
-    /**
-     * @return Style
-     */
-    public function getEmptyStyle()
-    {
-        return $this->emptyStyle;
-    }
-}

+ 0 - 189
thinkphp/library/think/console/output/formatter/Style.php

@@ -1,189 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\formatter;
-
-class Style
-{
-
-    private static $availableForegroundColors = [
-        'black'   => ['set' => 30, 'unset' => 39],
-        'red'     => ['set' => 31, 'unset' => 39],
-        'green'   => ['set' => 32, 'unset' => 39],
-        'yellow'  => ['set' => 33, 'unset' => 39],
-        'blue'    => ['set' => 34, 'unset' => 39],
-        'magenta' => ['set' => 35, 'unset' => 39],
-        'cyan'    => ['set' => 36, 'unset' => 39],
-        'white'   => ['set' => 37, 'unset' => 39],
-    ];
-    private static $availableBackgroundColors = [
-        'black'   => ['set' => 40, 'unset' => 49],
-        'red'     => ['set' => 41, 'unset' => 49],
-        'green'   => ['set' => 42, 'unset' => 49],
-        'yellow'  => ['set' => 43, 'unset' => 49],
-        'blue'    => ['set' => 44, 'unset' => 49],
-        'magenta' => ['set' => 45, 'unset' => 49],
-        'cyan'    => ['set' => 46, 'unset' => 49],
-        'white'   => ['set' => 47, 'unset' => 49],
-    ];
-    private static $availableOptions = [
-        'bold'       => ['set' => 1, 'unset' => 22],
-        'underscore' => ['set' => 4, 'unset' => 24],
-        'blink'      => ['set' => 5, 'unset' => 25],
-        'reverse'    => ['set' => 7, 'unset' => 27],
-        'conceal'    => ['set' => 8, 'unset' => 28],
-    ];
-
-    private $foreground;
-    private $background;
-    private $options = [];
-
-    /**
-     * 初始化输出的样式
-     * @param string|null $foreground 字体颜色
-     * @param string|null $background 背景色
-     * @param array       $options    格式
-     * @api
-     */
-    public function __construct($foreground = null, $background = null, array $options = [])
-    {
-        if (null !== $foreground) {
-            $this->setForeground($foreground);
-        }
-        if (null !== $background) {
-            $this->setBackground($background);
-        }
-        if (count($options)) {
-            $this->setOptions($options);
-        }
-    }
-
-    /**
-     * 设置字体颜色
-     * @param string|null $color 颜色名
-     * @throws \InvalidArgumentException
-     * @api
-     */
-    public function setForeground($color = null)
-    {
-        if (null === $color) {
-            $this->foreground = null;
-
-            return;
-        }
-
-        if (!isset(static::$availableForegroundColors[$color])) {
-            throw new \InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors))));
-        }
-
-        $this->foreground = static::$availableForegroundColors[$color];
-    }
-
-    /**
-     * 设置背景色
-     * @param string|null $color 颜色名
-     * @throws \InvalidArgumentException
-     * @api
-     */
-    public function setBackground($color = null)
-    {
-        if (null === $color) {
-            $this->background = null;
-
-            return;
-        }
-
-        if (!isset(static::$availableBackgroundColors[$color])) {
-            throw new \InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors))));
-        }
-
-        $this->background = static::$availableBackgroundColors[$color];
-    }
-
-    /**
-     * 设置字体格式
-     * @param string $option 格式名
-     * @throws \InvalidArgumentException When the option name isn't defined
-     * @api
-     */
-    public function setOption($option)
-    {
-        if (!isset(static::$availableOptions[$option])) {
-            throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
-        }
-
-        if (!in_array(static::$availableOptions[$option], $this->options)) {
-            $this->options[] = static::$availableOptions[$option];
-        }
-    }
-
-    /**
-     * 重置字体格式
-     * @param string $option 格式名
-     * @throws \InvalidArgumentException
-     */
-    public function unsetOption($option)
-    {
-        if (!isset(static::$availableOptions[$option])) {
-            throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
-        }
-
-        $pos = array_search(static::$availableOptions[$option], $this->options);
-        if (false !== $pos) {
-            unset($this->options[$pos]);
-        }
-    }
-
-    /**
-     * 批量设置字体格式
-     * @param array $options
-     */
-    public function setOptions(array $options)
-    {
-        $this->options = [];
-
-        foreach ($options as $option) {
-            $this->setOption($option);
-        }
-    }
-
-    /**
-     * 应用样式到文字
-     * @param string $text 文字
-     * @return string
-     */
-    public function apply($text)
-    {
-        $setCodes   = [];
-        $unsetCodes = [];
-
-        if (null !== $this->foreground) {
-            $setCodes[]   = $this->foreground['set'];
-            $unsetCodes[] = $this->foreground['unset'];
-        }
-        if (null !== $this->background) {
-            $setCodes[]   = $this->background['set'];
-            $unsetCodes[] = $this->background['unset'];
-        }
-        if (count($this->options)) {
-            foreach ($this->options as $option) {
-                $setCodes[]   = $option['set'];
-                $unsetCodes[] = $option['unset'];
-            }
-        }
-
-        if (0 === count($setCodes)) {
-            return $text;
-        }
-
-        return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
-    }
-}

+ 0 - 163
thinkphp/library/think/console/output/question/Choice.php

@@ -1,163 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\question;
-
-use think\console\output\Question;
-
-class Choice extends Question
-{
-
-    private $choices;
-    private $multiselect  = false;
-    private $prompt       = ' > ';
-    private $errorMessage = 'Value "%s" is invalid';
-
-    /**
-     * 构造方法
-     * @param string $question 问题
-     * @param array  $choices  选项
-     * @param mixed  $default  默认答案
-     */
-    public function __construct($question, array $choices, $default = null)
-    {
-        parent::__construct($question, $default);
-
-        $this->choices = $choices;
-        $this->setValidator($this->getDefaultValidator());
-        $this->setAutocompleterValues($choices);
-    }
-
-    /**
-     * 可选项
-     * @return array
-     */
-    public function getChoices()
-    {
-        return $this->choices;
-    }
-
-    /**
-     * 设置可否多选
-     * @param bool $multiselect
-     * @return self
-     */
-    public function setMultiselect($multiselect)
-    {
-        $this->multiselect = $multiselect;
-        $this->setValidator($this->getDefaultValidator());
-
-        return $this;
-    }
-
-    public function isMultiselect()
-    {
-        return $this->multiselect;
-    }
-
-    /**
-     * 获取提示
-     * @return string
-     */
-    public function getPrompt()
-    {
-        return $this->prompt;
-    }
-
-    /**
-     * 设置提示
-     * @param string $prompt
-     * @return self
-     */
-    public function setPrompt($prompt)
-    {
-        $this->prompt = $prompt;
-
-        return $this;
-    }
-
-    /**
-     * 设置错误提示信息
-     * @param string $errorMessage
-     * @return self
-     */
-    public function setErrorMessage($errorMessage)
-    {
-        $this->errorMessage = $errorMessage;
-        $this->setValidator($this->getDefaultValidator());
-
-        return $this;
-    }
-
-    /**
-     * 获取默认的验证方法
-     * @return callable
-     */
-    private function getDefaultValidator()
-    {
-        $choices      = $this->choices;
-        $errorMessage = $this->errorMessage;
-        $multiselect  = $this->multiselect;
-        $isAssoc      = $this->isAssoc($choices);
-
-        return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
-            // Collapse all spaces.
-            $selectedChoices = str_replace(' ', '', $selected);
-
-            if ($multiselect) {
-                // Check for a separated comma values
-                if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
-                    throw new \InvalidArgumentException(sprintf($errorMessage, $selected));
-                }
-                $selectedChoices = explode(',', $selectedChoices);
-            } else {
-                $selectedChoices = [$selected];
-            }
-
-            $multiselectChoices = [];
-            foreach ($selectedChoices as $value) {
-                $results = [];
-                foreach ($choices as $key => $choice) {
-                    if ($choice === $value) {
-                        $results[] = $key;
-                    }
-                }
-
-                if (count($results) > 1) {
-                    throw new \InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
-                }
-
-                $result = array_search($value, $choices);
-
-                if (!$isAssoc) {
-                    if (!empty($result)) {
-                        $result = $choices[$result];
-                    } elseif (isset($choices[$value])) {
-                        $result = $choices[$value];
-                    }
-                } elseif (empty($result) && array_key_exists($value, $choices)) {
-                    $result = $value;
-                }
-
-                if (empty($result)) {
-                    throw new \InvalidArgumentException(sprintf($errorMessage, $value));
-                }
-                array_push($multiselectChoices, $result);
-            }
-
-            if ($multiselect) {
-                return $multiselectChoices;
-            }
-
-            return current($multiselectChoices);
-        };
-    }
-}

+ 0 - 57
thinkphp/library/think/console/output/question/Confirmation.php

@@ -1,57 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-namespace think\console\output\question;
-
-use think\console\output\Question;
-
-class Confirmation extends Question
-{
-
-    private $trueAnswerRegex;
-
-    /**
-     * 构造方法
-     * @param string $question        问题
-     * @param bool   $default         默认答案
-     * @param string $trueAnswerRegex 验证正则
-     */
-    public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
-    {
-        parent::__construct($question, (bool) $default);
-
-        $this->trueAnswerRegex = $trueAnswerRegex;
-        $this->setNormalizer($this->getDefaultNormalizer());
-    }
-
-    /**
-     * 获取默认的答案回调
-     * @return callable
-     */
-    private function getDefaultNormalizer()
-    {
-        $default = $this->getDefault();
-        $regex   = $this->trueAnswerRegex;
-
-        return function ($answer) use ($default, $regex) {
-            if (is_bool($answer)) {
-                return $answer;
-            }
-
-            $answerIsTrue = (bool) preg_match($regex, $answer);
-            if (false === $default) {
-                return $answer && $answerIsTrue;
-            }
-
-            return !$answer || $answerIsTrue;
-        };
-    }
-}

+ 0 - 1166
thinkphp/library/think/db/Builder.php

@@ -1,1166 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db;
-
-use PDO;
-use think\Exception;
-
-abstract class Builder
-{
-    // connection对象实例
-    protected $connection;
-
-    // 查询表达式映射
-    protected $exp = ['EQ' => '=', 'NEQ' => '<>', 'GT' => '>', 'EGT' => '>=', 'LT' => '<', 'ELT' => '<=', 'NOTLIKE' => 'NOT LIKE', 'NOTIN' => 'NOT IN', 'NOTBETWEEN' => 'NOT BETWEEN', 'NOTEXISTS' => 'NOT EXISTS', 'NOTNULL' => 'NOT NULL', 'NOTBETWEEN TIME' => 'NOT BETWEEN TIME'];
-
-    // 查询表达式解析
-    protected $parser = [
-        'parseCompare'     => ['=', '<>', '>', '>=', '<', '<='],
-        'parseLike'        => ['LIKE', 'NOT LIKE'],
-        'parseBetween'     => ['NOT BETWEEN', 'BETWEEN'],
-        'parseIn'          => ['NOT IN', 'IN'],
-        'parseExp'         => ['EXP'],
-        'parseNull'        => ['NOT NULL', 'NULL'],
-        'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
-        'parseTime'        => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
-        'parseExists'      => ['NOT EXISTS', 'EXISTS'],
-    ];
-
-    // SQL表达式
-    protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%UNION%%ORDER%%LIMIT% %LOCK%%COMMENT%';
-
-    protected $insertSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
-
-    protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
-
-    protected $updateSql = 'UPDATE %TABLE% SET %SET%%JOIN%%WHERE%%ORDER%%LIMIT% %LOCK%%COMMENT%';
-
-    protected $deleteSql = 'DELETE FROM %TABLE%%USING%%JOIN%%WHERE%%ORDER%%LIMIT% %LOCK%%COMMENT%';
-
-    /**
-     * 架构函数
-     * @access public
-     * @param  Connection    $connection 数据库连接对象实例
-     */
-    public function __construct(Connection $connection)
-    {
-        $this->connection = $connection;
-    }
-
-    /**
-     * 获取当前的连接对象实例
-     * @access public
-     * @return Connection
-     */
-    public function getConnection()
-    {
-        return $this->connection;
-    }
-
-    /**
-     * 注册查询表达式解析
-     * @access public
-     * @param  string    $name   解析方法
-     * @param  array     $parser 匹配表达式数据
-     * @return $this
-     */
-    public function bindParser($name, $parser)
-    {
-        $this->parser[$name] = $parser;
-        return $this;
-    }
-
-    /**
-     * 数据分析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  array     $data      数据
-     * @param  array     $fields    字段信息
-     * @param  array     $bind      参数绑定
-     * @param  string    $suffix    参数绑定后缀
-     * @return array
-     */
-    protected function parseData(Query $query, $data = [], $fields = [], $bind = [], $suffix = '')
-    {
-        if (empty($data)) {
-            return [];
-        }
-
-        $options = $query->getOptions();
-
-        // 获取绑定信息
-        if (empty($bind)) {
-            $bind = $this->connection->getFieldsBind($options['table']);
-        }
-
-        if (empty($fields)) {
-            if ('*' == $options['field']) {
-                $fields = array_keys($bind);
-            } else {
-                $fields = $options['field'];
-            }
-        }
-
-        $result = [];
-
-        foreach ($data as $key => $val) {
-            $item = $this->parseKey($query, $key, true);
-
-            if ($val instanceof Expression) {
-                $result[$item] = $val->getValue();
-                continue;
-            } elseif (!is_scalar($val) && (in_array($key, (array) $query->getOptions('json')) || 'json' == $this->connection->getFieldsType($options['table'], $key))) {
-                $val = json_encode($val);
-            } elseif (is_object($val) && method_exists($val, '__toString')) {
-                // 对象数据写入
-                $val = $val->__toString();
-            }
-
-            if (false !== strpos($key, '->')) {
-                list($key, $name) = explode('->', $key);
-                $item             = $this->parseKey($query, $key);
-                $result[$item]    = 'json_set(' . $item . ', \'$.' . $name . '\', ' . $this->parseDataBind($query, $key, $val, $bind, $suffix) . ')';
-            } elseif (false === strpos($key, '.') && !in_array($key, $fields, true)) {
-                if ($options['strict']) {
-                    throw new Exception('fields not exists:[' . $key . ']');
-                }
-            } elseif (is_null($val)) {
-                $result[$item] = 'NULL';
-            } elseif (is_array($val) && !empty($val)) {
-                switch ($val[0]) {
-                    case 'INC':
-                        $result[$item] = $item . ' + ' . floatval($val[1]);
-                        break;
-                    case 'DEC':
-                        $result[$item] = $item . ' - ' . floatval($val[1]);
-                        break;
-                }
-            } elseif (is_scalar($val)) {
-                // 过滤非标量数据
-                $result[$item] = $this->parseDataBind($query, $key, $val, $bind, $suffix);
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * 数据绑定处理
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  string    $key       字段名
-     * @param  mixed     $data      数据
-     * @param  array     $bind      绑定数据
-     * @param  string    $suffix    绑定后缀
-     * @return string
-     */
-    protected function parseDataBind(Query $query, $key, $data, $bind = [], $suffix = '')
-    {
-        // 过滤非标量数据
-        if (0 === strpos($data, ':') && $query->isBind(substr($data, 1))) {
-            return $data;
-        }
-
-        $key  = str_replace(['.', '->'], '_', $key);
-        $name = 'data__' . $key . $suffix;
-
-        $query->bind($name, $data, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
-
-        return ':' . $name;
-    }
-
-    /**
-     * 字段名分析
-     * @access public
-     * @param  Query  $query    查询对象
-     * @param  string $key      字段名
-     * @param  bool   $strict   严格检测
-     * @return string
-     */
-    public function parseKey(Query $query, $key, $strict = false)
-    {
-        return $key;
-    }
-
-    /**
-     * field分析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  mixed     $fields    字段名
-     * @return string
-     */
-    protected function parseField(Query $query, $fields)
-    {
-        if ('*' == $fields || empty($fields)) {
-            $fieldsStr = '*';
-        } elseif (is_array($fields)) {
-            // 支持 'field1'=>'field2' 这样的字段别名定义
-            $array = [];
-
-            foreach ($fields as $key => $field) {
-                if ($field instanceof Expression) {
-                    $array[] = $field->getValue();
-                } elseif (!is_numeric($key)) {
-                    $array[] = $this->parseKey($query, $key) . ' AS ' . $this->parseKey($query, $field, true);
-                } else {
-                    $array[] = $this->parseKey($query, $field);
-                }
-            }
-
-            $fieldsStr = implode(',', $array);
-        }
-
-        return $fieldsStr;
-    }
-
-    /**
-     * table分析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  mixed     $tables    表名
-     * @return string
-     */
-    protected function parseTable(Query $query, $tables)
-    {
-        $item    = [];
-        $options = $query->getOptions();
-
-        foreach ((array) $tables as $key => $table) {
-            if (!is_numeric($key)) {
-                $key    = $this->connection->parseSqlTable($key);
-                $item[] = $this->parseKey($query, $key) . ' ' . $this->parseKey($query, $table);
-            } else {
-                $table = $this->connection->parseSqlTable($table);
-
-                if (isset($options['alias'][$table])) {
-                    $item[] = $this->parseKey($query, $table) . ' ' . $this->parseKey($query, $options['alias'][$table]);
-                } else {
-                    $item[] = $this->parseKey($query, $table);
-                }
-            }
-        }
-
-        return implode(',', $item);
-    }
-
-    /**
-     * where分析
-     * @access protected
-     * @param  Query     $query   查询对象
-     * @param  mixed     $where   查询条件
-     * @return string
-     */
-    protected function parseWhere(Query $query, $where)
-    {
-        $options  = $query->getOptions();
-        $whereStr = $this->buildWhere($query, $where);
-
-        if (!empty($options['soft_delete'])) {
-            // 附加软删除条件
-            list($field, $condition) = $options['soft_delete'];
-
-            $binds    = $this->connection->getFieldsBind($options['table']);
-            $whereStr = $whereStr ? '( ' . $whereStr . ' ) AND ' : '';
-            $whereStr = $whereStr . $this->parseWhereItem($query, $field, $condition, '', $binds);
-        }
-
-        return empty($whereStr) ? '' : ' WHERE ' . $whereStr;
-    }
-
-    /**
-     * 生成查询条件SQL
-     * @access public
-     * @param  Query     $query     查询对象
-     * @param  mixed     $where     查询条件
-     * @return string
-     */
-    public function buildWhere(Query $query, $where)
-    {
-        if (empty($where)) {
-            $where = [];
-        }
-
-        $whereStr = '';
-        $binds    = $this->connection->getFieldsBind($query->getOptions('table'));
-
-        foreach ($where as $logic => $val) {
-            $str = [];
-
-            foreach ($val as $value) {
-                if ($value instanceof Expression) {
-                    $str[] = ' ' . $logic . ' ( ' . $value->getValue() . ' )';
-                    continue;
-                }
-
-                if (is_array($value)) {
-                    if (key($value) !== 0) {
-                        throw new Exception('where express error:' . var_export($value, true));
-                    }
-                    $field = array_shift($value);
-                } elseif (!($value instanceof \Closure)) {
-                    throw new Exception('where express error:' . var_export($value, true));
-                }
-
-                if ($value instanceof \Closure) {
-                    // 使用闭包查询
-                    $newQuery = $query->newQuery()->setConnection($this->connection);
-                    $value($newQuery);
-                    $whereClause = $this->buildWhere($query, $newQuery->getOptions('where'));
-
-                    if (!empty($whereClause)) {
-                        $str[] = ' ' . $logic . ' ( ' . $whereClause . ' )';
-                    }
-                } elseif (is_array($field)) {
-                    array_unshift($value, $field);
-                    $str2 = [];
-                    foreach ($value as $item) {
-                        $str2[] = $this->parseWhereItem($query, array_shift($item), $item, $logic, $binds);
-                    }
-
-                    $str[] = ' ' . $logic . ' ( ' . implode(' AND ', $str2) . ' )';
-                } elseif (strpos($field, '|')) {
-                    // 不同字段使用相同查询条件(OR)
-                    $array = explode('|', $field);
-                    $item  = [];
-
-                    foreach ($array as $k) {
-                        $item[] = $this->parseWhereItem($query, $k, $value, '', $binds);
-                    }
-
-                    $str[] = ' ' . $logic . ' ( ' . implode(' OR ', $item) . ' )';
-                } elseif (strpos($field, '&')) {
-                    // 不同字段使用相同查询条件(AND)
-                    $array = explode('&', $field);
-                    $item  = [];
-
-                    foreach ($array as $k) {
-                        $item[] = $this->parseWhereItem($query, $k, $value, '', $binds);
-                    }
-
-                    $str[] = ' ' . $logic . ' ( ' . implode(' AND ', $item) . ' )';
-                } else {
-                    // 对字段使用表达式查询
-                    $field = is_string($field) ? $field : '';
-                    $str[] = ' ' . $logic . ' ' . $this->parseWhereItem($query, $field, $value, $logic, $binds);
-                }
-            }
-
-            $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($logic) + 1) : implode(' ', $str);
-        }
-
-        return $whereStr;
-    }
-
-    // where子单元分析
-    protected function parseWhereItem(Query $query, $field, $val, $rule = '', $binds = [], $bindName = null)
-    {
-        // 字段分析
-        $key = $field ? $this->parseKey($query, $field, true) : '';
-
-        // 查询规则和条件
-        if (!is_array($val)) {
-            $val = is_null($val) ? ['NULL', ''] : ['=', $val];
-        }
-
-        list($exp, $value) = $val;
-
-        // 对一个字段使用多个查询条件
-        if (is_array($exp)) {
-            $item = array_pop($val);
-
-            // 传入 or 或者 and
-            if (is_string($item) && in_array($item, ['AND', 'and', 'OR', 'or'])) {
-                $rule = $item;
-            } else {
-                array_push($val, $item);
-            }
-
-            foreach ($val as $k => $item) {
-                $bindName = 'where_' . str_replace('.', '_', $field) . '_' . $k;
-                $str[]    = $this->parseWhereItem($query, $field, $item, $rule, $binds, $bindName);
-            }
-
-            return '( ' . implode(' ' . $rule . ' ', $str) . ' )';
-        }
-
-        // 检测操作符
-        $exp = strtoupper($exp);
-        if (isset($this->exp[$exp])) {
-            $exp = $this->exp[$exp];
-        }
-
-        $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field);
-
-        if (preg_match('/\W/', $bindName)) {
-            // 处理带非单词字符的字段名
-            $bindName = md5($bindName);
-        }
-
-        if ($value instanceof Expression) {
-
-        } elseif (is_object($value) && method_exists($value, '__toString')) {
-            // 对象数据写入
-            $value = $value->__toString();
-        }
-
-        $bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
-
-        if (is_scalar($value) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
-            if (strpos($value, ':') !== 0 || !$query->isBind(substr($value, 1))) {
-                if ($query->isBind($bindName)) {
-                    $bindName .= '_' . str_replace('.', '_', uniqid('', true));
-                }
-
-                $query->bind($bindName, $value, $bindType);
-                $value = ':' . $bindName;
-            }
-        }
-
-        // 解析查询表达式
-        foreach ($this->parser as $fun => $parse) {
-            if (in_array($exp, $parse)) {
-                $whereStr = $this->$fun($query, $key, $exp, $value, $field, $bindName, $bindType, isset($val[2]) ? $val[2] : 'AND');
-                break;
-            }
-        }
-
-        if (!isset($whereStr)) {
-            throw new Exception('where express error:' . $exp);
-        }
-
-        return $whereStr;
-    }
-
-    /**
-     * 模糊查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @param  string    $logic
-     * @return string
-     */
-    protected function parseLike(Query $query, $key, $exp, $value, $field, $bindName, $bindType, $logic)
-    {
-        // 模糊匹配
-        if (is_array($value)) {
-            foreach ($value as $k => $item) {
-                $bindKey        = $bindName . '_' . $k;
-                $bind[$bindKey] = [$item, $bindType];
-                $array[]        = $key . ' ' . $exp . ' :' . $bindKey;
-            }
-
-            $query->bind($bind);
-
-            $whereStr = '(' . implode($array, ' ' . strtoupper($logic) . ' ') . ')';
-        } else {
-            $whereStr = $key . ' ' . $exp . ' ' . $value;
-        }
-
-        return $whereStr;
-    }
-
-    /**
-     * 表达式查询
-     * @access protected
-     * @param  Query        $query        查询对象
-     * @param  string       $key
-     * @param  string       $exp
-     * @param  Expression   $value
-     * @param  string       $field
-     * @param  string       $bindName
-     * @param  integer      $bindType
-     * @return string
-     */
-    protected function parseExp(Query $query, $key, $exp, Expression $value, $field, $bindName, $bindType)
-    {
-        // 表达式查询
-        return '( ' . $key . ' ' . $value->getValue() . ' )';
-    }
-
-    /**
-     * Null查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseNull(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        // NULL 查询
-        return $key . ' IS ' . $exp;
-    }
-
-    /**
-     * 范围查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseBetween(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        // BETWEEN 查询
-        $data = is_array($value) ? $value : explode(',', $value);
-
-        if ($query->isBind($bindName . '_between_1')) {
-            $bindKey1 = $bindName . '_between_1' . uniqid();
-            $bindKey2 = $bindName . '_between_2' . uniqid();
-        } else {
-            $bindKey1 = $bindName . '_between_1';
-            $bindKey2 = $bindName . '_between_2';
-        }
-
-        $bind = [
-            $bindKey1 => [$data[0], $bindType],
-            $bindKey2 => [$data[1], $bindType],
-        ];
-
-        $query->bind($bind);
-
-        $between = ':' . $bindKey1 . ' AND :' . $bindKey2;
-
-        return $key . ' ' . $exp . ' ' . $between;
-    }
-
-    /**
-     * Exists查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseExists(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        // EXISTS 查询
-        if ($value instanceof \Closure) {
-            $value = $this->parseClosure($query, $value, false);
-        }
-
-        return $exp . ' (' . $value . ')';
-    }
-
-    /**
-     * 时间比较查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseTime(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        return $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($query, $value, $field, $bindName, $bindType);
-    }
-
-    /**
-     * 大小比较查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseCompare(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        if (is_array($value)) {
-            throw new Exception('where express error:' . $exp . var_export($value, true));
-        }
-
-        // 比较运算
-        if ($value instanceof \Closure) {
-            $value = $this->parseClosure($query, $value);
-        }
-
-        return $key . ' ' . $exp . ' ' . $value;
-    }
-
-    /**
-     * 时间范围查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseBetweenTime(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        if (is_string($value)) {
-            $value = explode(',', $value);
-        }
-
-        return $key . ' ' . substr($exp, 0, -4)
-        . $this->parseDateTime($query, $value[0], $field, $bindName . '_between_1', $bindType)
-        . ' AND '
-        . $this->parseDateTime($query, $value[1], $field, $bindName . '_between_2', $bindType);
-
-    }
-
-    /**
-     * IN查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseIn(Query $query, $key, $exp, $value, $field, $bindName, $bindType)
-    {
-        // IN 查询
-        if ($value instanceof \Closure) {
-            $value = $this->parseClosure($query, $value, false);
-        } else {
-            $value = array_unique(is_array($value) ? $value : explode(',', $value));
-
-            $bind  = [];
-            $array = [];
-            $i     = 0;
-
-            foreach ($value as $k => $v) {
-                $i++;
-                if ($query->isBind($bindName . '_in_' . $i)) {
-                    $bindKey = $bindName . '_in_' . uniqid() . '_' . $i;
-                } else {
-                    $bindKey = $bindName . '_in_' . $i;
-                }
-                $bind[$bindKey] = [$v, $bindType];
-                $array[]        = ':' . $bindKey;
-            }
-
-            $zone = implode(',', $array);
-            $query->bind($bind);
-
-            $value = empty($zone) ? "''" : $zone;
-        }
-
-        return $key . ' ' . $exp . ' (' . $value . ')';
-    }
-
-    /**
-     * 闭包子查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  \Closure  $call
-     * @param  bool      $show
-     * @return string
-     */
-    protected function parseClosure(Query $query, $call, $show = true)
-    {
-        $newQuery = $query->newQuery()->setConnection($this->connection);
-        $call($newQuery);
-
-        return $newQuery->buildSql($show);
-    }
-
-    /**
-     * 日期时间条件解析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $value
-     * @param  string    $key
-     * @param  array     $options
-     * @param  string    $bindName
-     * @param  integer   $bindType
-     * @return string
-     */
-    protected function parseDateTime(Query $query, $value, $key, $bindName = null, $bindType = null)
-    {
-        $options = $query->getOptions();
-
-        // 获取时间字段类型
-        if (strpos($key, '.')) {
-            list($table, $key) = explode('.', $key);
-
-            if (isset($options['alias']) && $pos = array_search($table, $options['alias'])) {
-                $table = $pos;
-            }
-        } else {
-            $table = $options['table'];
-        }
-
-        $type = $this->connection->getTableInfo($table, 'type');
-
-        if (isset($type[$key])) {
-            $info = $type[$key];
-        }
-
-        if (isset($info)) {
-            if (is_string($value)) {
-                $value = strtotime($value) ?: $value;
-            }
-
-            if (preg_match('/(datetime|timestamp)/is', $info)) {
-                // 日期及时间戳类型
-                $value = date('Y-m-d H:i:s', $value);
-            } elseif (preg_match('/(date)/is', $info)) {
-                // 日期及时间戳类型
-                $value = date('Y-m-d', $value);
-            }
-        }
-
-        $bindName = $bindName ?: $key;
-
-        $query->bind($bindName, $value, $bindType);
-
-        return ':' . $bindName;
-    }
-
-    /**
-     * limit分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $limit
-     * @return string
-     */
-    protected function parseLimit(Query $query, $limit)
-    {
-        return (!empty($limit) && false === strpos($limit, '(')) ? ' LIMIT ' . $limit . ' ' : '';
-    }
-
-    /**
-     * join分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  array     $join
-     * @return string
-     */
-    protected function parseJoin(Query $query, $join)
-    {
-        $joinStr = '';
-
-        if (!empty($join)) {
-            foreach ($join as $item) {
-                list($table, $type, $on) = $item;
-
-                $condition = [];
-
-                foreach ((array) $on as $val) {
-                    if (strpos($val, '=')) {
-                        list($val1, $val2) = explode('=', $val, 2);
-                        $condition[]       = $this->parseKey($query, $val1) . '=' . $this->parseKey($query, $val2);
-                    } else {
-                        $condition[] = $val;
-                    }
-                }
-
-                $table = $this->parseTable($query, $table);
-
-                $joinStr .= ' ' . $type . ' JOIN ' . $table . ' ON ' . implode(' AND ', $condition);
-            }
-        }
-
-        return $joinStr;
-    }
-
-    /**
-     * order分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $order
-     * @return string
-     */
-    protected function parseOrder(Query $query, $order)
-    {
-        if (empty($order)) {
-            return '';
-        }
-
-        $array = [];
-
-        foreach ($order as $key => $val) {
-            if ($val instanceof Expression) {
-                $array[] = $val->getValue();
-            } elseif (is_array($val)) {
-                if (isset($val['sort'])) {
-                    $sort = ' ' . $val['sort'];
-                    unset($val['sort']);
-                } else {
-                    $sort = '';
-                }
-
-                $options = $query->getOptions();
-                $bind    = $this->connection->getFieldsBind($options['table']);
-
-                foreach ($val as $k => $item) {
-                    $val[$k] = $this->parseDataBind($query, $key, $item, $bind, $k);
-                }
-
-                $array[] = 'field(' . $this->parseKey($query, $key, true) . ',' . implode(',', $val) . ')' . $sort;
-            } elseif ('[rand]' == $val) {
-                $array[] = $this->parseRand($query);
-            } else {
-                if (is_numeric($key)) {
-                    list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
-                } else {
-                    $sort = $val;
-                }
-
-                $sort    = in_array(strtolower($sort), ['asc', 'desc'], true) ? ' ' . $sort : '';
-                $array[] = $this->parseKey($query, $key, true) . $sort;
-            }
-        }
-
-        $order = implode(',', $array);
-
-        return ' ORDER BY ' . $order;
-    }
-
-    /**
-     * group分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $group
-     * @return string
-     */
-    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);
-    }
-
-    /**
-     * having分析
-     * @access protected
-     * @param  Query  $query        查询对象
-     * @param  string $having
-     * @return string
-     */
-    protected function parseHaving(Query $query, $having)
-    {
-        return !empty($having) ? ' HAVING ' . $having : '';
-    }
-
-    /**
-     * comment分析
-     * @access protected
-     * @param  Query  $query        查询对象
-     * @param  string $comment
-     * @return string
-     */
-    protected function parseComment(Query $query, $comment)
-    {
-        return !empty($comment) ? ' /* ' . $comment . ' */' : '';
-    }
-
-    /**
-     * distinct分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $distinct
-     * @return string
-     */
-    protected function parseDistinct(Query $query, $distinct)
-    {
-        return !empty($distinct) ? ' DISTINCT ' : '';
-    }
-
-    /**
-     * union分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $union
-     * @return string
-     */
-    protected function parseUnion(Query $query, $union)
-    {
-        if (empty($union)) {
-            return '';
-        }
-
-        $type = $union['type'];
-        unset($union['type']);
-
-        foreach ($union as $u) {
-            if ($u instanceof \Closure) {
-                $sql[] = $type . ' ' . $this->parseClosure($query, $u);
-            } elseif (is_string($u)) {
-                $sql[] = $type . ' ( ' . $this->connection->parseSqlTable($u) . ' )';
-            }
-        }
-
-        return ' ' . implode(' ', $sql);
-    }
-
-    /**
-     * index分析,可在操作链中指定需要强制使用的索引
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $index
-     * @return string
-     */
-    protected function parseForce(Query $query, $index)
-    {
-        if (empty($index)) {
-            return '';
-        }
-
-        return sprintf(" FORCE INDEX ( %s ) ", is_array($index) ? implode(',', $index) : $index);
-    }
-
-    /**
-     * 设置锁机制
-     * @access protected
-     * @param  Query         $query        查询对象
-     * @param  bool|string   $lock
-     * @return string
-     */
-    protected function parseLock(Query $query, $lock = false)
-    {
-        if (is_bool($lock)) {
-            return $lock ? ' FOR UPDATE ' : '';
-        } elseif (is_string($lock) && !empty($lock)) {
-            return ' ' . trim($lock) . ' ';
-        }
-    }
-
-    /**
-     * 生成查询SQL
-     * @access public
-     * @param  Query  $query  查询对象
-     * @return string
-     */
-    public function select(Query $query)
-    {
-        $options = $query->getOptions();
-
-        return str_replace(
-            ['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'],
-            [
-                $this->parseTable($query, $options['table']),
-                $this->parseDistinct($query, $options['distinct']),
-                $this->parseField($query, $options['field']),
-                $this->parseJoin($query, $options['join']),
-                $this->parseWhere($query, $options['where']),
-                $this->parseGroup($query, $options['group']),
-                $this->parseHaving($query, $options['having']),
-                $this->parseOrder($query, $options['order']),
-                $this->parseLimit($query, $options['limit']),
-                $this->parseUnion($query, $options['union']),
-                $this->parseLock($query, $options['lock']),
-                $this->parseComment($query, $options['comment']),
-                $this->parseForce($query, $options['force']),
-            ],
-            $this->selectSql);
-    }
-
-    /**
-     * 生成Insert SQL
-     * @access public
-     * @param  Query     $query   查询对象
-     * @param  bool      $replace 是否replace
-     * @return string
-     */
-    public function insert(Query $query, $replace = false)
-    {
-        $options = $query->getOptions();
-
-        // 分析并处理数据
-        $data = $this->parseData($query, $options['data']);
-        if (empty($data)) {
-            return 0;
-        }
-
-        $fields = array_keys($data);
-        $values = array_values($data);
-
-        return str_replace(
-            ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
-            [
-                $replace ? 'REPLACE' : 'INSERT',
-                $this->parseTable($query, $options['table']),
-                implode(' , ', $fields),
-                implode(' , ', $values),
-                $this->parseComment($query, $options['comment']),
-            ],
-            $this->insertSql);
-    }
-
-    /**
-     * 生成insertall SQL
-     * @access public
-     * @param  Query     $query   查询对象
-     * @param  array     $dataSet 数据集
-     * @param  bool      $replace 是否replace
-     * @return string
-     */
-    public function insertAll(Query $query, $dataSet, $replace = false)
-    {
-        $options = $query->getOptions();
-
-        // 获取合法的字段
-        if ('*' == $options['field']) {
-            $allowFields = $this->connection->getTableFields($options['table']);
-        } else {
-            $allowFields = $options['field'];
-        }
-
-        // 获取绑定信息
-        $bind = $this->connection->getFieldsBind($options['table']);
-
-        foreach ($dataSet as $k => $data) {
-            $data = $this->parseData($query, $data, $allowFields, $bind, '_' . $k);
-
-            $values[] = 'SELECT ' . implode(',', array_values($data));
-
-            if (!isset($insertFields)) {
-                $insertFields = array_keys($data);
-            }
-        }
-
-        $fields = [];
-
-        foreach ($insertFields as $field) {
-            $fields[] = $this->parseKey($query, $field, true);
-        }
-
-        return str_replace(
-            ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
-            [
-                $replace ? 'REPLACE' : 'INSERT',
-                $this->parseTable($query, $options['table']),
-                implode(' , ', $fields),
-                implode(' UNION ALL ', $values),
-                $this->parseComment($query, $options['comment']),
-            ],
-            $this->insertAllSql);
-    }
-
-    /**
-     * 生成slect insert SQL
-     * @access public
-     * @param  Query     $query  查询对象
-     * @param  array     $fields 数据
-     * @param  string    $table  数据表
-     * @return string
-     */
-    public function selectInsert(Query $query, $fields, $table)
-    {
-        $options = $query->getOptions();
-
-        if (is_string($fields)) {
-            $fields = explode(',', $fields);
-        }
-
-        foreach ($fields as &$field) {
-            $field = $this->parseKey($query, $field, true);
-        }
-
-        return 'INSERT INTO ' . $this->parseTable($query, $table, $options) . ' (' . implode(',', $fields) . ') ' . $this->select($options);
-    }
-
-    /**
-     * 生成update SQL
-     * @access public
-     * @param  Query     $query  查询对象
-     * @return string
-     */
-    public function update(Query $query)
-    {
-        $options = $query->getOptions();
-
-        $table = $this->parseTable($query, $options['table']);
-        $data  = $this->parseData($query, $options['data']);
-
-        if (empty($data)) {
-            return '';
-        }
-
-        foreach ($data as $key => $val) {
-            $set[] = $key . ' = ' . $val;
-        }
-
-        return str_replace(
-            ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
-            [
-                $this->parseTable($query, $options['table']),
-                implode(' , ', $set),
-                $this->parseJoin($query, $options['join']),
-                $this->parseWhere($query, $options['where']),
-                $this->parseOrder($query, $options['order']),
-                $this->parseLimit($query, $options['limit']),
-                $this->parseLock($query, $options['lock']),
-                $this->parseComment($query, $options['comment']),
-            ],
-            $this->updateSql);
-    }
-
-    /**
-     * 生成delete SQL
-     * @access public
-     * @param  Query  $query  查询对象
-     * @return string
-     */
-    public function delete(Query $query)
-    {
-        $options = $query->getOptions();
-
-        return str_replace(
-            ['%TABLE%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
-            [
-                $this->parseTable($query, $options['table']),
-                !empty($options['using']) ? ' USING ' . $this->parseTable($query, $options['using']) . ' ' : '',
-                $this->parseJoin($query, $options['join']),
-                $this->parseWhere($query, $options['where']),
-                $this->parseOrder($query, $options['order']),
-                $this->parseLimit($query, $options['limit']),
-                $this->parseLock($query, $options['lock']),
-                $this->parseComment($query, $options['comment']),
-            ],
-            $this->deleteSql);
-    }
-}

+ 0 - 2152
thinkphp/library/think/db/Connection.php

@@ -1,2152 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db;
-
-use InvalidArgumentException;
-use PDO;
-use PDOStatement;
-use think\Container;
-use think\Db;
-use think\db\exception\BindParamException;
-use think\Debug;
-use think\Exception;
-use think\exception\PDOException;
-
-abstract class Connection
-{
-    protected static $instance = [];
-    /** @var PDOStatement PDO操作实例 */
-    protected $PDOStatement;
-
-    /** @var string 当前SQL指令 */
-    protected $queryStr = '';
-    // 返回或者影响记录数
-    protected $numRows = 0;
-    // 事务指令数
-    protected $transTimes = 0;
-    // 错误信息
-    protected $error = '';
-
-    /** @var PDO[] 数据库连接ID 支持多个连接 */
-    protected $links = [];
-
-    /** @var PDO 当前连接ID */
-    protected $linkID;
-    protected $linkRead;
-    protected $linkWrite;
-
-    // 查询结果类型
-    protected $fetchType = PDO::FETCH_ASSOC;
-    // 字段属性大小写
-    protected $attrCase = PDO::CASE_LOWER;
-    // 监听回调
-    protected static $event = [];
-
-    // 数据表信息
-    protected static $info = [];
-
-    // 使用Builder类
-    protected $builderClassName;
-    // Builder对象
-    protected $builder;
-    // 数据库连接参数配置
-    protected $config = [
-        // 数据库类型
-        'type'            => '',
-        // 服务器地址
-        'hostname'        => '',
-        // 数据库名
-        'database'        => '',
-        // 用户名
-        'username'        => '',
-        // 密码
-        'password'        => '',
-        // 端口
-        'hostport'        => '',
-        // 连接dsn
-        'dsn'             => '',
-        // 数据库连接参数
-        'params'          => [],
-        // 数据库编码默认采用utf8
-        'charset'         => 'utf8',
-        // 数据库表前缀
-        'prefix'          => '',
-        // 数据库调试模式
-        'debug'           => false,
-        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
-        'deploy'          => 0,
-        // 数据库读写是否分离 主从式有效
-        'rw_separate'     => false,
-        // 读写分离后 主服务器数量
-        'master_num'      => 1,
-        // 指定从服务器序号
-        'slave_no'        => '',
-        // 是否严格检查字段是否存在
-        'fields_strict'   => true,
-        // 数据集返回类型
-        'resultset_type'  => '',
-        // 自动写入时间戳字段
-        'auto_timestamp'  => false,
-        // 时间字段取出后的默认时间格式
-        'datetime_format' => 'Y-m-d H:i:s',
-        // 是否需要进行SQL性能分析
-        'sql_explain'     => false,
-        // Builder类
-        'builder'         => '',
-        // Query类
-        'query'           => '\\think\\db\\Query',
-        // 是否需要断线重连
-        'break_reconnect' => false,
-        // 断线标识字符串
-        'break_match_str' => [],
-    ];
-
-    // PDO连接参数
-    protected $params = [
-        PDO::ATTR_CASE              => PDO::CASE_NATURAL,
-        PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
-        PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
-        PDO::ATTR_STRINGIFY_FETCHES => false,
-        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 = [];
-
-    /**
-     * 架构函数 读取数据库配置信息
-     * @access public
-     * @param  array $config 数据库配置数组
-     */
-    public function __construct(array $config = [])
-    {
-        if (!empty($config)) {
-            $this->config = array_merge($this->config, $config);
-        }
-
-        // 创建Builder对象
-        $class = $this->getBuilderClass();
-
-        $this->builder = new $class($this);
-
-        // 执行初始化操作
-        $this->initialize();
-    }
-
-    /**
-     * 初始化
-     * @access protected
-     * @return void
-     */
-    protected function initialize()
-    {}
-
-    /**
-     * 取得数据库连接类实例
-     * @access public
-     * @param  mixed         $config 连接配置
-     * @param  bool|string   $name 连接标识 true 强制重新连接
-     * @return Connection
-     * @throws Exception
-     */
-    public static function instance($config = [], $name = false)
-    {
-        if (false === $name) {
-            $name = md5(serialize($config));
-        }
-
-        if (true === $name || !isset(self::$instance[$name])) {
-            // 解析连接参数 支持数组和字符串
-            $options = self::parseConfig($config);
-
-            if (empty($options['type'])) {
-                throw new InvalidArgumentException('Undefined db type');
-            }
-
-            $class = false !== strpos($options['type'], '\\') ? $options['type'] : '\\think\\db\\connector\\' . ucwords($options['type']);
-            // 记录初始化信息
-            Container::get('app')->log('[ DB ] INIT ' . $options['type']);
-
-            if (true === $name) {
-                $name = md5(serialize($config));
-            }
-
-            self::$instance[$name] = new $class($options);
-        }
-
-        return self::$instance[$name];
-    }
-
-    /**
-     * 获取当前连接器类对应的Builder类
-     * @access public
-     * @return string
-     */
-    public function getBuilderClass()
-    {
-        if (!empty($this->builderClassName)) {
-            return $this->builderClassName;
-        }
-
-        return $this->getConfig('builder') ?: '\\think\\db\\builder\\' . ucfirst($this->getConfig('type'));
-    }
-
-    /**
-     * 设置当前的数据库Builder对象
-     * @access protected
-     * @param  Builder    $builder
-     * @return void
-     */
-    protected function setBuilder(Builder $builder)
-    {
-        $this->builder = $builder;
-
-        return $this;
-    }
-
-    /**
-     * 获取当前的builder实例对象
-     * @access public
-     * @return Builder
-     */
-    public function getBuilder()
-    {
-        return $this->builder;
-    }
-
-    /**
-     * 解析pdo连接的dsn信息
-     * @access protected
-     * @param  array $config 连接信息
-     * @return string
-     */
-    abstract protected function parseDsn($config);
-
-    /**
-     * 取得数据表的字段信息
-     * @access public
-     * @param  string $tableName
-     * @return array
-     */
-    abstract public function getFields($tableName);
-
-    /**
-     * 取得数据库的表信息
-     * @access public
-     * @param string $dbName
-     * @return array
-     */
-    abstract public function getTables($dbName);
-
-    /**
-     * SQL性能分析
-     * @access protected
-     * @param  string $sql
-     * @return array
-     */
-    abstract protected function getExplain($sql);
-
-    /**
-     * 对返数据表字段信息进行大小写转换出来
-     * @access public
-     * @param  array $info 字段信息
-     * @return array
-     */
-    public function fieldCase($info)
-    {
-        // 字段大小写转换
-        switch ($this->attrCase) {
-            case PDO::CASE_LOWER:
-                $info = array_change_key_case($info);
-                break;
-            case PDO::CASE_UPPER:
-                $info = array_change_key_case($info, CASE_UPPER);
-                break;
-            case PDO::CASE_NATURAL:
-            default:
-                // 不做转换
-        }
-
-        return $info;
-    }
-
-    /**
-     * 获取字段绑定类型
-     * @access public
-     * @param  string $type 字段类型
-     * @return integer
-     */
-    public function getFieldBindType($type)
-    {
-        if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) {
-            $bind = PDO::PARAM_STR;
-        } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {
-            $bind = PDO::PARAM_INT;
-        } elseif (preg_match('/bool/is', $type)) {
-            $bind = PDO::PARAM_BOOL;
-        } else {
-            $bind = PDO::PARAM_STR;
-        }
-
-        return $bind;
-    }
-
-    /**
-     * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名(小写)
-     * @access public
-     * @param  string $sql sql语句
-     * @return string
-     */
-    public function parseSqlTable($sql)
-    {
-        if (false !== strpos($sql, '__')) {
-            $prefix = $this->getConfig('prefix');
-            $sql    = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {
-                return $prefix . strtolower($match[1]);
-            }, $sql);
-        }
-
-        return $sql;
-    }
-
-    /**
-     * 获取数据表信息
-     * @access public
-     * @param  mixed  $tableName 数据表名 留空自动获取
-     * @param  string $fetch     获取信息类型 包括 fields type bind pk
-     * @return mixed
-     */
-    public function getTableInfo($tableName, $fetch = '')
-    {
-        if (is_array($tableName)) {
-            $tableName = key($tableName) ?: current($tableName);
-        }
-
-        if (strpos($tableName, ',')) {
-            // 多表不获取字段信息
-            return false;
-        } else {
-            $tableName = $this->parseSqlTable($tableName);
-        }
-
-        // 修正子查询作为表名的问题
-        if (strpos($tableName, ')')) {
-            return [];
-        }
-
-        list($tableName) = explode(' ', $tableName);
-
-        if (!strpos($tableName, '.')) {
-            $schema = $this->getConfig('database') . '.' . $tableName;
-        } else {
-            $schema = $tableName;
-        }
-
-        if (!isset(self::$info[$schema])) {
-            // 读取缓存
-            $cacheFile = Container::get('app')->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR . $schema . '.php';
-
-            if (!$this->config['debug'] && is_file($cacheFile)) {
-                $info = include $cacheFile;
-            } else {
-                $info = $this->getFields($tableName);
-            }
-
-            $fields = array_keys($info);
-            $bind   = $type   = [];
-
-            foreach ($info as $key => $val) {
-                // 记录字段类型
-                $type[$key] = $val['type'];
-                $bind[$key] = $this->getFieldBindType($val['type']);
-
-                if (!empty($val['primary'])) {
-                    $pk[] = $key;
-                }
-            }
-
-            if (isset($pk)) {
-                // 设置主键
-                $pk = count($pk) > 1 ? $pk : $pk[0];
-            } else {
-                $pk = null;
-            }
-
-            self::$info[$schema] = ['fields' => $fields, 'type' => $type, 'bind' => $bind, 'pk' => $pk];
-        }
-
-        return $fetch ? self::$info[$schema][$fetch] : self::$info[$schema];
-    }
-
-    /**
-     * 获取数据表的主键
-     * @access public
-     * @param  string $tableName 数据表名
-     * @return string|array
-     */
-    public function getPk($tableName)
-    {
-        return $this->getTableInfo($tableName, 'pk');
-    }
-
-    /**
-     * 获取数据表字段信息
-     * @access public
-     * @param  string $tableName 数据表名
-     * @return array
-     */
-    public function getTableFields($tableName)
-    {
-        return $this->getTableInfo($tableName, 'fields');
-    }
-
-    /**
-     * 获取数据表字段类型
-     * @access public
-     * @param  string $tableName 数据表名
-     * @param  string $field    字段名
-     * @return array|string
-     */
-    public function getFieldsType($tableName, $field = null)
-    {
-        $result = $this->getTableInfo($tableName, 'type');
-
-        if ($field && isset($result[$field])) {
-            return $result[$field];
-        }
-
-        return $result;
-    }
-
-    /**
-     * 获取数据表绑定信息
-     * @access public
-     * @param  string $tableName 数据表名
-     * @return array
-     */
-    public function getFieldsBind($tableName)
-    {
-        return $this->getTableInfo($tableName, 'bind');
-    }
-
-    /**
-     * 获取数据库的配置参数
-     * @access public
-     * @param  string $config 配置名称
-     * @return mixed
-     */
-    public function getConfig($config = '')
-    {
-        return $config ? $this->config[$config] : $this->config;
-    }
-
-    /**
-     * 设置数据库的配置参数
-     * @access public
-     * @param  string|array      $config 配置名称
-     * @param  mixed             $value 配置值
-     * @return void
-     */
-    public function setConfig($config, $value = '')
-    {
-        if (is_array($config)) {
-            $this->config = array_merge($this->config, $config);
-        } else {
-            $this->config[$config] = $value;
-        }
-    }
-
-    /**
-     * 连接数据库方法
-     * @access public
-     * @param  array         $config 连接参数
-     * @param  integer       $linkNum 连接序号
-     * @param  array|bool    $autoConnection 是否自动连接主数据库(用于分布式)
-     * @return PDO
-     * @throws Exception
-     */
-    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);
-            } else {
-                throw $e;
-            }
-        }
-    }
-
-    /**
-     * 释放查询结果
-     * @access public
-     */
-    public function free()
-    {
-        $this->PDOStatement = null;
-    }
-
-    /**
-     * 获取PDO对象
-     * @access public
-     * @return \PDO|false
-     */
-    public function getPdo()
-    {
-        if (!$this->linkID) {
-            return false;
-        }
-
-        return $this->linkID;
-    }
-
-    /**
-     * 执行查询 使用生成器返回数据
-     * @access public
-     * @param  string    $sql sql指令
-     * @param  array     $bind 参数绑定
-     * @param  bool      $master 是否在主服务器读操作
-     * @param  Model     $model 模型对象实例
-     * @param  array     $condition 查询条件
-     * @param  mixed     $relation 关联查询
-     * @return \Generator
-     */
-    public function getCursor($sql, $bind = [], $master = false, $model = null, $condition = null, $relation = null)
-    {
-        $this->initConnect($master);
-
-        // 记录SQL语句
-        $this->queryStr = $sql;
-
-        $this->bind = $bind;
-
-        // 释放前次的查询结果
-        if (!empty($this->PDOStatement)) {
-            $this->free();
-        }
-
-        Db::$queryTimes++;
-
-        // 调试开始
-        $this->debug(true);
-
-        // 预处理
-        if (empty($this->PDOStatement)) {
-            $this->PDOStatement = $this->linkID->prepare($sql);
-        }
-
-        // 是否为存储过程调用
-        $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
-
-        // 参数绑定
-        if ($procedure) {
-            $this->bindParam($bind);
-        } else {
-            $this->bindValue($bind);
-        }
-
-        // 执行查询
-        $this->PDOStatement->execute();
-
-        // 调试结束
-        $this->debug(false);
-
-        // 返回结果集
-        while ($result = $this->PDOStatement->fetch($this->fetchType)) {
-            if ($model) {
-                $instance = $model->newInstance($result, $condition);
-
-                if ($relation) {
-                    $instance->relationQuery($relation);
-                }
-
-                yield $instance;
-            } else {
-                yield $result;
-            }
-        }
-    }
-
-    /**
-     * 执行查询 返回数据集
-     * @access public
-     * @param  string    $sql sql指令
-     * @param  array     $bind 参数绑定
-     * @param  bool      $master 是否在主服务器读操作
-     * @param  bool      $pdo 是否返回PDO对象
-     * @return array
-     * @throws BindParamException
-     * @throws \PDOException
-     * @throws \Exception
-     * @throws \Throwable
-     */
-    public function query($sql, $bind = [], $master = false, $pdo = false)
-    {
-        $this->initConnect($master);
-
-        if (!$this->linkID) {
-            return false;
-        }
-
-        // 记录SQL语句
-        $this->queryStr = $sql;
-
-        $this->bind = $bind;
-
-        Db::$queryTimes++;
-
-        try {
-            // 调试开始
-            $this->debug(true);
-
-            // 释放前次的查询结果
-            if (!empty($this->PDOStatement)) {
-                $this->free();
-            }
-
-            // 预处理
-            if (empty($this->PDOStatement)) {
-                $this->PDOStatement = $this->linkID->prepare($sql);
-            }
-
-            // 是否为存储过程调用
-            $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
-
-            // 参数绑定
-            if ($procedure) {
-                $this->bindParam($bind);
-            } else {
-                $this->bindValue($bind);
-            }
-
-            // 执行查询
-            $this->PDOStatement->execute();
-
-            // 调试结束
-            $this->debug(false);
-
-            // 返回结果集
-            return $this->getResult($pdo, $procedure);
-        } catch (\PDOException $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->query($sql, $bind, $master, $pdo);
-            }
-
-            throw new PDOException($e, $this->config, $this->getLastsql());
-        } catch (\Throwable $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->query($sql, $bind, $master, $pdo);
-            }
-
-            throw $e;
-        } catch (\Exception $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->query($sql, $bind, $master, $pdo);
-            }
-
-            throw $e;
-        }
-    }
-
-    /**
-     * 执行语句
-     * @access public
-     * @param  string        $sql sql指令
-     * @param  array         $bind 参数绑定
-     * @return int
-     * @throws BindParamException
-     * @throws \PDOException
-     * @throws \Exception
-     * @throws \Throwable
-     */
-    public function execute($sql, $bind = [])
-    {
-        $this->initConnect(true);
-
-        if (!$this->linkID) {
-            return false;
-        }
-
-        // 记录SQL语句
-        $this->queryStr = $sql;
-
-        $this->bind = $bind;
-
-        Db::$executeTimes++;
-        try {
-            // 调试开始
-            $this->debug(true);
-
-            //释放前次的查询结果
-            if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
-                $this->free();
-            }
-
-            // 预处理
-            if (empty($this->PDOStatement)) {
-                $this->PDOStatement = $this->linkID->prepare($sql);
-            }
-
-            // 是否为存储过程调用
-            $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
-
-            // 参数绑定
-            if ($procedure) {
-                $this->bindParam($bind);
-            } else {
-                $this->bindValue($bind);
-            }
-
-            // 执行语句
-            $this->PDOStatement->execute();
-
-            // 调试结束
-            $this->debug(false);
-
-            $this->numRows = $this->PDOStatement->rowCount();
-
-            return $this->numRows;
-        } catch (\PDOException $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->execute($sql, $bind);
-            }
-
-            throw new PDOException($e, $this->config, $this->getLastsql());
-        } catch (\Throwable $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->execute($sql, $bind);
-            }
-
-            throw $e;
-        } catch (\Exception $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->execute($sql, $bind);
-            }
-
-            throw $e;
-        }
-    }
-
-    /**
-     * 查找单条记录
-     * @access public
-     * @param  Query  $query        查询对象
-     * @return array|null|\PDOStatement|string
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function find(Query $query)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-        $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]);
-        }
-
-        $data = $options['data'];
-
-        if (empty($options['fetch_sql']) && !empty($options['cache'])) {
-            // 判断查询缓存
-            $cache = $options['cache'];
-
-            if (is_string($cache['key'])) {
-                $key = $cache['key'];
-            } elseif (!isset($key)) {
-                $key = $this->getCacheKey($query, $data);
-            }
-
-            $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;
-            } 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);
-        }
-
-        // 事件回调
-        $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;
-        }
-
-        if (isset($cache) && $result) {
-            // 缓存数据
-            $this->cacheData($key, $result, $cache);
-        }
-
-        return $result;
-    }
-
-    /**
-     * 使用游标查询记录
-     * @access public
-     * @param  Query   $query        查询对象
-     * @return \Generator
-     */
-    public function cursor(Query $query)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-
-        // 生成查询SQL
-        $sql = $this->builder->select($query);
-
-        $bind = $query->getBind();
-
-        $condition = isset($options['where']['AND']) ? $options['where']['AND'] : null;
-        $relation  = isset($options['relaltion']) ? $options['relation'] : null;
-
-        // 执行查询操作
-        return $this->getCursor($sql, $bind, $options['master'], $query->getModel(), $condition, $relation);
-    }
-
-    /**
-     * 查找记录
-     * @access public
-     * @param  Query   $query        查询对象
-     * @return array|\PDOStatement|string
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function select(Query $query)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-
-        if (empty($options['fetch_sql']) && !empty($options['cache'])) {
-            $resultSet = $this->getCacheData($query, $options['cache'], null, $key);
-
-            if (false !== $resultSet) {
-                return $resultSet;
-            }
-        }
-
-        // 生成查询SQL
-        $sql = $this->builder->select($query);
-
-        $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 (!empty($options['cache']) && false !== $resultSet) {
-            // 缓存数据集
-            $this->cacheData($key, $resultSet, $options['cache']);
-        }
-
-        return $resultSet;
-    }
-
-    /**
-     * 插入记录
-     * @access public
-     * @param  Query   $query        查询对象
-     * @param  boolean $replace      是否replace
-     * @param  boolean $getLastInsID 返回自增主键
-     * @param  string  $sequence     自增序列名
-     * @return integer|string
-     */
-    public function insert(Query $query, $replace = false, $getLastInsID = false, $sequence = null)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-
-        // 生成SQL语句
-        $sql = $this->builder->insert($query, $replace);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 执行操作
-        $result = $this->execute($sql, $bind);
-
-        if ($result) {
-            $sequence  = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
-            $lastInsId = $this->getLastInsID($sequence);
-
-            $data = $options['data'];
-
-            if ($lastInsId) {
-                $pk = $query->getPk($options);
-                if (is_string($pk)) {
-                    $data[$pk] = $lastInsId;
-                }
-            }
-
-            $query->setOption('data', $data);
-
-            $query->trigger('after_insert');
-
-            if ($getLastInsID) {
-                return $lastInsId;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * 批量插入记录
-     * @access public
-     * @param  Query     $query      查询对象
-     * @param  mixed     $dataSet    数据集
-     * @param  bool      $replace    是否replace
-     * @param  integer   $limit      每次写入数据限制
-     * @return integer|string
-     * @throws \Exception
-     * @throws \Throwable
-     */
-    public function insertAll(Query $query, $dataSet = [], $replace = false, $limit = null)
-    {
-        if (!is_array(reset($dataSet))) {
-            return false;
-        }
-
-        $options = $query->getOptions();
-
-        if ($limit) {
-            // 分批写入 自动启动事务支持
-            $this->startTrans();
-
-            try {
-                $array = array_chunk($dataSet, $limit, true);
-                $count = 0;
-
-                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 {
-                        $count += $this->execute($sql, $bind);
-                    }
-                }
-
-                // 提交事务
-                $this->commit();
-            } catch (\Exception $e) {
-                $this->rollback();
-                throw $e;
-            } catch (\Throwable $e) {
-                $this->rollback();
-                throw $e;
-            }
-
-            return isset($fetchSql) ? implode(';', $fetchSql) : $count;
-        }
-
-        $sql  = $this->builder->insertAll($query, $dataSet, $replace);
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            return $this->getRealSql($sql, $bind);
-        }
-
-        return $this->execute($sql, $bind);
-    }
-
-    /**
-     * 通过Select方式插入记录
-     * @access public
-     * @param  Query     $query      查询对象
-     * @param  string    $fields     要插入的数据表字段名
-     * @param  string    $table      要插入的数据表名
-     * @return integer|string
-     * @throws PDOException
-     */
-    public function selectInsert(Query $query, $fields, $table)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-
-        $table = $this->parseSqlTable($table);
-
-        $sql = $this->builder->selectInsert($query, $fields, $table);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            return $this->getRealSql($sql, $bind);
-        }
-
-        return $this->execute($sql, $bind);
-    }
-
-    /**
-     * 更新记录
-     * @access public
-     * @param  Query     $query  查询对象
-     * @return integer|string
-     * @throws Exception
-     * @throws PDOException
-     */
-    public function update(Query $query)
-    {
-        $options = $query->getOptions();
-
-        if (isset($options['cache']) && is_string($options['cache']['key'])) {
-            $key = $options['cache']['key'];
-        }
-
-        $pk   = $query->getPk($options);
-        $data = $options['data'];
-
-        if (empty($options['where'])) {
-            // 如果存在主键数据 则自动作为更新条件
-            if (is_string($pk) && isset($data[$pk])) {
-                $where[$pk] = [$pk, '=', $data[$pk]];
-                if (!isset($key)) {
-                    $key = $this->getCacheKey($query, $data[$pk]);
-                }
-                unset($data[$pk]);
-            } elseif (is_array($pk)) {
-                // 增加复合主键支持
-                foreach ($pk as $field) {
-                    if (isset($data[$field])) {
-                        $where[$field] = [$field, '=', $data[$field]];
-                    } else {
-                        // 如果缺少复合主键数据则不执行
-                        throw new Exception('miss complex primary data');
-                    }
-                    unset($data[$field]);
-                }
-            }
-
-            if (!isset($where)) {
-                // 如果没有任何更新条件则不执行
-                throw new Exception('miss update condition');
-            } else {
-                $options['where']['AND'] = $where;
-                $query->setOption('where', ['AND' => $where]);
-            }
-        } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) {
-            $key = $this->getCacheKey($query, $options['where']['AND'][$pk]);
-        }
-
-        // 更新数据
-        $query->setOption('data', $data);
-
-        // 生成UPDATE SQL语句
-        $sql  = $this->builder->update($query);
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 检测缓存
-        $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;
-            }
-
-            $query->setOption('data', $data);
-            $query->trigger('after_update');
-        }
-
-        return $result;
-    }
-
-    /**
-     * 删除记录
-     * @access public
-     * @param  Query $query 查询对象
-     * @return int
-     * @throws Exception
-     * @throws PDOException
-     */
-    public function delete(Query $query)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-        $pk      = $query->getPk($options);
-        $data    = $options['data'];
-
-        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);
-        } elseif (is_string($pk) && isset($options['where']['AND'][$pk])) {
-            $key = $this->getCacheKey($query, $options['where']['AND'][$pk]);
-        }
-
-        if (true !== $data && empty($options['where'])) {
-            // 如果条件为空 不进行删除操作 除非设置 1=1
-            throw new Exception('delete without condition');
-        }
-
-        // 生成删除SQL语句
-        $sql = $this->builder->delete($query);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 检测缓存
-        $cache = Container::get('cache');
-
-        if (isset($key) && $cache->get($key)) {
-            // 删除缓存
-            $cache->rm($key);
-        } elseif (!empty($options['cache']['tag'])) {
-            $cache->clear($options['cache']['tag']);
-        }
-
-        // 执行操作
-        $result = $this->execute($sql, $bind);
-
-        if ($result) {
-            if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {
-                list($a, $val) = explode('|', $key);
-                $item[$pk]     = $val;
-                $data          = $item;
-            }
-
-            $options['data'] = $data;
-
-            $query->trigger('after_delete');
-        }
-
-        return $result;
-    }
-
-    /**
-     * 得到某个字段的值
-     * @access public
-     * @param  Query     $query 查询对象
-     * @param  string    $field   字段名
-     * @param  bool      $default   默认值
-     * @return mixed
-     */
-    public function value(Query $query, $field, $default = null)
-    {
-        $options = $query->getOptions();
-
-        if (empty($options['fetch_sql']) && !empty($options['cache'])) {
-
-            $result = $this->getCacheData($query, $options['cache'], $field, $key);
-
-            if (false !== $result) {
-                return $result;
-            }
-        }
-
-        if (isset($options['field'])) {
-            $query->removeOption('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);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 执行查询操作
-        $pdo = $this->query($sql, $bind, $options['master'], true);
-
-        $result = $pdo->fetchColumn();
-
-        if (isset($cache) && false !== $result) {
-            // 缓存数据
-            $this->cacheData($key, $result, $cache);
-        }
-
-        return false !== $result ? $result : $default;
-    }
-
-    /**
-     * 得到某个字段的值
-     * @access public
-     * @param  Query     $query     查询对象
-     * @param  string    $aggregate 聚合方法
-     * @param  string    $field     字段名
-     * @return mixed
-     */
-    public function aggregate(Query $query, $aggregate, $field)
-    {
-        $field = $aggregate . '(' . $this->builder->parseKey($query, $field) . ') AS tp_' . strtolower($aggregate);
-
-        return $this->value($query, $field, 0);
-    }
-
-    /**
-     * 得到某个列的数组
-     * @access public
-     * @param  Query     $query 查询对象
-     * @param  string    $field 字段名 多个字段用逗号分隔
-     * @param  string    $key   索引
-     * @return array
-     */
-    public function column(Query $query, $field, $key = '')
-    {
-        $options = $query->getOptions();
-
-        if (empty($options['fetch_sql']) && !empty($options['cache'])) {
-            // 判断查询缓存
-            $cache = $options['cache'];
-
-            $guid = is_string($cache['key']) ? $cache['key'] : $this->getCacheKey($query, $field);
-
-            $result = Container::get('cache')->get($guid);
-
-            if (false !== $result) {
-                return $result;
-            }
-        }
-
-        if (isset($options['field'])) {
-            $query->removeOption('field');
-        }
-
-        if (is_null($field)) {
-            $field = '*';
-        } elseif ($key && '*' != $field) {
-            $field = $key . ',' . $field;
-        }
-
-        if (is_string($field)) {
-            $field = array_map('trim', explode(',', $field));
-        }
-
-        $query->setOption('field', $field);
-
-        // 生成查询SQL
-        $sql = $this->builder->select($query);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 执行查询操作
-        $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);
-            } else {
-                $result = [];
-            }
-        }
-
-        if (isset($cache) && isset($guid)) {
-            // 缓存数据
-            $this->cacheData($guid, $result, $cache);
-        }
-
-        return $result;
-    }
-
-    /**
-     * 执行查询但只返回PDOStatement对象
-     * @access public
-     * @return \PDOStatement|string
-     */
-    public function pdo(Query $query)
-    {
-        // 分析查询表达式
-        $options = $query->getOptions();
-
-        // 生成查询SQL
-        $sql = $this->builder->select($query);
-
-        $bind = $query->getBind();
-
-        if (!empty($options['fetch_sql'])) {
-            // 获取实际执行的SQL语句
-            return $this->getRealSql($sql, $bind);
-        }
-
-        // 执行查询操作
-        return $this->query($sql, $bind, $options['master'], true);
-    }
-
-    /**
-     * 根据参数绑定组装最终的SQL语句 便于调试
-     * @access public
-     * @param  string    $sql 带参数绑定的sql语句
-     * @param  array     $bind 参数绑定列表
-     * @return string
-     */
-    public function getRealSql($sql, array $bind = [])
-    {
-        if (is_array($sql)) {
-            $sql = implode(';', $sql);
-        }
-
-        foreach ($bind as $key => $val) {
-            $value = is_array($val) ? $val[0] : $val;
-            $type  = is_array($val) ? $val[1] : PDO::PARAM_STR;
-
-            if (PDO::PARAM_STR == $type) {
-                $value = '\'' . addslashes($value) . '\'';
-            } elseif (PDO::PARAM_INT == $type) {
-                $value = (float) $value;
-            }
-
-            // 判断占位符
-            $sql = is_numeric($key) ?
-            substr_replace($sql, $value, strpos($sql, '?'), 1) :
-            str_replace(
-                [':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL],
-                [$value . ')', $value . ',', $value . ' ', $value . PHP_EOL],
-                $sql . ' ');
-        }
-
-        return rtrim($sql);
-    }
-
-    /**
-     * 参数绑定
-     * 支持 ['name'=>'value','id'=>123] 对应命名占位符
-     * 或者 ['value',123] 对应问号占位符
-     * @access public
-     * @param  array $bind 要绑定的参数列表
-     * @return void
-     * @throws BindParamException
-     */
-    protected function bindValue(array $bind = [])
-    {
-        foreach ($bind as $key => $val) {
-            // 占位符
-            $param = is_numeric($key) ? $key + 1 : ':' . $key;
-
-            if (is_array($val)) {
-                if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {
-                    $val[0] = 0;
-                }
-                $result = $this->PDOStatement->bindValue($param, $val[0], $val[1]);
-            } else {
-                $result = $this->PDOStatement->bindValue($param, $val);
-            }
-
-            if (!$result) {
-                throw new BindParamException(
-                    "Error occurred  when binding parameters '{$param}'",
-                    $this->config,
-                    $this->getLastsql(),
-                    $bind
-                );
-            }
-        }
-    }
-
-    /**
-     * 存储过程的输入输出参数绑定
-     * @access public
-     * @param  array $bind 要绑定的参数列表
-     * @return void
-     * @throws BindParamException
-     */
-    protected function bindParam($bind)
-    {
-        foreach ($bind as $key => $val) {
-            $param = is_numeric($key) ? $key + 1 : ':' . $key;
-
-            if (is_array($val)) {
-                array_unshift($val, $param);
-                $result = call_user_func_array([$this->PDOStatement, 'bindParam'], $val);
-            } else {
-                $result = $this->PDOStatement->bindValue($param, $val);
-            }
-
-            if (!$result) {
-                $param = array_shift($val);
-
-                throw new BindParamException(
-                    "Error occurred  when binding parameters '{$param}'",
-                    $this->config,
-                    $this->getLastsql(),
-                    $bind
-                );
-            }
-        }
-    }
-
-    /**
-     * 获得数据集数组
-     * @access protected
-     * @param  bool   $pdo 是否返回PDOStatement
-     * @param  bool   $procedure 是否存储过程
-     * @return array
-     */
-    protected function getResult($pdo = false, $procedure = false)
-    {
-        if ($pdo) {
-            // 返回PDOStatement对象处理
-            return $this->PDOStatement;
-        }
-
-        if ($procedure) {
-            // 存储过程返回结果
-            return $this->procedure();
-        }
-
-        $result = $this->PDOStatement->fetchAll($this->fetchType);
-
-        $this->numRows = count($result);
-
-        return $result;
-    }
-
-    /**
-     * 获得存储过程数据集
-     * @access protected
-     * @return array
-     */
-    protected function procedure()
-    {
-        $item = [];
-
-        do {
-            $result = $this->getResult();
-            if ($result) {
-                $item[] = $result;
-            }
-        } while ($this->PDOStatement->nextRowset());
-
-        $this->numRows = count($item);
-
-        return $item;
-    }
-
-    /**
-     * 执行数据库事务
-     * @access public
-     * @param  callable $callback 数据操作方法回调
-     * @return mixed
-     * @throws PDOException
-     * @throws \Exception
-     * @throws \Throwable
-     */
-    public function transaction($callback)
-    {
-        $this->startTrans();
-
-        try {
-            $result = null;
-            if (is_callable($callback)) {
-                $result = call_user_func_array($callback, [$this]);
-            }
-
-            $this->commit();
-            return $result;
-        } catch (\Exception $e) {
-            $this->rollback();
-            throw $e;
-        } catch (\Throwable $e) {
-            $this->rollback();
-            throw $e;
-        }
-    }
-
-    /**
-     * 启动事务
-     * @access public
-     * @return void
-     * @throws \PDOException
-     * @throws \Exception
-     */
-    public function startTrans()
-    {
-        $this->initConnect(true);
-        if (!$this->linkID) {
-            return false;
-        }
-
-        ++$this->transTimes;
-
-        try {
-            if (1 == $this->transTimes) {
-                $this->linkID->beginTransaction();
-            } elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
-                $this->linkID->exec(
-                    $this->parseSavepoint('trans' . $this->transTimes)
-                );
-            }
-        } catch (\PDOException $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->startTrans();
-            }
-            throw $e;
-        } catch (\Exception $e) {
-            if ($this->isBreak($e)) {
-                return $this->close()->startTrans();
-            }
-            throw $e;
-        }
-    }
-
-    /**
-     * 用于非自动提交状态下面的查询提交
-     * @access public
-     * @return void
-     * @throws PDOException
-     */
-    public function commit()
-    {
-        $this->initConnect(true);
-
-        if (1 == $this->transTimes) {
-            $this->linkID->commit();
-        }
-
-        --$this->transTimes;
-    }
-
-    /**
-     * 事务回滚
-     * @access public
-     * @return void
-     * @throws PDOException
-     */
-    public function rollback()
-    {
-        $this->initConnect(true);
-
-        if (1 == $this->transTimes) {
-            $this->linkID->rollBack();
-        } elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
-            $this->linkID->exec(
-                $this->parseSavepointRollBack('trans' . $this->transTimes)
-            );
-        }
-
-        $this->transTimes = max(0, $this->transTimes - 1);
-    }
-
-    /**
-     * 是否支持事务嵌套
-     * @return bool
-     */
-    protected function supportSavepoint()
-    {
-        return false;
-    }
-
-    /**
-     * 生成定义保存点的SQL
-     * @access protected
-     * @param  $name
-     * @return string
-     */
-    protected function parseSavepoint($name)
-    {
-        return 'SAVEPOINT ' . $name;
-    }
-
-    /**
-     * 生成回滚到保存点的SQL
-     * @access protected
-     * @param  $name
-     * @return string
-     */
-    protected function parseSavepointRollBack($name)
-    {
-        return 'ROLLBACK TO SAVEPOINT ' . $name;
-    }
-
-    /**
-     * 批处理执行SQL语句
-     * 批处理的指令都认为是execute操作
-     * @access public
-     * @param  array $sqlArray   SQL批处理指令
-     * @param  array $bind       参数绑定
-     * @return boolean
-     */
-    public function batchQuery($sqlArray = [], $bind = [])
-    {
-        if (!is_array($sqlArray)) {
-            return false;
-        }
-
-        // 自动启动事务支持
-        $this->startTrans();
-
-        try {
-            foreach ($sqlArray as $sql) {
-                $this->execute($sql, $bind);
-            }
-            // 提交事务
-            $this->commit();
-        } catch (\Exception $e) {
-            $this->rollback();
-            throw $e;
-        }
-
-        return true;
-    }
-
-    /**
-     * 获得查询次数
-     * @access public
-     * @param  boolean $execute 是否包含所有查询
-     * @return integer
-     */
-    public function getQueryTimes($execute = false)
-    {
-        return $execute ? Db::$queryTimes + Db::$executeTimes : Db::$queryTimes;
-    }
-
-    /**
-     * 获得执行次数
-     * @access public
-     * @return integer
-     */
-    public function getExecuteTimes()
-    {
-        return Db::$executeTimes;
-    }
-
-    /**
-     * 关闭数据库(或者重新连接)
-     * @access public
-     * @return $this
-     */
-    public function close()
-    {
-        $this->linkID    = null;
-        $this->linkWrite = null;
-        $this->linkRead  = null;
-        $this->links     = [];
-
-        return $this;
-    }
-
-    /**
-     * 是否断线
-     * @access protected
-     * @param  \PDOException|\Exception  $e 异常对象
-     * @return bool
-     */
-    protected function isBreak($e)
-    {
-        if (!$this->config['break_reconnect']) {
-            return false;
-        }
-
-        $error = $e->getMessage();
-
-        foreach ($this->breakMatchStr as $msg) {
-            if (false !== stripos($error, $msg)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 获取最近一次查询的sql语句
-     * @access public
-     * @return string
-     */
-    public function getLastSql()
-    {
-        return $this->getRealSql($this->queryStr, $this->bind);
-    }
-
-    /**
-     * 获取最近插入的ID
-     * @access public
-     * @param  string  $sequence     自增序列名
-     * @return string
-     */
-    public function getLastInsID($sequence = null)
-    {
-        return $this->linkID->lastInsertId($sequence);
-    }
-
-    /**
-     * 获取返回或者影响的记录数
-     * @access public
-     * @return integer
-     */
-    public function getNumRows()
-    {
-        return $this->numRows;
-    }
-
-    /**
-     * 获取最近的错误信息
-     * @access public
-     * @return string
-     */
-    public function getError()
-    {
-        if ($this->PDOStatement) {
-            $error = $this->PDOStatement->errorInfo();
-            $error = $error[1] . ':' . $error[2];
-        } else {
-            $error = '';
-        }
-
-        if ('' != $this->queryStr) {
-            $error .= "\n [ SQL语句 ] : " . $this->getLastsql();
-        }
-
-        return $error;
-    }
-
-    /**
-     * 数据库调试 记录当前SQL及分析性能
-     * @access protected
-     * @param  boolean $start 调试开始标记 true 开始 false 结束
-     * @param  string  $sql 执行的SQL语句 留空自动获取
-     * @return void
-     */
-    protected function debug($start, $sql = '')
-    {
-        if (!empty($this->config['debug'])) {
-            // 开启数据库调试模式
-            $debug = Container::get('debug');
-
-            if ($start) {
-                $debug->remark('queryStartTime', 'time');
-            } else {
-                // 记录操作结束时间
-                $debug->remark('queryEndTime', 'time');
-                $runtime = $debug->getRangeTime('queryStartTime', 'queryEndTime');
-                $sql     = $sql ?: $this->getLastsql();
-                $result  = [];
-
-                // SQL性能分析
-                if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) {
-                    $result = $this->getExplain($sql);
-                }
-
-                // SQL监听
-                $this->triggerSql($sql, $runtime, $result);
-            }
-        }
-    }
-
-    /**
-     * 监听SQL执行
-     * @access public
-     * @param  callable $callback 回调方法
-     * @return void
-     */
-    public function listen($callback)
-    {
-        self::$event[] = $callback;
-    }
-
-    /**
-     * 触发SQL事件
-     * @access protected
-     * @param  string    $sql SQL语句
-     * @param  float     $runtime SQL运行时间
-     * @param  mixed     $explain SQL分析
-     * @return bool
-     */
-    protected function triggerSql($sql, $runtime, $explain = [])
-    {
-        if (!empty(self::$event)) {
-            foreach (self::$event as $callback) {
-                if (is_callable($callback)) {
-                    call_user_func_array($callback, [$sql, $runtime, $explain]);
-                }
-            }
-        } else {
-            // 未注册监听则记录到日志中
-            $this->log('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]');
-
-            if (!empty($explain)) {
-                $this->log('[ EXPLAIN : ' . var_export($explain, true) . ' ]');
-            }
-        }
-    }
-
-    public function log($log, $type = 'sql')
-    {
-        $this->config['debug'] && Container::get('log')->record($log, $type);
-    }
-
-    /**
-     * 初始化数据库连接
-     * @access protected
-     * @param  boolean $master 是否主服务器
-     * @return void
-     */
-    protected function initConnect($master = true)
-    {
-        if (!empty($this->config['deploy'])) {
-            // 采用分布式数据库
-            if ($master || $this->transTimes) {
-                if (!$this->linkWrite) {
-                    $this->linkWrite = $this->multiConnect(true);
-                }
-
-                $this->linkID = $this->linkWrite;
-            } else {
-                if (!$this->linkRead) {
-                    $this->linkRead = $this->multiConnect(false);
-                }
-
-                $this->linkID = $this->linkRead;
-            }
-        } elseif (!$this->linkID) {
-            // 默认单数据库
-            $this->linkID = $this->connect();
-        }
-    }
-
-    /**
-     * 连接分布式服务器
-     * @access protected
-     * @param  boolean $master 主服务器
-     * @return PDO
-     */
-    protected function multiConnect($master = false)
-    {
-        $_config = [];
-
-        // 分布式数据库配置解析
-        foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {
-            $_config[$name] = explode(',', $this->config[$name]);
-        }
-
-        // 主服务器序号
-        $m = floor(mt_rand(0, $this->config['master_num'] - 1));
-
-        if ($this->config['rw_separate']) {
-            // 主从式采用读写分离
-            if ($master) // 主服务器写入
-            {
-                $r = $m;
-            } elseif (is_numeric($this->config['slave_no'])) {
-                // 指定服务器读
-                $r = $this->config['slave_no'];
-            } else {
-                // 读操作连接从服务器 每次随机连接的数据库
-                $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1));
-            }
-        } else {
-            // 读写操作不区分服务器 每次随机连接的数据库
-            $r = floor(mt_rand(0, count($_config['hostname']) - 1));
-        }
-        $dbMaster = false;
-
-        if ($m != $r) {
-            $dbMaster = [];
-            foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {
-                $dbMaster[$name] = isset($_config[$name][$m]) ? $_config[$name][$m] : $_config[$name][0];
-            }
-        }
-
-        $dbConfig = [];
-
-        foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {
-            $dbConfig[$name] = isset($_config[$name][$r]) ? $_config[$name][$r] : $_config[$name][0];
-        }
-
-        return $this->connect($dbConfig, $r, $r == $m ? false : $dbMaster);
-    }
-
-    /**
-     * 析构方法
-     * @access public
-     */
-    public function __destruct()
-    {
-        // 释放查询
-        $this->free();
-
-        // 关闭连接
-        $this->close();
-    }
-
-    /**
-     * 缓存数据
-     * @access protected
-     * @param  string    $key    缓存标识
-     * @param  mixed     $data   缓存数据
-     * @param  array     $config 缓存参数
-     */
-    protected function cacheData($key, $data, $config = [])
-    {
-        $cache = Container::get('cache');
-
-        if (isset($config['tag'])) {
-            $cache->tag($config['tag'])->set($key, $data, $config['expire']);
-        } else {
-            $cache->set($key, $data, $config['expire']);
-        }
-    }
-
-    /**
-     * 获取缓存数据
-     * @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   缓存数据
-     * @return string
-     */
-    protected function getCacheKey(Query $query, $value)
-    {
-        if (is_scalar($value)) {
-            $data = $value;
-        } elseif (is_array($value) && isset($value[1], $value[2]) && in_array($value[1], ['=', 'eq'], true) && is_scalar($value[2])) {
-            $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) {
-            throw new Exception('closure not support cache(true)');
-        }
-    }
-
-    /**
-     * 数据库连接参数解析
-     * @access private
-     * @param  mixed $config
-     * @return array
-     */
-    private static function parseConfig($config)
-    {
-        if (empty($config)) {
-            $config = Container::get('config')->pull('database');
-        } elseif (is_string($config) && false === strpos($config, '/')) {
-            // 支持读取配置参数
-            $config = Container::get('config')->get('database.' . $config);
-        }
-
-        if (is_string($config)) {
-            return self::parseDsnConfig($config);
-        } else {
-            return $config;
-        }
-    }
-
-    /**
-     * DSN解析
-     * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8
-     * @access private
-     * @param  string $dsnStr
-     * @return array
-     */
-    private static function parseDsnConfig($dsnStr)
-    {
-        $info = parse_url($dsnStr);
-
-        if (!$info) {
-            return [];
-        }
-
-        $dsn = [
-            'type'     => $info['scheme'],
-            'username' => isset($info['user']) ? $info['user'] : '',
-            'password' => isset($info['pass']) ? $info['pass'] : '',
-            'hostname' => isset($info['host']) ? $info['host'] : '',
-            'hostport' => isset($info['port']) ? $info['port'] : '',
-            'database' => !empty($info['path']) ? ltrim($info['path'], '/') : '',
-            'charset'  => isset($info['fragment']) ? $info['fragment'] : 'utf8',
-        ];
-
-        if (isset($info['query'])) {
-            parse_str($info['query'], $dsn['params']);
-        } else {
-            $dsn['params'] = [];
-        }
-
-        return $dsn;
-    }
-
-}

+ 0 - 48
thinkphp/library/think/db/Expression.php

@@ -1,48 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db;
-
-class Expression
-{
-    /**
-     * 查询表达式
-     *
-     * @var string
-     */
-    protected $value;
-
-    /**
-     * 创建一个查询表达式
-     *
-     * @param  string  $value
-     * @return void
-     */
-    public function __construct($value)
-    {
-        $this->value = $value;
-    }
-
-    /**
-     * 获取表达式
-     *
-     * @return string
-     */
-    public function getValue()
-    {
-        return $this->value;
-    }
-
-    public function __toString()
-    {
-        return (string) $this->value;
-    }
-}

+ 0 - 3143
thinkphp/library/think/db/Query.php

@@ -1,3143 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db;
-
-use PDO;
-use think\Collection;
-use think\Container;
-use think\db\exception\BindParamException;
-use think\db\exception\DataNotFoundException;
-use think\db\exception\ModelNotFoundException;
-use think\Exception;
-use think\exception\DbException;
-use think\exception\PDOException;
-use think\Loader;
-use think\Model;
-use think\model\Relation;
-use think\model\relation\OneToOne;
-use think\Paginator;
-
-class Query
-{
-    /**
-     * 数据库连接对象列表
-     * @var array
-     */
-    protected static $connections = [];
-
-    /**
-     * 当前数据库连接对象
-     * @var Connection
-     */
-    protected $connection;
-
-    /**
-     * 当前模型对象
-     * @var Model
-     */
-    protected $model;
-
-    /**
-     * 当前数据表名称(不含前缀)
-     * @var string
-     */
-    protected $name = '';
-
-    /**
-     * 当前数据表主键
-     * @var string|array
-     */
-    protected $pk;
-
-    /**
-     * 当前数据表前缀
-     * @var string
-     */
-    protected $prefix = '';
-
-    /**
-     * 当前查询参数
-     * @var array
-     */
-    protected $options = [];
-
-    /**
-     * 当前参数绑定
-     * @var array
-     */
-    protected $bind = [];
-
-    /**
-     * 事件回调
-     * @var array
-     */
-    private static $event = [];
-
-    /**
-     * 扩展查询方法
-     * @var array
-     */
-    private static $extend = [];
-
-    /**
-     * 日期查询表达式
-     * @var array
-     */
-    protected $timeRule = [
-        'today'      => ['today', 'tomorrow'],
-        'yesterday'  => ['yesterday', 'today'],
-        'week'       => ['this week 00:00:00', 'next week 00:00:00'],
-        'last week'  => ['last week 00:00:00', 'this week 00:00:00'],
-        'month'      => ['first Day of this month 00:00:00', 'first Day of next month 00:00:00'],
-        'last month' => ['first Day of last month 00:00:00', 'first Day of this month 00:00:00'],
-        'year'       => ['this year 1/1', 'next year 1/1'],
-        'last year'  => ['last year 1/1', 'this year 1/1'],
-    ];
-
-    /**
-     * 日期查询快捷定义
-     * @var array
-     */
-    protected $timeExp = ['d' => 'today', 'w' => 'week', 'm' => 'month', 'y' => 'year'];
-
-    /**
-     * 架构函数
-     * @access public
-     */
-    public function __construct(Connection $connection = null)
-    {
-        if (is_null($connection)) {
-            $this->connection = Connection::instance();
-        } else {
-            $this->connection = $connection;
-        }
-
-        $this->prefix = $this->connection->getConfig('prefix');
-    }
-
-    /**
-     * 创建一个新的查询对象
-     * @access public
-     * @return Query
-     */
-    public function newQuery()
-    {
-        return new static($this->connection);
-    }
-
-    /**
-     * 利用__call方法实现一些特殊的Model方法
-     * @access public
-     * @param  string $method 方法名称
-     * @param  array  $args   调用参数
-     * @return mixed
-     * @throws DbException
-     * @throws Exception
-     */
-    public function __call($method, $args)
-    {
-        if (isset(self::$extend[strtolower($method)])) {
-            // 调用扩展查询方法
-            array_unshift($args, $this);
-
-            return Container::getInstance()->invoke(self::$extend[strtolower($method)], $args);
-        } elseif (strtolower(substr($method, 0, 5)) == 'getby') {
-            // 根据某个字段获取记录
-            $field = Loader::parseName(substr($method, 5));
-            return $this->where($field, '=', $args[0])->find();
-        } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') {
-            // 根据某个字段获取记录的某个值
-            $name = Loader::parseName(substr($method, 10));
-            return $this->where($name, '=', $args[0])->value($args[1]);
-        } elseif (strtolower(substr($method, 0, 7)) == 'whereor') {
-            $name = Loader::parseName(substr($method, 7));
-            array_unshift($args, $name);
-            return call_user_func_array([$this, 'whereOr'], $args);
-        } elseif (strtolower(substr($method, 0, 5)) == 'where') {
-            $name = Loader::parseName(substr($method, 5));
-            array_unshift($args, $name);
-            return call_user_func_array([$this, 'where'], $args);
-        } elseif ($this->model && method_exists($this->model, 'scope' . $method)) {
-            // 动态调用命名范围
-            $method = 'scope' . $method;
-            array_unshift($args, $this);
-
-            call_user_func_array([$this->model, $method], $args);
-            return $this;
-        } else {
-            throw new Exception('method not exist:' . static::class . '->' . $method);
-        }
-    }
-
-    /**
-     * 扩展查询方法
-     * @access public
-     * @param  string|array  $method     查询方法名
-     * @param  callable      $callback
-     * @return void
-     */
-    public static function extend($method, $callback = null)
-    {
-        if (is_array($method)) {
-            foreach ($method as $key => $val) {
-                self::$extend[strtolower($key)] = $val;
-            }
-        } else {
-            self::$extend[strtolower($method)] = $callback;
-        }
-    }
-
-    /**
-     * 设置当前的数据库Connection对象
-     * @access public
-     * @param  Connection      $connection
-     * @return $this
-     */
-    public function setConnection(Connection $connection)
-    {
-        $this->connection = $connection;
-        $this->prefix     = $this->connection->getConfig('prefix');
-
-        return $this;
-    }
-
-    /**
-     * 获取当前的数据库Connection对象
-     * @access public
-     * @return Connection
-     */
-    public function getConnection()
-    {
-        return $this->connection;
-    }
-
-    /**
-     * 指定模型
-     * @access public
-     * @param  Model $model 模型对象实例
-     * @return $this
-     */
-    public function model(Model $model)
-    {
-        $this->model = $model;
-        return $this;
-    }
-
-    /**
-     * 获取当前的模型对象
-     * @access public
-     * @return Model|null
-     */
-    public function getModel()
-    {
-        return $this->model ? $this->model->setQuery($this) : null;
-    }
-
-    /**
-     * 指定当前数据表名(不含前缀)
-     * @access public
-     * @param  string $name
-     * @return $this
-     */
-    public function name($name)
-    {
-        $this->name = $name;
-        return $this;
-    }
-
-    /**
-     * 获取当前的数据表名称
-     * @access public
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name ?: $this->model->getName();
-    }
-
-    /**
-     * 得到当前或者指定名称的数据表
-     * @access public
-     * @param  string $name
-     * @return string
-     */
-    public function getTable($name = '')
-    {
-        if (empty($name) && isset($this->options['table'])) {
-            return $this->options['table'];
-        }
-
-        $name = $name ?: $this->name;
-
-        return $this->prefix . Loader::parseName($name);
-    }
-
-    /**
-     * 切换数据库连接
-     * @access public
-     * @param  mixed         $config 连接配置
-     * @param  bool|string   $name 连接标识 true 强制重新连接
-     * @return $this|object
-     * @throws Exception
-     */
-    public function connect($config = [], $name = false)
-    {
-        $this->connection = Connection::instance($config, $name);
-
-        $query = $this->connection->getConfig('query');
-
-        if (__CLASS__ != trim($query, '\\')) {
-            return new $query($this->connection);
-        }
-
-        $this->prefix = $this->connection->getConfig('prefix');
-
-        return $this;
-    }
-
-    /**
-     * 执行查询 返回数据集
-     * @access public
-     * @param  string      $sql    sql指令
-     * @param  array       $bind   参数绑定
-     * @param  boolean     $master 是否在主服务器读操作
-     * @param  bool|string $class  指定返回的数据集对象
-     * @return mixed
-     * @throws BindParamException
-     * @throws PDOException
-     */
-    public function query($sql, $bind = [], $master = false, $class = false)
-    {
-        return $this->connection->query($sql, $bind, $master, $class);
-    }
-
-    /**
-     * 执行语句
-     * @access public
-     * @param  string $sql  sql指令
-     * @param  array  $bind 参数绑定
-     * @return int
-     * @throws BindParamException
-     * @throws PDOException
-     */
-    public function execute($sql, $bind = [])
-    {
-        return $this->connection->execute($sql, $bind);
-    }
-
-    /**
-     * 监听SQL执行
-     * @access public
-     * @param  callable $callback 回调方法
-     * @return void
-     */
-    public function listen($callback)
-    {
-        $this->connection->listen($callback);
-    }
-
-    /**
-     * 获取最近插入的ID
-     * @access public
-     * @param  string $sequence 自增序列名
-     * @return string
-     */
-    public function getLastInsID($sequence = null)
-    {
-        return $this->connection->getLastInsID($sequence);
-    }
-
-    /**
-     * 获取返回或者影响的记录数
-     * @access public
-     * @return integer
-     */
-    public function getNumRows()
-    {
-        return $this->connection->getNumRows();
-    }
-
-    /**
-     * 获取最近一次查询的sql语句
-     * @access public
-     * @return string
-     */
-    public function getLastSql()
-    {
-        return $this->connection->getLastSql();
-    }
-
-    /**
-     * 执行数据库事务
-     * @access public
-     * @param  callable $callback 数据操作方法回调
-     * @return mixed
-     */
-    public function transaction($callback)
-    {
-        return $this->connection->transaction($callback);
-    }
-
-    /**
-     * 启动事务
-     * @access public
-     * @return void
-     */
-    public function startTrans()
-    {
-        $this->connection->startTrans();
-    }
-
-    /**
-     * 用于非自动提交状态下面的查询提交
-     * @access public
-     * @return void
-     * @throws PDOException
-     */
-    public function commit()
-    {
-        $this->connection->commit();
-    }
-
-    /**
-     * 事务回滚
-     * @access public
-     * @return void
-     * @throws PDOException
-     */
-    public function rollback()
-    {
-        $this->connection->rollback();
-    }
-
-    /**
-     * 批处理执行SQL语句
-     * 批处理的指令都认为是execute操作
-     * @access public
-     * @param  array $sql SQL批处理指令
-     * @return boolean
-     */
-    public function batchQuery($sql = [])
-    {
-        return $this->connection->batchQuery($sql);
-    }
-
-    /**
-     * 获取数据库的配置参数
-     * @access public
-     * @param  string $name 参数名称
-     * @return mixed
-     */
-    public function getConfig($name = '')
-    {
-        return $this->connection->getConfig($name);
-    }
-
-    /**
-     * 获取数据表字段信息
-     * @access public
-     * @param  string $tableName 数据表名
-     * @return array
-     */
-    public function getTableFields($tableName = '')
-    {
-        if ('' == $tableName) {
-            $tableName = isset($this->options['table']) ? $this->options['table'] : $this->getTable();
-        }
-
-        return $this->connection->getTableFields($tableName);
-    }
-
-    /**
-     * 获取数据表字段类型
-     * @access public
-     * @param  string $tableName 数据表名
-     * @param  string $field    字段名
-     * @return array|string
-     */
-    public function getFieldsType($tableName = '', $field = null)
-    {
-        if ('' == $tableName) {
-            $tableName = isset($this->options['table']) ? $this->options['table'] : $this->getTable();
-        }
-
-        return $this->connection->getFieldsType($tableName, $field);
-    }
-
-    /**
-     * 得到分表的的数据表名
-     * @access public
-     * @param  array  $data  操作的数据
-     * @param  string $field 分表依据的字段
-     * @param  array  $rule  分表规则
-     * @return string
-     */
-    public function getPartitionTableName($data, $field, $rule = [])
-    {
-        // 对数据表进行分区
-        if ($field && isset($data[$field])) {
-            $value = $data[$field];
-            $type  = $rule['type'];
-            switch ($type) {
-                case 'id':
-                    // 按照id范围分表
-                    $step = $rule['expr'];
-                    $seq  = floor($value / $step) + 1;
-                    break;
-                case 'year':
-                    // 按照年份分表
-                    if (!is_numeric($value)) {
-                        $value = strtotime($value);
-                    }
-                    $seq = date('Y', $value) - $rule['expr'] + 1;
-                    break;
-                case 'mod':
-                    // 按照id的模数分表
-                    $seq = ($value % $rule['num']) + 1;
-                    break;
-                case 'md5':
-                    // 按照md5的序列分表
-                    $seq = (ord(substr(md5($value), 0, 1)) % $rule['num']) + 1;
-                    break;
-                default:
-                    if (function_exists($type)) {
-                        // 支持指定函数哈希
-                        $seq = (ord(substr($type($value), 0, 1)) % $rule['num']) + 1;
-                    } else {
-                        // 按照字段的首字母的值分表
-                        $seq = (ord($value{0}) % $rule['num']) + 1;
-                    }
-            }
-            return $this->getTable() . '_' . $seq;
-        }
-        // 当设置的分表字段不在查询条件或者数据中
-        // 进行联合查询,必须设定 partition['num']
-        $tableName = [];
-        for ($i = 0; $i < $rule['num']; $i++) {
-            $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1);
-        }
-
-        $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name;
-
-        return $tableName;
-    }
-
-    /**
-     * 得到某个字段的值
-     * @access public
-     * @param  string $field   字段名
-     * @param  mixed  $default 默认值
-     * @return mixed
-     */
-    public function value($field, $default = null)
-    {
-        $this->parseOptions();
-
-        $result = $this->connection->value($this, $field, $default);
-
-        if (!empty($this->options['fetch_sql'])) {
-            return $result;
-        }
-
-        return $result;
-    }
-
-    /**
-     * 得到某个列的数组
-     * @access public
-     * @param  string $field 字段名 多个字段用逗号分隔
-     * @param  string $key   索引
-     * @return array
-     */
-    public function column($field, $key = '')
-    {
-        $this->parseOptions();
-
-        return $this->connection->column($this, $field, $key);
-    }
-
-    /**
-     * 聚合查询
-     * @access public
-     * @param  string $aggregate    聚合方法
-     * @param  string $field        字段名
-     * @param  bool   $force        强制转为数字类型
-     * @return mixed
-     */
-    public function aggregate($aggregate, $field, $force = false)
-    {
-        $this->parseOptions();
-
-        $result = $this->connection->aggregate($this, $aggregate, $field);
-
-        if (!empty($this->options['fetch_sql'])) {
-            return $result;
-        } elseif ($force) {
-            $result += 0;
-        }
-
-        return $result;
-    }
-
-    /**
-     * COUNT查询
-     * @access public
-     * @param  string $field 字段名
-     * @return integer|string
-     */
-    public function count($field = '*')
-    {
-        if (isset($this->options['group'])) {
-            // 支持GROUP
-            $options = $this->getOptions();
-            $subSql  = $this->options($options)->field('count(' . $field . ') AS think_count')->bind($this->bind)->buildSql();
-
-            $query = $this->newQuery()->table([$subSql => '_group_count_']);
-
-            if (!empty($options['fetch_sql'])) {
-                $query->fetchSql(true);
-            }
-
-            return $query->aggregate('COUNT', '*', true);
-        }
-
-        return $this->aggregate('COUNT', $field, true);
-    }
-
-    /**
-     * SUM查询
-     * @access public
-     * @param  string $field 字段名
-     * @return float|int
-     */
-    public function sum($field)
-    {
-        return $this->aggregate('SUM', $field, true);
-    }
-
-    /**
-     * MIN查询
-     * @access public
-     * @param  string $field    字段名
-     * @param  bool   $force    强制转为数字类型
-     * @return mixed
-     */
-    public function min($field, $force = true)
-    {
-        return $this->aggregate('MIN', $field, $force);
-    }
-
-    /**
-     * MAX查询
-     * @access public
-     * @param  string $field    字段名
-     * @param  bool   $force    强制转为数字类型
-     * @return mixed
-     */
-    public function max($field, $force = true)
-    {
-        return $this->aggregate('MAX', $field, $force);
-    }
-
-    /**
-     * AVG查询
-     * @access public
-     * @param  string $field 字段名
-     * @return float|int
-     */
-    public function avg($field)
-    {
-        return $this->aggregate('AVG', $field, true);
-    }
-
-    /**
-     * 设置记录的某个字段值
-     * 支持使用数据库字段和方法
-     * @access public
-     * @param  string|array $field 字段名
-     * @param  mixed        $value 字段值
-     * @return integer
-     */
-    public function setField($field, $value = '')
-    {
-        if (is_array($field)) {
-            $data = $field;
-        } else {
-            $data[$field] = $value;
-        }
-
-        return $this->update($data);
-    }
-
-    /**
-     * 字段值(延迟)增长
-     * @access public
-     * @param  string  $field    字段名
-     * @param  integer $step     增长值
-     * @param  integer $lazyTime 延时时间(s)
-     * @return integer|true
-     * @throws Exception
-     */
-    public function setInc($field, $step = 1, $lazyTime = 0)
-    {
-        $condition = !empty($this->options['where']) ? $this->options['where'] : [];
-
-        if (empty($condition)) {
-            // 没有条件不做任何更新
-            throw new Exception('no data to update');
-        }
-
-        if ($lazyTime > 0) {
-            // 延迟写入
-            $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));
-            $step = $this->lazyWrite('inc', $guid, $step, $lazyTime);
-
-            if (false === $step) {
-                // 清空查询条件
-                $this->options = [];
-                return true;
-            }
-        }
-
-        return $this->setField($field, ['INC', $step]);
-    }
-
-    /**
-     * 字段值(延迟)减少
-     * @access public
-     * @param  string  $field    字段名
-     * @param  integer $step     减少值
-     * @param  integer $lazyTime 延时时间(s)
-     * @return integer|true
-     * @throws Exception
-     */
-    public function setDec($field, $step = 1, $lazyTime = 0)
-    {
-        $condition = !empty($this->options['where']) ? $this->options['where'] : [];
-
-        if (empty($condition)) {
-            // 没有条件不做任何更新
-            throw new Exception('no data to update');
-        }
-
-        if ($lazyTime > 0) {
-            // 延迟写入
-            $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));
-            $step = $this->lazyWrite('dec', $guid, $step, $lazyTime);
-
-            if (false === $step) {
-                // 清空查询条件
-                $this->options = [];
-                return true;
-            }
-
-            $value = ['INC', $step];
-        } else {
-            $value = ['DEC', $step];
-        }
-
-        return $this->setField($field, $value);
-    }
-
-    /**
-     * 延时更新检查 返回false表示需要延时
-     * 否则返回实际写入的数值
-     * @access protected
-     * @param  string  $type     自增或者自减
-     * @param  string  $guid     写入标识
-     * @param  integer $step     写入步进值
-     * @param  integer $lazyTime 延时时间(s)
-     * @return false|integer
-     */
-    protected function lazyWrite($type, $guid, $step, $lazyTime)
-    {
-        $cache = Container::get('cache');
-
-        if (!$cache->has($guid . '_time')) {
-            // 计时开始
-            $cache->set($guid . '_time', time(), 0);
-            $cache->$type($guid, $step);
-        } elseif (time() > $cache->get($guid . '_time') + $lazyTime) {
-            // 删除缓存
-            $value = $cache->$type($guid, $step);
-            $cache->rm($guid);
-            $cache->rm($guid . '_time');
-            return 0 === $value ? false : $value;
-        } else {
-            // 更新缓存
-            $cache->$type($guid, $step);
-        }
-
-        return false;
-    }
-
-    /**
-     * 查询SQL组装 join
-     * @access public
-     * @param  mixed  $join      关联的表名
-     * @param  mixed  $condition 条件
-     * @param  string $type      JOIN类型
-     * @return $this
-     */
-    public function join($join, $condition = null, $type = 'INNER')
-    {
-        if (empty($condition)) {
-            // 如果为组数,则循环调用join
-            foreach ($join as $key => $value) {
-                if (is_array($value) && 2 <= count($value)) {
-                    $this->join($value[0], $value[1], isset($value[2]) ? $value[2] : $type);
-                }
-            }
-        } else {
-            $table = $this->getJoinTable($join);
-
-            $this->options['join'][] = [$table, strtoupper($type), $condition];
-        }
-
-        return $this;
-    }
-
-    /**
-     * LEFT JOIN
-     * @access public
-     * @param  mixed  $join      关联的表名
-     * @param  mixed  $condition 条件
-     * @return $this
-     */
-    public function leftJoin($join, $condition = null)
-    {
-        return $this->join($join, $condition, 'LEFT');
-    }
-
-    /**
-     * RIGHT JOIN
-     * @access public
-     * @param  mixed  $join      关联的表名
-     * @param  mixed  $condition 条件
-     * @return $this
-     */
-    public function rightJoin($join, $condition = null)
-    {
-        return $this->join($join, $condition, 'RIGHT');
-    }
-
-    /**
-     * FULL JOIN
-     * @access public
-     * @param  mixed  $join      关联的表名
-     * @param  mixed  $condition 条件
-     * @return $this
-     */
-    public function fullJoin($join, $condition = null)
-    {
-        return $this->join($join, $condition, 'FULL');
-    }
-
-    /**
-     * 获取Join表名及别名 支持
-     * ['prefix_table或者子查询'=>'alias'] 'table alias'
-     * @access protected
-     * @param  array|string $join
-     * @param  string       $alias
-     * @return string
-     */
-    protected function getJoinTable($join, &$alias = null)
-    {
-        if (is_array($join)) {
-            $table = $join;
-            $alias = array_shift($join);
-        } else {
-            $join = trim($join);
-
-            if (false !== strpos($join, '(')) {
-                // 使用子查询
-                $table = $join;
-            } else {
-                $prefix = $this->prefix;
-                if (strpos($join, ' ')) {
-                    // 使用别名
-                    list($table, $alias) = explode(' ', $join);
-                } else {
-                    $table = $join;
-                    if (false === strpos($join, '.') && 0 !== strpos($join, '__')) {
-                        $alias = $join;
-                    }
-                }
-
-                if ($prefix && false === strpos($table, '.') && 0 !== strpos($table, $prefix) && 0 !== strpos($table, '__')) {
-                    $table = $this->getTable($table);
-                }
-            }
-
-            if (isset($alias) && $table != $alias) {
-                $table = [$table => $alias];
-            }
-        }
-
-        return $table;
-    }
-
-    /**
-     * 查询SQL组装 union
-     * @access public
-     * @param  mixed   $union
-     * @param  boolean $all
-     * @return $this
-     */
-    public function union($union, $all = false)
-    {
-        $this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION';
-
-        if (is_array($union)) {
-            $this->options['union'] = array_merge($this->options['union'], $union);
-        } else {
-            $this->options['union'][] = $union;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 查询SQL组装 union all
-     * @access public
-     * @param  mixed   $union
-     * @return $this
-     */
-    public function unionAll($union)
-    {
-        return $this->union($union, true);
-    }
-
-    /**
-     * 指定查询字段 支持字段排除和指定数据表
-     * @access public
-     * @param  mixed   $field
-     * @param  boolean $except    是否排除
-     * @param  string  $tableName 数据表名
-     * @param  string  $prefix    字段前缀
-     * @param  string  $alias     别名前缀
-     * @return $this
-     */
-    public function field($field, $except = false, $tableName = '', $prefix = '', $alias = '')
-    {
-        if (empty($field)) {
-            return $this;
-        } elseif ($field instanceof Expression) {
-            $this->options['field'][] = $field;
-            return $this;
-        }
-
-        if (is_string($field)) {
-            if (preg_match('/[\<\'\"\(]/', $field)) {
-                return $this->fieldRaw($field);
-            }
-
-            $field = array_map('trim', explode(',', $field));
-        }
-
-        if (true === $field) {
-            // 获取全部字段
-            $fields = $this->getTableFields($tableName);
-            $field  = $fields ?: ['*'];
-        } elseif ($except) {
-            // 字段排除
-            $fields = $this->getTableFields($tableName);
-            $field  = $fields ? array_diff($fields, $field) : $field;
-        }
-
-        if ($tableName) {
-            // 添加统一的前缀
-            $prefix = $prefix ?: $tableName;
-            foreach ($field as $key => $val) {
-                if (is_numeric($key)) {
-                    $val = $prefix . '.' . $val . ($alias ? ' AS ' . $alias . $val : '');
-                }
-                $field[$key] = $val;
-            }
-        }
-
-        if (isset($this->options['field'])) {
-            $field = array_merge((array) $this->options['field'], $field);
-        }
-
-        $this->options['field'] = array_unique($field);
-
-        return $this;
-    }
-
-    /**
-     * 表达式方式指定查询字段
-     * @access public
-     * @param  string $field    字段名
-     * @param  array  $bind     参数绑定
-     * @return $this
-     */
-    public function fieldRaw($field, array $bind = [])
-    {
-        $this->options['field'][] = $this->raw($field);
-
-        if ($bind) {
-            $this->bind($bind);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置数据排除字段
-     * @access public
-     * @param  mixed $field 字段名或者数据
-     * @return $this
-     */
-    public function hidden($field)
-    {
-        return $this->field($field, true);
-    }
-
-    /**
-     * 设置数据
-     * @access public
-     * @param  mixed $field 字段名或者数据
-     * @param  mixed $value 字段值
-     * @return $this
-     */
-    public function data($field, $value = null)
-    {
-        if (is_array($field)) {
-            $this->options['data'] = isset($this->options['data']) ? array_merge($this->options['data'], $field) : $field;
-        } else {
-            $this->options['data'][$field] = $value;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 字段值增长
-     * @access public
-     * @param  string|array $field 字段名
-     * @param  integer      $step  增长值
-     * @return $this
-     */
-    public function inc($field, $step = 1, $op = 'INC')
-    {
-        $fields = is_string($field) ? explode(',', $field) : $field;
-
-        foreach ($fields as $field => $val) {
-            if (is_numeric($field)) {
-                $field = $val;
-            } else {
-                $step = $val;
-            }
-
-            $this->data($field, [$op, $step]);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 字段值减少
-     * @access public
-     * @param  string|array $field 字段名
-     * @param  integer      $step  增长值
-     * @return $this
-     */
-    public function dec($field, $step = 1)
-    {
-        return $this->inc($field, $step, 'DEC');
-    }
-
-    /**
-     * 使用表达式设置数据
-     * @access public
-     * @param  string $field 字段名
-     * @param  string $value 字段值
-     * @return $this
-     */
-    public function exp($field, $value)
-    {
-        $this->data($field, $this->raw($value));
-        return $this;
-    }
-
-    /**
-     * 使用表达式设置数据
-     * @access public
-     * @param  mixed $value 表达式
-     * @return Expression
-     */
-    public function raw($value)
-    {
-        return new Expression($value);
-    }
-
-    /**
-     * 指定JOIN查询字段
-     * @access public
-     * @param  string|array $table 数据表
-     * @param  string|array $field 查询字段
-     * @param  string|array $on    JOIN条件
-     * @param  string       $type  JOIN类型
-     * @return $this
-     */
-    public function view($join, $field = true, $on = null, $type = 'INNER')
-    {
-        $this->options['view'] = true;
-
-        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');
-            }
-        } else {
-            $fields = [];
-            $table  = $this->getJoinTable($join, $alias);
-
-            if (true === $field) {
-                $fields = $alias . '.*';
-            } else {
-                if (is_string($field)) {
-                    $field = explode(',', $field);
-                }
-
-                foreach ($field as $key => $val) {
-                    if (is_numeric($key)) {
-                        $fields[] = $alias . '.' . $val;
-
-                        $this->options['map'][$val] = $alias . '.' . $val;
-                    } else {
-                        if (preg_match('/[,=\.\'\"\(\s]/', $key)) {
-                            $name = $key;
-                        } else {
-                            $name = $alias . '.' . $key;
-                        }
-
-                        $fields[] = $name . ' AS ' . $val;
-
-                        $this->options['map'][$val] = $name;
-                    }
-                }
-            }
-
-            $this->field($fields);
-
-            if ($on) {
-                $this->join($table, $on, $type);
-            } else {
-                $this->table($table);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 设置分表规则
-     * @access public
-     * @param  array  $data  操作的数据
-     * @param  string $field 分表依据的字段
-     * @param  array  $rule  分表规则
-     * @return $this
-     */
-    public function partition($data, $field, $rule = [])
-    {
-        $this->options['table'] = $this->getPartitionTableName($data, $field, $rule);
-
-        return $this;
-    }
-
-    /**
-     * 指定AND查询条件
-     * @access public
-     * @param  mixed $field     查询字段
-     * @param  mixed $op        查询表达式
-     * @param  mixed $condition 查询条件
-     * @return $this
-     */
-    public function where($field, $op = null, $condition = null)
-    {
-        $param = func_get_args();
-        array_shift($param);
-        return $this->parseWhereExp('AND', $field, $op, $condition, $param);
-    }
-
-    /**
-     * 指定OR查询条件
-     * @access public
-     * @param  mixed $field     查询字段
-     * @param  mixed $op        查询表达式
-     * @param  mixed $condition 查询条件
-     * @return $this
-     */
-    public function whereOr($field, $op = null, $condition = null)
-    {
-        $param = func_get_args();
-        array_shift($param);
-        return $this->parseWhereExp('OR', $field, $op, $condition, $param);
-    }
-
-    /**
-     * 指定XOR查询条件
-     * @access public
-     * @param  mixed $field     查询字段
-     * @param  mixed $op        查询表达式
-     * @param  mixed $condition 查询条件
-     * @return $this
-     */
-    public function whereXor($field, $op = null, $condition = null)
-    {
-        $param = func_get_args();
-        array_shift($param);
-        return $this->parseWhereExp('XOR', $field, $op, $condition, $param);
-    }
-
-    /**
-     * 指定Null查询条件
-     * @access public
-     * @param  mixed  $field 查询字段
-     * @param  string $logic 查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNull($field, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'NULL', null, [], true);
-    }
-
-    /**
-     * 指定NotNull查询条件
-     * @access public
-     * @param  mixed  $field 查询字段
-     * @param  string $logic 查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNotNull($field, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'NOTNULL', null, [], true);
-    }
-
-    /**
-     * 指定Exists查询条件
-     * @access public
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereExists($condition, $logic = 'AND')
-    {
-        $this->options['where'][strtoupper($logic)][] = ['', 'EXISTS', $condition];
-        return $this;
-    }
-
-    /**
-     * 指定NotExists查询条件
-     * @access public
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNotExists($condition, $logic = 'AND')
-    {
-        $this->options['where'][strtoupper($logic)][] = ['', 'NOT EXISTS', $condition];
-        return $this;
-    }
-
-    /**
-     * 指定In查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereIn($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'IN', $condition, [], true);
-    }
-
-    /**
-     * 指定NotIn查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNotIn($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'NOT IN', $condition, [], true);
-    }
-
-    /**
-     * 指定Like查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereLike($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'LIKE', $condition, [], true);
-    }
-
-    /**
-     * 指定NotLike查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNotLike($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'NOT LIKE', $condition, [], true);
-    }
-
-    /**
-     * 指定Between查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereBetween($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'BETWEEN', $condition, [], true);
-    }
-
-    /**
-     * 指定NotBetween查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  mixed  $condition 查询条件
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereNotBetween($field, $condition, $logic = 'AND')
-    {
-        return $this->parseWhereExp($logic, $field, 'NOT BETWEEN', $condition, [], true);
-    }
-
-    /**
-     * 比较两个字段
-     * @access public
-     * @param  string    $field1     查询字段
-     * @param  string    $operator   比较操作符
-     * @param  string    $field2     比较字段
-     * @param  string    $logic      查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereColumn($field1, $operator, $field2 = null, $logic = 'AND')
-    {
-        if (is_null($field2)) {
-            $field2   = $operator;
-            $operator = '=';
-        }
-
-        return $this->whereExp($field1, $operator . ' ' . $field2, [], $logic);
-    }
-
-    /**
-     * 设置软删除字段及条件
-     * @access public
-     * @param  false|string  $field     查询字段
-     * @param  mixed         $condition 查询条件
-     * @return $this
-     */
-    public function useSoftDelete($field, $condition = null)
-    {
-        if ($field) {
-            $this->options['soft_delete'] = [$field, $condition];
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定Exp查询条件
-     * @access public
-     * @param  mixed  $field     查询字段
-     * @param  string $condition 查询条件
-     * @param  array  $bind      参数绑定
-     * @param  string $logic     查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereExp($field, $condition, $bind = [], $logic = 'AND')
-    {
-        $this->options['where'][$logic][] = [$field, 'EXP', $this->raw($condition)];
-
-        if ($bind) {
-            $this->bind($bind);
-        }
-        return $this;
-    }
-
-    /**
-     * 指定表达式查询条件
-     * @access public
-     * @param  string $where  查询条件
-     * @param  array  $bind   参数绑定
-     * @param  string $logic  查询逻辑 and or xor
-     * @return $this
-     */
-    public function whereRaw($where, $bind = [], $logic = 'AND')
-    {
-        $this->options['where'][$logic][] = $this->raw($where);
-
-        if ($bind) {
-            $this->bind($bind);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定表达式查询条件 OR
-     * @access public
-     * @param  string $where  查询条件
-     * @param  array  $bind   参数绑定
-     * @return $this
-     */
-    public function whereOrRaw($where, $bind = [])
-    {
-        return $this->whereRaw($where, $bind, 'OR');
-    }
-
-    /**
-     * 分析查询表达式
-     * @access protected
-     * @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)
-    {
-        if ($field instanceof $this) {
-            $this->options['where'] = $field->getOptions('where');
-            return $this;
-        }
-
-        $logic = strtoupper($logic);
-
-        if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) {
-            $field = $this->options['via'] . '.' . $field;
-        }
-
-        if ($field instanceof Expression) {
-            return $this->whereRaw($field, is_array($op) ? $op : []);
-        } elseif ($strict) {
-            // 使用严格模式查询
-            $where = [$field, $op, $condition];
-        } elseif (is_array($field)) {
-            // 解析数组批量查询
-            return $this->parseArrayWhereItems($field, $logic);
-        } elseif ($field instanceof \Closure) {
-            $where = $field;
-        } elseif (is_string($field)) {
-            if (preg_match('/[,=\<\'\"\(\s]/', $field)) {
-                return $this->whereRaw($field, $op);
-            } elseif (is_string($op) && strtolower($op) == 'exp') {
-                $bind = isset($param[2]) && is_array($param[2]) ? $param[2] : null;
-                return $this->whereExp($field, $condition, $bind, $logic);
-            }
-
-            $where = $this->parseWhereItem($logic, $field, $op, $condition, $param);
-        }
-
-        if (!empty($where)) {
-            $this->options['where'][$logic][] = $where;
-        }
-
-        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 (is_array($op)) {
-            // 同一字段多条件查询
-            array_unshift($param, $field);
-            $where = $param;
-        } elseif ($field && is_null($condition)) {
-            if (in_array(strtoupper($op), ['NULL', 'NOTNULL', 'NOT NULL'], true)) {
-                // null查询
-                $where = [$field, $op, ''];
-            } elseif (in_array(strtolower($op), ['=', 'eq', null], true)) {
-                $where = [$field, 'NULL', ''];
-            } elseif (in_array(strtolower($op), ['<>', 'neq'], true)) {
-                $where = [$field, 'NOTNULL', ''];
-            } else {
-                // 字段相等查询
-                $where = [$field, '=', $op];
-            }
-        } 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) {
-                $where[] = is_null($val) ? [$key, 'NULL', ''] : [$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
-     * @param  string $field 查询字段
-     * @param  string $logic 查询逻辑 and or xor
-     * @return $this
-     */
-    public function removeWhereField($field, $logic = 'AND')
-    {
-        $logic = strtoupper($logic);
-
-        if (isset($this->options['where'][$logic][$field])) {
-            unset($this->options['where'][$logic][$field]);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 去除查询参数
-     * @access public
-     * @param  string|bool $option 参数名 true 表示去除所有参数
-     * @return $this
-     */
-    public function removeOption($option = true)
-    {
-        if (true === $option) {
-            $this->options = [];
-        } elseif (is_string($option) && isset($this->options[$option])) {
-            unset($this->options[$option]);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 条件查询
-     * @access public
-     * @param  mixed             $condition  满足条件(支持闭包)
-     * @param  \Closure|array    $query      满足条件后执行的查询表达式(闭包或数组)
-     * @param  \Closure|array    $otherwise  不满足条件后执行
-     * @return $this
-     */
-    public function when($condition, $query, $otherwise = null)
-    {
-        if ($condition instanceof \Closure) {
-            $condition = $condition($this);
-        }
-
-        if ($condition) {
-            if ($query instanceof \Closure) {
-                $query($this, $condition);
-            } elseif (is_array($query)) {
-                $this->where($query);
-            }
-        } elseif ($otherwise) {
-            if ($otherwise instanceof \Closure) {
-                $otherwise($this, $condition);
-            } elseif (is_array($otherwise)) {
-                $this->where($otherwise);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定查询数量
-     * @access public
-     * @param  mixed $offset 起始位置
-     * @param  mixed $length 查询数量
-     * @return $this
-     */
-    public function limit($offset, $length = null)
-    {
-        if (is_null($length) && strpos($offset, ',')) {
-            list($offset, $length) = explode(',', $offset);
-        }
-
-        $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : '');
-
-        return $this;
-    }
-
-    /**
-     * 指定分页
-     * @access public
-     * @param  mixed $page     页数
-     * @param  mixed $listRows 每页数量
-     * @return $this
-     */
-    public function page($page, $listRows = null)
-    {
-        if (is_null($listRows) && strpos($page, ',')) {
-            list($page, $listRows) = explode(',', $page);
-        }
-
-        $this->options['page'] = [intval($page), intval($listRows)];
-
-        return $this;
-    }
-
-    /**
-     * 分页查询
-     * @access public
-     * @param  int|array $listRows 每页数量 数组表示配置参数
-     * @param  int|bool  $simple   是否简洁模式或者总记录数
-     * @param  array     $config   配置参数
-     *                            page:当前页,
-     *                            path:url路径,
-     *                            query:url额外参数,
-     *                            fragment:url锚点,
-     *                            var_page:分页变量,
-     *                            list_rows:每页数量
-     *                            type:分页类名
-     * @return \think\Paginator
-     * @throws DbException
-     */
-    public function paginate($listRows = null, $simple = false, $config = [])
-    {
-        if (is_int($simple)) {
-            $total  = $simple;
-            $simple = false;
-        }
-
-        $paginate = Container::get('config')->pull('paginate');
-
-        if (is_array($listRows)) {
-            $config   = array_merge($paginate, $listRows);
-            $listRows = $config['list_rows'];
-        } else {
-            $config   = array_merge($paginate, $config);
-            $listRows = $listRows ?: $config['list_rows'];
-        }
-
-        /** @var Paginator $class */
-        $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']);
-        $page  = isset($config['page']) ? (int) $config['page'] : call_user_func([
-            $class,
-            'getCurrentPage',
-        ], $config['var_page']);
-
-        $page = $page < 1 ? 1 : $page;
-
-        $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']);
-
-        if (!isset($total) && !$simple) {
-            $options = $this->getOptions();
-
-            unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']);
-
-            $bind    = $this->bind;
-            $total   = $this->count();
-            $results = $this->options($options)->bind($bind)->page($page, $listRows)->select();
-        } elseif ($simple) {
-            $results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select();
-            $total   = null;
-        } else {
-            $results = $this->page($page, $listRows)->select();
-        }
-
-        return $class::make($results, $listRows, $page, $total, $simple, $config);
-    }
-
-    /**
-     * 指定当前操作的数据表
-     * @access public
-     * @param  mixed $table 表名
-     * @return $this
-     */
-    public function table($table)
-    {
-        if (is_string($table)) {
-            if (strpos($table, ')')) {
-                // 子查询
-            } elseif (strpos($table, ',')) {
-                $tables = explode(',', $table);
-                $table  = [];
-
-                foreach ($tables as $item) {
-                    list($item, $alias) = explode(' ', trim($item));
-                    if ($alias) {
-                        $this->alias([$item => $alias]);
-                        $table[$item] = $alias;
-                    } else {
-                        $table[] = $item;
-                    }
-                }
-            } elseif (strpos($table, ' ')) {
-                list($table, $alias) = explode(' ', $table);
-
-                $table = [$table => $alias];
-                $this->alias($table);
-            }
-        } else {
-            $tables = $table;
-            $table  = [];
-
-            foreach ($tables as $key => $val) {
-                if (is_numeric($key)) {
-                    $table[] = $val;
-                } else {
-                    $this->alias([$key => $val]);
-                    $table[$key] = $val;
-                }
-            }
-        }
-
-        $this->options['table'] = $table;
-
-        return $this;
-    }
-
-    /**
-     * USING支持 用于多表删除
-     * @access public
-     * @param  mixed $using
-     * @return $this
-     */
-    public function using($using)
-    {
-        $this->options['using'] = $using;
-        return $this;
-    }
-
-    /**
-     * 指定排序 order('id','desc') 或者 order(['id'=>'desc','create_time'=>'desc'])
-     * @access public
-     * @param  string|array $field 排序字段
-     * @param  string       $order 排序
-     * @return $this
-     */
-    public function order($field, $order = null)
-    {
-        if (empty($field)) {
-            return $this;
-        } elseif ($field instanceof Expression) {
-            $this->options['order'][] = $field;
-            return $this;
-        }
-
-        if (is_string($field)) {
-            if (!empty($this->options['via'])) {
-                $field = $this->options['via'] . '.' . $field;
-            }
-
-            if (strpos($field, ',')) {
-                $field = array_map('trim', explode(',', $field));
-            } else {
-                $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 (is_array($field)) {
-            $this->options['order'] = array_merge($this->options['order'], $field);
-        } else {
-            $this->options['order'][] = $field;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 表达式方式指定Field排序
-     * @access public
-     * @param  string $field 排序字段
-     * @param  array  $bind  参数绑定
-     * @return $this
-     */
-    public function orderRaw($field, array $bind = [])
-    {
-        $this->options['order'][] = $this->raw($field);
-
-        if ($bind) {
-            $this->bind($bind);
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定Field排序 order('id',[1,2,3],'desc')
-     * @access public
-     * @param  string|array $field 排序字段
-     * @param  array        $values 排序值
-     * @param  string       $order
-     * @return $this
-     */
-    public function orderField($field, array $values = [], $order = '')
-    {
-        $values['sort'] = $order;
-
-        $this->options['order'][$field] = $values;
-        return $this;
-    }
-
-    /**
-     * 随机排序
-     * @access public
-     * @return $this
-     */
-    public function orderRand()
-    {
-        $this->options['order'][] = '[rand]';
-        return $this;
-    }
-
-    /**
-     * 查询缓存
-     * @access public
-     * @param  mixed             $key    缓存key
-     * @param  integer|\DateTime $expire 缓存有效期
-     * @param  string            $tag    缓存标签
-     * @return $this
-     */
-    public function cache($key = true, $expire = null, $tag = null)
-    {
-        // 增加快捷调用方式 cache(10) 等同于 cache(true, 10)
-        if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) {
-            $expire = $key;
-            $key    = true;
-        }
-
-        if (false !== $key) {
-            $this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag];
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定group查询
-     * @access public
-     * @param  string|array $group GROUP
-     * @return $this
-     */
-    public function group($group)
-    {
-        $this->options['group'] = $group;
-        return $this;
-    }
-
-    /**
-     * 指定having查询
-     * @access public
-     * @param  string $having having
-     * @return $this
-     */
-    public function having($having)
-    {
-        $this->options['having'] = $having;
-        return $this;
-    }
-
-    /**
-     * 指定查询lock
-     * @access public
-     * @param  bool|string $lock 是否lock
-     * @return $this
-     */
-    public function lock($lock = false)
-    {
-        $this->options['lock']   = $lock;
-        $this->options['master'] = true;
-
-        return $this;
-    }
-
-    /**
-     * 指定distinct查询
-     * @access public
-     * @param  string $distinct 是否唯一
-     * @return $this
-     */
-    public function distinct($distinct)
-    {
-        $this->options['distinct'] = $distinct;
-        return $this;
-    }
-
-    /**
-     * 指定数据表别名
-     * @access public
-     * @param  array|string $alias 数据表别名
-     * @return $this
-     */
-    public function alias($alias)
-    {
-        if (is_array($alias)) {
-            foreach ($alias as $key => $val) {
-                if (false !== strpos($key, '__')) {
-                    $table = $this->connection->parseSqlTable($key);
-                } else {
-                    $table = $key;
-                }
-                $this->options['alias'][$table] = $val;
-            }
-        } else {
-            if (isset($this->options['table'])) {
-                $table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table'];
-                if (false !== strpos($table, '__')) {
-                    $table = $this->connection->parseSqlTable($table);
-                }
-            } else {
-                $table = $this->getTable();
-            }
-
-            $this->options['alias'][$table] = $alias;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定强制索引
-     * @access public
-     * @param  string $force 索引名称
-     * @return $this
-     */
-    public function force($force)
-    {
-        $this->options['force'] = $force;
-        return $this;
-    }
-
-    /**
-     * 查询注释
-     * @access public
-     * @param  string $comment 注释
-     * @return $this
-     */
-    public function comment($comment)
-    {
-        $this->options['comment'] = $comment;
-        return $this;
-    }
-
-    /**
-     * 获取执行的SQL语句
-     * @access public
-     * @param  boolean $fetch 是否返回sql
-     * @return $this
-     */
-    public function fetchSql($fetch = true)
-    {
-        $this->options['fetch_sql'] = $fetch;
-        return $this;
-    }
-
-    /**
-     * 不主动获取数据集
-     * @access public
-     * @param  bool $pdo 是否返回 PDOStatement 对象
-     * @return $this
-     */
-    public function fetchPdo($pdo = true)
-    {
-        $this->options['fetch_pdo'] = $pdo;
-        return $this;
-    }
-
-    /**
-     * 设置从主服务器读取数据
-     * @access public
-     * @return $this
-     */
-    public function master()
-    {
-        $this->options['master'] = true;
-        return $this;
-    }
-
-    /**
-     * 设置是否严格检查字段名
-     * @access public
-     * @param  bool $strict 是否严格检查字段
-     * @return $this
-     */
-    public function strict($strict = true)
-    {
-        $this->options['strict'] = $strict;
-        return $this;
-    }
-
-    /**
-     * 设置查询数据不存在是否抛出异常
-     * @access public
-     * @param  bool $fail 数据不存在是否抛出异常
-     * @return $this
-     */
-    public function failException($fail = true)
-    {
-        $this->options['fail'] = $fail;
-        return $this;
-    }
-
-    /**
-     * 设置自增序列名
-     * @access public
-     * @param  string $sequence 自增序列名
-     * @return $this
-     */
-    public function sequence($sequence = null)
-    {
-        $this->options['sequence'] = $sequence;
-        return $this;
-    }
-
-    /**
-     * 设置JSON字段信息
-     * @access public
-     * @param  array $json JSON字段
-     * @return $this
-     */
-    public function json(array $json = [])
-    {
-        $this->options['json'] = $json;
-        return $this;
-    }
-
-    /**
-     * 添加查询范围
-     * @access public
-     * @param  array|string|\Closure   $scope 查询范围定义
-     * @param  array                   $args  参数
-     * @return $this
-     */
-    public function scope($scope, ...$args)
-    {
-        // 查询范围的第一个参数始终是当前查询对象
-        array_unshift($args, $this);
-
-        if ($scope instanceof \Closure) {
-            call_user_func_array($scope, $args);
-            return $this;
-        }
-
-        if (is_string($scope)) {
-            $scope = explode(',', $scope);
-        }
-
-        if ($this->model) {
-            // 检查模型类的查询范围方法
-            foreach ($scope as $name) {
-                $method = 'scope' . trim($name);
-
-                if (method_exists($this->model, $method)) {
-                    call_user_func_array([$this->model, $method], $args);
-                }
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 指定数据表主键
-     * @access public
-     * @param  string $pk 主键
-     * @return $this
-     */
-    public function pk($pk)
-    {
-        $this->pk = $pk;
-        return $this;
-    }
-
-    /**
-     * 查询日期或者时间
-     * @access public
-     * @param  string       $name  时间表达式
-     * @param  string|array $rule  时间范围
-     * @return $this
-     */
-    public function timeRule($name, $rule)
-    {
-        $this->timeRule[$name] = $rule;
-        return $this;
-    }
-
-    /**
-     * 查询日期或者时间
-     * @access public
-     * @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')
-    {
-        if (is_null($range)) {
-            if (is_array($op)) {
-                $range = $op;
-            } else {
-                if (isset($this->timeExp[strtolower($op)])) {
-                    $op = $this->timeExp[strtolower($op)];
-                }
-
-                if (isset($this->timeRule[strtolower($op)])) {
-                    $range = $this->timeRule[strtolower($op)];
-                } else {
-                    $range = $op;
-                }
-            }
-
-            $op = is_array($range) ? 'between' : '>=';
-        }
-
-        return $this->parseWhereExp($logic, $field, strtolower($op) . ' time', $range, [], true);
-    }
-
-    /**
-     * 查询日期或者时间范围
-     * @access public
-     * @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')
-    {
-        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);
-    }
-
-    /**
-     * 获取当前数据表的主键
-     * @access public
-     * @param  string|array $options 数据表名或者查询参数
-     * @return string|array
-     */
-    public function getPk($options = '')
-    {
-        if (!empty($this->pk)) {
-            $pk = $this->pk;
-        } else {
-            $pk = $this->connection->getPk(is_array($options) && isset($options['table']) ? $options['table'] : $this->getTable());
-        }
-
-        return $pk;
-    }
-
-    /**
-     * 参数绑定
-     * @access public
-     * @param  mixed   $key   参数名
-     * @param  mixed   $value 绑定变量值
-     * @param  integer $type  绑定类型
-     * @return $this
-     */
-    public function bind($key, $value = false, $type = PDO::PARAM_STR)
-    {
-        if (is_array($key)) {
-            $this->bind = array_merge($this->bind, $key);
-        } else {
-            $this->bind[$key] = [$value, $type];
-        }
-
-        return $this;
-    }
-
-    /**
-     * 检测参数是否已经绑定
-     * @access public
-     * @param  string $key 参数名
-     * @return bool
-     */
-    public function isBind($key)
-    {
-        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
-     * @param  array $options 表达式参数
-     * @return $this
-     */
-    protected function options(array $options)
-    {
-        $this->options = $options;
-        return $this;
-    }
-
-    /**
-     * 获取当前的查询参数
-     * @access public
-     * @param  string $name 参数名
-     * @return mixed
-     */
-    public function getOptions($name = '')
-    {
-        if ('' === $name) {
-            return $this->options;
-        }
-        return isset($this->options[$name]) ? $this->options[$name] : null;
-    }
-
-    /**
-     * 设置当前的查询参数
-     * @access public
-     * @param  string $option 参数名
-     * @param  mixed  $value  参数值
-     * @return $this
-     */
-    public function setOption($option, $value)
-    {
-        $this->options[$option] = $value;
-        return $this;
-    }
-
-    /**
-     * 设置关联查询JOIN预查询
-     * @access public
-     * @param  string|array $with 关联方法名称
-     * @return $this
-     */
-    public function with($with)
-    {
-        if (empty($with)) {
-            return $this;
-        }
-
-        if (is_string($with)) {
-            $with = explode(',', $with);
-        }
-
-        $first = true;
-
-        /** @var Model $class */
-        $class = $this->model;
-        foreach ($with as $key => $relation) {
-            $subRelation = '';
-            $closure     = false;
-
-            if ($relation instanceof \Closure) {
-                // 支持闭包查询过滤关联条件
-                $closure    = $relation;
-                $relation   = $key;
-                $with[$key] = $key;
-            } elseif (is_array($relation)) {
-                $subRelation = $relation;
-                $relation    = $key;
-            } elseif (is_string($relation) && strpos($relation, '.')) {
-                $with[$key] = $relation;
-
-                list($relation, $subRelation) = explode('.', $relation, 2);
-            }
-
-            /** @var Relation $model */
-            $relation = Loader::parseName($relation, 1, false);
-            $model    = $class->$relation();
-
-            if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
-                $model->removeOption()->eagerly($this, $relation, $subRelation, $closure, $first);
-                $first = false;
-            } elseif ($closure) {
-                $with[$key] = $closure;
-            }
-        }
-        $this->via();
-
-        if (isset($this->options['with'])) {
-            $this->options['with'] = array_merge($this->options['with'], $with);
-        } else {
-            $this->options['with'] = $with;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 关联统计
-     * @access protected
-     * @param  string|array $relation 关联方法名
-     * @param  string       $aggregate 聚合查询方法
-     * @param  string       $field 字段
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    protected function withAggregate($relation, $aggregate = 'count', $field = '*', $subQuery = true)
-    {
-        $relations = is_string($relation) ? explode(',', $relation) : $relation;
-
-        if (!$subQuery) {
-            $this->options['with_count'][] = [$relations, $aggregate, $field];
-        } else {
-            if (!isset($this->options['field'])) {
-                $this->field('*');
-            }
-
-            foreach ($relations as $key => $relation) {
-                $closure = false;
-                if ($relation instanceof \Closure) {
-                    $closure  = $relation;
-                    $relation = $key;
-                }
-                $relation = Loader::parseName($relation, 1, false);
-                $count    = '(' . $this->model->$relation()->getRelationCountQuery($closure, $aggregate, $field) . ')';
-                $this->field([$count => Loader::parseName($relation) . '_' . $aggregate]);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * 关联统计
-     * @access public
-     * @param  string|array $relation 关联方法名
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    public function withCount($relation, $subQuery = true)
-    {
-        return $this->withAggregate($relation, 'count', '*', $subQuery);
-    }
-
-    /**
-     * 关联统计Sum
-     * @access public
-     * @param  string|array $relation 关联方法名
-     * @param  string       $field 字段
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    public function withSum($relation, $field, $subQuery = true)
-    {
-        return $this->withAggregate($relation, 'sum', $field, $subQuery);
-    }
-
-    /**
-     * 关联统计Max
-     * @access public
-     * @param  string|array $relation 关联方法名
-     * @param  string       $field 字段
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    public function withMax($relation, $field, $subQuery = true)
-    {
-        return $this->withAggregate($relation, 'max', $field, $subQuery);
-    }
-
-    /**
-     * 关联统计Min
-     * @access public
-     * @param  string|array $relation 关联方法名
-     * @param  string       $field 字段
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    public function withMin($relation, $field, $subQuery = true)
-    {
-        return $this->withAggregate($relation, 'min', $field, $subQuery);
-    }
-
-    /**
-     * 关联统计Avg
-     * @access public
-     * @param  string|array $relation 关联方法名
-     * @param  string       $field 字段
-     * @param  bool         $subQuery 是否使用子查询
-     * @return $this
-     */
-    public function withAvg($relation, $field, $subQuery = true)
-    {
-        return $this->withAggregate($relation, 'avg', $field, $subQuery);
-    }
-
-    /**
-     * 关联预加载中 获取关联指定字段值
-     * example:
-     * Model::with(['relation' => function($query){
-     *     $query->withField("id,name");
-     * }])
-     *
-     * @access public
-     * @param  string | array $field 指定获取的字段
-     * @return $this
-     */
-    public function withField($field)
-    {
-        $this->options['with_field'] = $field;
-
-        return $this;
-    }
-
-    /**
-     * 设置当前字段添加的表别名
-     * @access public
-     * @param  string $via
-     * @return $this
-     */
-    public function via($via = '')
-    {
-        $this->options['via'] = $via;
-
-        return $this;
-    }
-
-    /**
-     * 设置关联查询
-     * @access public
-     * @param  string|array $relation 关联名称
-     * @return $this
-     */
-    public function relation($relation)
-    {
-        if (empty($relation)) {
-            return $this;
-        }
-
-        if (is_string($relation)) {
-            $relation = explode(',', $relation);
-        }
-
-        if (isset($this->options['relation'])) {
-            $this->options['relation'] = array_merge($this->options['relation'], $relation);
-        } else {
-            $this->options['relation'] = $relation;
-        }
-
-        return $this;
-    }
-
-    /**
-     * 插入记录
-     * @access public
-     * @param  array   $data         数据
-     * @param  boolean $replace      是否replace
-     * @param  boolean $getLastInsID 返回自增主键
-     * @param  string  $sequence     自增序列名
-     * @return integer|string
-     */
-    public function insert(array $data = [], $replace = false, $getLastInsID = false, $sequence = null)
-    {
-        $this->parseOptions();
-
-        $this->options['data'] = array_merge($this->options['data'], $data);
-
-        return $this->connection->insert($this, $replace, $getLastInsID, $sequence);
-    }
-
-    /**
-     * 插入记录并获取自增ID
-     * @access public
-     * @param  array   $data     数据
-     * @param  boolean $replace  是否replace
-     * @param  string  $sequence 自增序列名
-     * @return integer|string
-     */
-    public function insertGetId(array $data, $replace = false, $sequence = null)
-    {
-        return $this->insert($data, $replace, true, $sequence);
-    }
-
-    /**
-     * 批量插入记录
-     * @access public
-     * @param  array     $dataSet 数据集
-     * @param  boolean   $replace 是否replace
-     * @param  integer   $limit   每次写入数据限制
-     * @return integer|string
-     */
-    public function insertAll(array $dataSet = [], $replace = false, $limit = null)
-    {
-        $this->parseOptions();
-
-        if (empty($dataSet)) {
-            $dataSet = $this->options['data'];
-        }
-
-        if (empty($limit) && !empty($this->options['limit'])) {
-            $limit = $this->options['limit'];
-        }
-
-        return $this->connection->insertAll($this, $dataSet, $replace, $limit);
-    }
-
-    /**
-     * 通过Select方式插入记录
-     * @access public
-     * @param  string $fields 要插入的数据表字段名
-     * @param  string $table  要插入的数据表名
-     * @return integer|string
-     * @throws PDOException
-     */
-    public function selectInsert($fields, $table)
-    {
-        $this->parseOptions();
-
-        return $this->connection->selectInsert($this, $fields, $table);
-    }
-
-    /**
-     * 更新记录
-     * @access public
-     * @param  mixed $data 数据
-     * @return integer|string
-     * @throws Exception
-     * @throws PDOException
-     */
-    public function update(array $data = [])
-    {
-        $this->parseOptions();
-
-        $this->options['data'] = array_merge($this->options['data'], $data);
-
-        return $this->connection->update($this);
-    }
-
-    /**
-     * 删除记录
-     * @access public
-     * @param  mixed $data 表达式 true 表示强制删除
-     * @return int
-     * @throws Exception
-     * @throws PDOException
-     */
-    public function delete($data = null)
-    {
-        $this->parseOptions();
-
-        if (!is_null($data) && true !== $data) {
-            // AR模式分析主键条件
-            $this->parsePkWhere($data);
-        }
-
-        if (!empty($this->options['soft_delete'])) {
-            // 软删除
-            list($field, $condition) = $this->options['soft_delete'];
-            unset($this->options['soft_delete']);
-            $this->options['data'] = [$field => $condition];
-
-            return $this->connection->update($this);
-        }
-
-        $this->options['data'] = $data;
-
-        return $this->connection->delete($this);
-    }
-
-    /**
-     * 执行查询但只返回PDOStatement对象
-     * @access public
-     * @return \PDOStatement|string
-     */
-    public function getPdo()
-    {
-        $this->parseOptions();
-
-        return $this->connection->pdo($this);
-    }
-
-    /**
-     * 使用游标查找记录
-     * @access public
-     * @param  array|string|Query|\Closure $data
-     * @return \Generator
-     */
-    public function cursor($data = null)
-    {
-        if ($data instanceof \Closure) {
-            $data($this);
-            $data = null;
-        }
-
-        $this->parseOptions();
-
-        if (!is_null($data)) {
-            // 主键条件分析
-            $this->parsePkWhere($data);
-        }
-
-        $this->options['data'] = $data;
-
-        $connection = clone $this->connection;
-
-        return $connection->cursor($this);
-    }
-
-    /**
-     * 查找记录
-     * @access public
-     * @param  array|string|Query|\Closure $data
-     * @return Collection|array|\PDOStatement|string
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function select($data = null)
-    {
-        if ($data instanceof Query) {
-            return $data->select();
-        } elseif ($data instanceof \Closure) {
-            $data($this);
-            $data = null;
-        }
-
-        $this->parseOptions();
-
-        if (false === $data) {
-            // 用于子查询 不查询只返回SQL
-            $this->options['fetch_sql'] = true;
-        } elseif (!is_null($data)) {
-            // 主键条件分析
-            $this->parsePkWhere($data);
-        }
-
-        $this->options['data'] = $data;
-
-        $resultSet = $this->connection->select($this);
-
-        if ($this->options['fetch_sql']) {
-            return $resultSet;
-        }
-
-        // 数据列表读取后的处理
-        if (!empty($this->model)) {
-            // 生成模型对象
-            if (count($resultSet) > 0) {
-                foreach ($resultSet as $key => &$result) {
-                    // 数据转换为模型对象
-                    $this->resultToModel($result, $this->options, true);
-                }
-
-                if (!empty($this->options['with'])) {
-                    // 预载入
-                    $result->eagerlyResultSet($resultSet, $this->options['with']);
-                }
-
-                // 模型数据集转换
-                $resultSet = $result->toCollection($resultSet);
-            } else {
-                $resultSet = $this->model->toCollection($resultSet);
-            }
-        } else {
-            if (!empty($this->options['json'])) {
-                foreach ($resultSet as &$result) {
-                    $this->jsonResult($result, $this->options['json'], true);
-                }
-            }
-
-            if ('collection' == $this->connection->getConfig('resultset_type')) {
-                // 返回Collection对象
-                $resultSet = new Collection($resultSet);
-            }
-        }
-
-        // 返回结果处理
-        if (!empty($this->options['fail']) && count($resultSet) == 0) {
-            $this->throwNotFound($this->options);
-        }
-
-        return $resultSet;
-    }
-
-    /**
-     * 查找单条记录
-     * @access public
-     * @param  array|string|Query|\Closure $data
-     * @return array|null|\PDOStatement|string|Model
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function find($data = null)
-    {
-        if ($data instanceof Query) {
-            return $data->find();
-        } elseif ($data instanceof \Closure) {
-            $data($this);
-            $data = null;
-        }
-
-        $this->parseOptions();
-
-        if (!is_null($data)) {
-            // AR模式分析主键条件
-            $this->parsePkWhere($data);
-        }
-
-        $this->options['data'] = $data;
-
-        $result = $this->connection->find($this);
-
-        if ($this->options['fetch_sql']) {
-            return $result;
-        }
-
-        // 数据处理
-        if (!empty($result)) {
-            if (!empty($this->model)) {
-                // 返回模型对象
-                $this->resultToModel($result, $this->options);
-            } elseif (!empty($this->options['json'])) {
-                $this->jsonResult($result, $this->options['json'], true);
-            }
-        } elseif (!empty($this->options['fail'])) {
-            $this->throwNotFound($this->options);
-        }
-
-        return $result;
-    }
-
-    /**
-     * JSON字段数据转换
-     * @access protected
-     * @param  array $result     查询数据
-     * @param  array $json       JSON字段
-     * @param  bool  $assoc      是否转换为数组
-     * @return void
-     */
-    protected function jsonResult(&$result, $json = [], $assoc = false)
-    {
-        foreach ($json as $name) {
-            if (isset($result[$name])) {
-                $result[$name] = json_decode($result[$name], $assoc);
-            }
-        }
-    }
-
-    /**
-     * 查询数据转换为模型对象
-     * @access protected
-     * @param  array $result     查询数据
-     * @param  array $options    查询参数
-     * @param  bool  $resultSet  是否为数据集查询
-     * @return void
-     */
-    protected function resultToModel(&$result, $options = [], $resultSet = false)
-    {
-        if (!empty($options['json'])) {
-            $this->jsonResult($result, $options['json']);
-        }
-
-        $condition = (!$resultSet && isset($options['where']['AND'])) ? $options['where']['AND'] : null;
-        $result    = $this->model->newInstance($result, $condition);
-
-        // 关联查询
-        if (!empty($options['relation'])) {
-            $result->relationQuery($options['relation']);
-        }
-
-        // 预载入查询
-        if (!$resultSet && !empty($options['with'])) {
-            $result->eagerlyResult($result, $options['with']);
-        }
-
-        // 关联统计
-        if (!empty($options['with_count'])) {
-            foreach ($options['with_count'] as $val) {
-                $result->relationCount($result, $val[0], $val[1], $val[2]);
-            }
-        }
-    }
-
-    /**
-     * 查询失败 抛出异常
-     * @access protected
-     * @param  array $options 查询参数
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    protected function throwNotFound($options = [])
-    {
-        if (!empty($this->model)) {
-            $class = get_class($this->model);
-            throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options);
-        }
-        $table = is_array($options['table']) ? key($options['table']) : $options['table'];
-        throw new DataNotFoundException('table data not Found:' . $table, $table, $options);
-    }
-
-    /**
-     * 查找多条记录 如果不存在则抛出异常
-     * @access public
-     * @param  array|string|Query|\Closure $data
-     * @return array|\PDOStatement|string|Model
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function selectOrFail($data = null)
-    {
-        return $this->failException(true)->select($data);
-    }
-
-    /**
-     * 查找单条记录 如果不存在则抛出异常
-     * @access public
-     * @param  array|string|Query|\Closure $data
-     * @return array|\PDOStatement|string|Model
-     * @throws DbException
-     * @throws ModelNotFoundException
-     * @throws DataNotFoundException
-     */
-    public function findOrFail($data = null)
-    {
-        return $this->failException(true)->find($data);
-    }
-
-    /**
-     * 分批数据返回处理
-     * @access public
-     * @param  integer      $count    每次处理的数据数量
-     * @param  callable     $callback 处理回调方法
-     * @param  string|array $column   分批处理的字段名
-     * @param  string       $order    字段排序
-     * @return boolean
-     * @throws DbException
-     */
-    public function chunk($count, $callback, $column = null, $order = 'asc')
-    {
-        $options = $this->getOptions();
-        $column  = $column ?: $this->getPk($options);
-
-        if (isset($options['order'])) {
-            if (Container::get('app')->isDebug()) {
-                throw new DbException('chunk not support call order');
-            }
-            unset($options['order']);
-        }
-
-        $bind = $this->bind;
-
-        if (is_array($column)) {
-            $times = 1;
-            $query = $this->options($options)->page($times, $count);
-        } else {
-            $query = $this->options($options)->limit($count);
-
-            if (strpos($column, '.')) {
-                list($alias, $key) = explode('.', $column);
-            } else {
-                $key = $column;
-            }
-        }
-
-        $resultSet = $query->order($column, $order)->select();
-
-        while (count($resultSet) > 0) {
-            if ($resultSet instanceof Collection) {
-                $resultSet = $resultSet->all();
-            }
-
-            if (false === call_user_func($callback, $resultSet)) {
-                return false;
-            }
-
-            if (isset($times)) {
-                $times++;
-                $query = $this->options($options)->page($times, $count);
-            } else {
-                $end    = end($resultSet);
-                $lastId = is_array($end) ? $end[$key] : $end->getData($key);
-
-                $query = $this->options($options)
-                    ->limit($count)
-                    ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId);
-            }
-
-            $resultSet = $query->bind($bind)->order($column, $order)->select();
-        }
-
-        return true;
-    }
-
-    /**
-     * 获取绑定的参数 并清空
-     * @access public
-     * @param  bool $clear
-     * @return array
-     */
-    public function getBind($clear = true)
-    {
-        $bind = $this->bind;
-        if ($clear) {
-            $this->bind = [];
-        }
-
-        return $bind;
-    }
-
-    /**
-     * 创建子查询SQL
-     * @access public
-     * @param  bool $sub
-     * @return string
-     * @throws DbException
-     */
-    public function buildSql($sub = true)
-    {
-        return $sub ? '( ' . $this->select(false) . ' )' : $this->select(false);
-    }
-
-    /**
-     * 视图查询处理
-     * @access protected
-     * @param  array   $options    查询参数
-     * @return void
-     */
-    protected function parseView(&$options)
-    {
-        foreach (['AND', 'OR'] as $logic) {
-            if (isset($options['where'][$logic])) {
-                foreach ($options['where'][$logic] as $key => $val) {
-                    if (array_key_exists($key, $options['map'])) {
-                        array_shift($val);
-                        array_unshift($val, $options['map'][$key]);
-                        $options['where'][$logic][$options['map'][$key]] = $val;
-                        unset($options['where'][$logic][$key]);
-                    }
-                }
-            }
-        }
-
-        if (isset($options['order'])) {
-            // 视图查询排序处理
-            if (is_string($options['order'])) {
-                $options['order'] = explode(',', $options['order']);
-            }
-            foreach ($options['order'] as $key => $val) {
-                if (is_numeric($key)) {
-                    if (strpos($val, ' ')) {
-                        list($field, $sort) = explode(' ', $val);
-                        if (array_key_exists($field, $options['map'])) {
-                            $options['order'][$options['map'][$field]] = $sort;
-                            unset($options['order'][$key]);
-                        }
-                    } elseif (array_key_exists($val, $options['map'])) {
-                        $options['order'][$options['map'][$val]] = 'asc';
-                        unset($options['order'][$key]);
-                    }
-                } elseif (array_key_exists($key, $options['map'])) {
-                    $options['order'][$options['map'][$key]] = $val;
-                    unset($options['order'][$key]);
-                }
-            }
-        }
-    }
-
-    /**
-     * 把主键值转换为查询条件 支持复合主键
-     * @access public
-     * @param  array|string $data    主键数据
-     * @return void
-     * @throws Exception
-     */
-    public function parsePkWhere($data)
-    {
-        $pk = $this->getPk($this->options);
-
-        // 获取当前数据表
-        $table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table'];
-
-        if (!empty($this->options['alias'][$table])) {
-            $alias = $this->options['alias'][$table];
-        }
-
-        if (is_string($pk)) {
-            $key = isset($alias) ? $alias . '.' . $pk : $pk;
-            // 根据主键查询
-            if (is_array($data)) {
-                $where[$pk] = isset($data[$pk]) ? [$key, '=', $data[$pk]] : [$key, 'in', $data];
-            } else {
-                $where[$pk] = strpos($data, ',') ? [$key, 'IN', $data] : [$key, '=', $data];
-            }
-        } elseif (is_array($pk) && is_array($data) && !empty($data)) {
-            // 根据复合主键查询
-            foreach ($pk as $key) {
-                if (isset($data[$key])) {
-                    $attr        = isset($alias) ? $alias . '.' . $key : $key;
-                    $where[$key] = [$attr, '=', $data[$key]];
-                } else {
-                    throw new Exception('miss complex primary data');
-                }
-            }
-        }
-
-        if (!empty($where)) {
-            if (isset($this->options['where']['AND'])) {
-                $this->options['where']['AND'] = array_merge($this->options['where']['AND'], $where);
-            } else {
-                $this->options['where']['AND'] = $where;
-            }
-        }
-
-        return;
-    }
-
-    /**
-     * 分析表达式(可用于查询或者写入操作)
-     * @access protected
-     * @return array
-     */
-    protected function parseOptions()
-    {
-        $options = $this->getOptions();
-
-        // 获取数据表
-        if (empty($options['table'])) {
-            $options['table'] = $this->getTable();
-        }
-
-        if (!isset($options['where'])) {
-            $options['where'] = [];
-        } elseif (isset($options['view'])) {
-            // 视图查询条件处理
-            $this->parseView($options);
-        }
-
-        if (!isset($options['field'])) {
-            $options['field'] = '*';
-        }
-
-        foreach (['data', 'order'] as $name) {
-            if (!isset($options[$name])) {
-                $options[$name] = [];
-            }
-        }
-
-        if (!isset($options['strict'])) {
-            $options['strict'] = $this->getConfig('fields_strict');
-        }
-
-        foreach (['master', 'lock', 'fetch_pdo', 'fetch_sql', 'distinct'] as $name) {
-            if (!isset($options[$name])) {
-                $options[$name] = false;
-            }
-        }
-
-        foreach (['join', 'union', 'group', 'having', 'limit', 'force', 'comment'] as $name) {
-            if (!isset($options[$name])) {
-                $options[$name] = '';
-            }
-        }
-
-        if (isset($options['page'])) {
-            // 根据页数计算limit
-            list($page, $listRows) = $options['page'];
-            $page                  = $page > 0 ? $page : 1;
-            $listRows              = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20);
-            $offset                = $listRows * ($page - 1);
-            $options['limit']      = $offset . ',' . $listRows;
-        }
-
-        $this->options = $options;
-
-        return $options;
-    }
-
-    /**
-     * 注册回调方法
-     * @access public
-     * @param  string   $event    事件名
-     * @param  callable $callback 回调方法
-     * @return void
-     */
-    public static function event($event, $callback)
-    {
-        self::$event[$event] = $callback;
-    }
-
-    /**
-     * 触发事件
-     * @access public
-     * @param  string $event   事件名
-     * @return bool
-     */
-    public function trigger($event)
-    {
-        $result = false;
-
-        if (isset(self::$event[$event])) {
-            $result = Container::getInstance()->invoke(self::$event[$event], [$this]);
-        }
-
-        return $result;
-    }
-
-}

+ 0 - 188
thinkphp/library/think/db/builder/Mysql.php

@@ -1,188 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db\builder;
-
-use think\db\Builder;
-use think\db\Query;
-
-/**
- * mysql数据库驱动
- */
-class Mysql extends Builder
-{
-    // 查询表达式解析
-    protected $parser = [
-        'parseCompare'     => ['=', '<>', '>', '>=', '<', '<='],
-        'parseLike'        => ['LIKE', 'NOT LIKE'],
-        'parseBetween'     => ['NOT BETWEEN', 'BETWEEN'],
-        'parseIn'          => ['NOT IN', 'IN'],
-        'parseExp'         => ['EXP'],
-        'parseRegexp'      => ['REGEXP', 'NOT REGEXP'],
-        'parseNull'        => ['NOT NULL', 'NULL'],
-        'parseBetweenTime' => ['BETWEEN TIME', 'NOT BETWEEN TIME'],
-        'parseTime'        => ['< TIME', '> TIME', '<= TIME', '>= TIME'],
-        'parseExists'      => ['NOT EXISTS', 'EXISTS'],
-    ];
-
-    protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
-    protected $updateSql    = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
-
-    /**
-     * 生成insertall SQL
-     * @access public
-     * @param  Query     $query   查询对象
-     * @param  array     $dataSet 数据集
-     * @param  bool      $replace 是否replace
-     * @return string
-     */
-    public function insertAll(Query $query, $dataSet, $replace = false)
-    {
-        $options = $query->getOptions();
-
-        // 获取合法的字段
-        if ('*' == $options['field']) {
-            $allowFields = $this->connection->getTableFields($options['table']);
-        } else {
-            $allowFields = $options['field'];
-        }
-
-        // 获取绑定信息
-        $bind = $this->connection->getFieldsBind($options['table']);
-
-        foreach ($dataSet as $k => $data) {
-            $data = $this->parseData($query, $data, $allowFields, $bind, '_' . $k);
-
-            $values[] = '( ' . implode(',', array_values($data)) . ' )';
-
-            if (!isset($insertFields)) {
-                $insertFields = array_keys($data);
-            }
-        }
-
-        $fields = [];
-        foreach ($insertFields as $field) {
-            $fields[] = $this->parseKey($query, $field);
-        }
-
-        return str_replace(
-            ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
-            [
-                $replace ? 'REPLACE' : 'INSERT',
-                $this->parseTable($query, $options['table']),
-                implode(' , ', $fields),
-                implode(' , ', $values),
-                $this->parseComment($query, $options['comment']),
-            ],
-            $this->insertAllSql);
-    }
-
-    /**
-     * 正则查询
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @return string
-     */
-    protected function parseRegexp(Query $query, $key, $exp, $value, $field)
-    {
-        return $key . ' ' . $exp . ' ' . $value;
-    }
-
-    /**
-     * 字段和表名处理
-     * @access public
-     * @param  Query     $query 查询对象
-     * @param  string    $key   字段名
-     * @param  bool      $strict   严格检测
-     * @return string
-     */
-    public function parseKey(Query $query, $key, $strict = false)
-    {
-        if (is_int($key)) {
-            return $key;
-        }
-        $key = trim($key);
-
-        if (strpos($key, '->') && false === strpos($key, '(')) {
-            // JSON字段支持
-            list($field, $name) = explode('->', $key, 2);
-
-            return 'json_extract(' . $this->parseKey($query, $field) . ', \'$.' . str_replace('->', '.', $name) . '\')';
-        } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
-            list($table, $key) = explode('.', $key, 2);
-
-            $alias = $query->getOptions('alias');
-
-            if ('__TABLE__' == $table) {
-                $table = $query->getOptions('table');
-                $table = is_array($table) ? array_shift($table) : $table;
-            }
-
-            if (isset($alias[$table])) {
-                $table = $alias[$table];
-            }
-        }
-
-        if ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
-            $key = '`' . $key . '`';
-        }
-
-        if (isset($table)) {
-            if (strpos($table, '.')) {
-                $table = str_replace('.', '`.`', $table);
-            }
-
-            $key = '`' . $table . '`.' . $key;
-        }
-
-        return $key;
-    }
-
-    /**
-     * field分析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  mixed     $fields    字段名
-     * @return string
-     */
-    protected function parseField(Query $query, $fields)
-    {
-        $fieldsStr = parent::parseField($query, $fields);
-        $options   = $query->getOptions();
-
-        if (!empty($options['point'])) {
-            $array = [];
-            foreach ($options['point'] as $key => $field) {
-                $key     = !is_numeric($key) ? $key : $field;
-                $array[] = 'AsText(' . $this->parseKey($query, $key) . ') AS ' . $this->parseKey($query, $field);
-            }
-            $fieldsStr .= ',' . implode(',', $array);
-        }
-
-        return $fieldsStr;
-    }
-
-    /**
-     * 随机排序
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @return string
-     */
-    protected function parseRand(Query $query)
-    {
-        return 'rand()';
-    }
-
-}

+ 0 - 98
thinkphp/library/think/db/builder/Pgsql.php

@@ -1,98 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db\builder;
-
-use think\db\Builder;
-use think\db\Query;
-
-/**
- * Pgsql数据库驱动
- */
-class Pgsql extends Builder
-{
-
-    protected $insertSql    = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
-    protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
-
-    /**
-     * limit分析
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @param  mixed     $limit
-     * @return string
-     */
-    public function parseLimit(Query $query, $limit)
-    {
-        $limitStr = '';
-
-        if (!empty($limit)) {
-            $limit = explode(',', $limit);
-            if (count($limit) > 1) {
-                $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';
-            } else {
-                $limitStr .= ' LIMIT ' . $limit[0] . ' ';
-            }
-        }
-
-        return $limitStr;
-    }
-
-    /**
-     * 字段和表名处理
-     * @access public
-     * @param  Query     $query     查询对象
-     * @param  string    $key       字段名
-     * @param  bool   $strict   严格检测
-     * @return string
-     */
-    public function parseKey(Query $query, $key, $strict = false)
-    {
-        $key = trim($key);
-
-        if (strpos($key, '->') && false === strpos($key, '(')) {
-            // JSON字段支持
-            list($field, $name) = explode('->', $key);
-            $key                = $field . '->>\'' . $name . '\'';
-        } elseif (strpos($key, '.')) {
-            list($table, $key) = explode('.', $key, 2);
-
-            $alias = $query->getOptions('alias');
-
-            if ('__TABLE__' == $table) {
-                $table = $query->getOptions('table');
-                $table = is_array($table) ? array_shift($table) : $table;
-            }
-
-            if (isset($alias[$table])) {
-                $table = $alias[$table];
-            }
-        }
-
-        if (isset($table)) {
-            $key = $table . '.' . $key;
-        }
-
-        return $key;
-    }
-
-    /**
-     * 随机排序
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @return string
-     */
-    protected function parseRand(Query $query)
-    {
-        return 'RANDOM()';
-    }
-
-}

+ 0 - 89
thinkphp/library/think/db/builder/Sqlite.php

@@ -1,89 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-namespace think\db\builder;
-
-use think\db\Builder;
-use think\db\Query;
-
-/**
- * Sqlite数据库驱动
- */
-class Sqlite extends Builder
-{
-
-    /**
-     * limit
-     * @access public
-     * @param  Query     $query        查询对象
-     * @param  mixed     $limit
-     * @return string
-     */
-    public function parseLimit(Query $query, $limit)
-    {
-        $limitStr = '';
-
-        if (!empty($limit)) {
-            $limit = explode(',', $limit);
-            if (count($limit) > 1) {
-                $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';
-            } else {
-                $limitStr .= ' LIMIT ' . $limit[0] . ' ';
-            }
-        }
-
-        return $limitStr;
-    }
-
-    /**
-     * 随机排序
-     * @access protected
-     * @param  Query     $query        查询对象
-     * @return string
-     */
-    protected function parseRand(Query $query)
-    {
-        return 'RANDOM()';
-    }
-
-    /**
-     * 字段和表名处理
-     * @access public
-     * @param  Query     $query     查询对象
-     * @param  string    $key       字段名
-     * @param  bool      $strict   严格检测
-     * @return string
-     */
-    public function parseKey(Query $query, $key, $strict = false)
-    {
-        $key = trim($key);
-        if (strpos($key, '.')) {
-            list($table, $key) = explode('.', $key, 2);
-
-            $alias = $query->getOptions('alias');
-
-            if ('__TABLE__' == $table) {
-                $table = $query->getOptions('table');
-                $table = is_array($table) ? array_shift($table) : $table;
-            }
-
-            if (isset($alias[$table])) {
-                $table = $alias[$table];
-            }
-        }
-
-        if (isset($table)) {
-            $key = $table . '.' . $key;
-        }
-
-        return $key;
-    }
-}

Some files were not shown because too many files changed in this diff