Browse Source

[更新]ComposerUpdate

Anyon 6 năm trước cách đây
mục cha
commit
340a0b144c
42 tập tin đã thay đổi với 628 bổ sung186 xóa
  1. 2 2
      extend/service/ToolsService.php
  2. 4 1
      thinkphp/README.md
  3. 0 22
      thinkphp/base.php
  4. 5 6
      thinkphp/library/think/App.php
  5. 62 0
      thinkphp/library/think/Collection.php
  6. 85 23
      thinkphp/library/think/Config.php
  7. 1 0
      thinkphp/library/think/Container.php
  8. 1 1
      thinkphp/library/think/Facade.php
  9. 5 0
      thinkphp/library/think/Model.php
  10. 1 1
      thinkphp/library/think/cache/driver/Memcache.php
  11. 7 32
      thinkphp/library/think/db/Connection.php
  12. 156 36
      thinkphp/library/think/db/Query.php
  13. 9 0
      thinkphp/library/think/facade/App.php
  14. 9 0
      thinkphp/library/think/facade/Build.php
  15. 9 0
      thinkphp/library/think/facade/Cache.php
  16. 10 1
      thinkphp/library/think/facade/Config.php
  17. 9 0
      thinkphp/library/think/facade/Cookie.php
  18. 9 0
      thinkphp/library/think/facade/Debug.php
  19. 9 0
      thinkphp/library/think/facade/Env.php
  20. 9 0
      thinkphp/library/think/facade/Hook.php
  21. 9 0
      thinkphp/library/think/facade/Lang.php
  22. 9 0
      thinkphp/library/think/facade/Log.php
  23. 9 0
      thinkphp/library/think/facade/Middleware.php
  24. 9 0
      thinkphp/library/think/facade/Request.php
  25. 9 0
      thinkphp/library/think/facade/Response.php
  26. 9 0
      thinkphp/library/think/facade/Route.php
  27. 9 0
      thinkphp/library/think/facade/Session.php
  28. 36 0
      thinkphp/library/think/facade/Template.php
  29. 9 0
      thinkphp/library/think/facade/Url.php
  30. 10 0
      thinkphp/library/think/facade/Validate.php
  31. 9 0
      thinkphp/library/think/facade/View.php
  32. 16 0
      thinkphp/library/think/model/Collection.php
  33. 16 5
      thinkphp/library/think/model/concern/Attribute.php
  34. 9 7
      thinkphp/library/think/model/concern/RelationShip.php
  35. 4 0
      thinkphp/library/think/model/concern/TimeStamp.php
  36. 1 2
      thinkphp/library/think/model/relation/BelongsToMany.php
  37. 34 28
      thinkphp/library/think/model/relation/OneToOne.php
  38. 1 1
      thinkphp/library/think/route/Dispatch.php
  39. 1 1
      vendor/autoload.php
  40. 7 7
      vendor/composer/autoload_real.php
  41. 4 4
      vendor/composer/autoload_static.php
  42. 6 6
      vendor/composer/installed.json

+ 2 - 2
extend/service/ToolsService.php

@@ -37,8 +37,8 @@ class ToolsService
             Session::init(config('session.'));
         }
         $token = request()->header('token', '');
-        empty($token) && $token = request()->post('token', '');
         empty($token) && $token = request()->get('token', '');
+        empty($token) && $token = request()->post('token', '');
         list($name, $value) = explode('=', decode($token) . '=');
         if (!empty($value) && session_name() === $name) {
             session_id($value);
@@ -48,7 +48,7 @@ class ToolsService
             header('Access-Control-Allow-Credentials:true');
             header('Access-Control-Allow-Methods:GET,POST,OPTIONS');
             header("Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Cookie,token");
-            header('Content-Type:text/plain charset=UTF-8');
+            header('Content-Type:text/plain charset=utf-8');
             header('Access-Control-Max-Age:1728000');
             header('HTTP/1.0 204 No Content');
             header('Content-Length:0');

+ 4 - 1
thinkphp/README.md

@@ -3,9 +3,11 @@
 ThinkPHP 5.1 —— 12载初心,你值得信赖的PHP框架
 ===============
 
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/top-think/framework/badges/quality-score.png?b=5.1)](https://scrutinizer-ci.com/g/top-think/framework/?branch=5.1)
 [![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)
+[![PHP Version](https://img.shields.io/badge/php-%3E%3D5.6-8892BF.svg)](http://www.php.net/)
 [![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework)
 
 ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特性包括:
@@ -25,6 +27,7 @@ ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特
  + 中间件支持(`V5.1.6+`)
  + 支持`Swoole`/`Workerman`运行(`V5.1.18+`)
 
+
 ### 废除的功能:
 
  + 聚合模型
@@ -67,7 +70,7 @@ composer update topthink/framework
 
 ## 命名规范
 
-`ThinkPHP5`遵循PSR-2命名规范和PSR-4自动加载规范。
+`ThinkPHP5.1`遵循PSR-2命名规范和PSR-4自动加载规范。
 
 ## 参与开发
 

+ 0 - 22
thinkphp/base.php

@@ -28,28 +28,6 @@ if (interface_exists('Psr\Log\LoggerInterface')) {
     {}
 }
 
-// 注册核心类的静态代理
-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,

+ 5 - 6
thinkphp/library/think/App.php

@@ -20,7 +20,7 @@ use think\route\Dispatch;
  */
 class App extends Container
 {
-    const VERSION = '5.1.21';
+    const VERSION = '5.1.22';
 
     /**
      * 当前模块路径
@@ -178,6 +178,8 @@ class App extends Container
 
         $this->instance('app', $this);
 
+        $this->configExt = $this->env->get('config_ext', '.php');
+
         // 加载惯例配置文件
         $this->config->set(include $this->thinkPath . 'convention.php');
 
@@ -204,8 +206,6 @@ class App extends Container
         // 注册应用命名空间
         Loader::addNamespace($this->namespace, $this->appPath);
 
-        $this->configExt = $this->env->get('config_ext', '.php');
-
         // 初始化应用
         $this->init();
 
@@ -312,7 +312,7 @@ class App extends Container
 
             // 自动读取配置文件
             if (is_dir($path . 'config')) {
-                $dir = $path . 'config';
+                $dir = $path . 'config'.DIRECTORY_SEPARATOR;
             } elseif (is_dir($this->configPath . $module)) {
                 $dir = $this->configPath . $module;
             }
@@ -321,8 +321,7 @@ class App extends Container
 
             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->config->load($dir . $file, pathinfo($file, PATHINFO_FILENAME));
                 }
             }
         }

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

@@ -250,6 +250,68 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
     }
 
     /**
+     * 根据字段条件过滤数组中的元素
+     * @access public
+     * @param  string   $field 字段名
+     * @param  mixed    $operator 操作符
+     * @param  mixed    $value 数据
+     * @return static
+     */
+    public function where($field, $operator, $value = null)
+    {
+        if (is_null($value)) {
+            $value    = $operator;
+            $operator = '=';
+        }
+
+        return $this->filter(function ($data) use ($field, $operator, $value) {
+            if (strpos($field, '.')) {
+                list($field, $relation) = explode('.', $field);
+
+                $result = isset($data[$field][$relation]) ? $data[$field][$relation] : null;
+            } else {
+                $result = isset($data[$field]) ? $data[$field] : null;
+            }
+
+            switch ($operator) {
+                case '===':
+                    return $result === $value;
+                case '!==':
+                    return $result !== $value;
+                case '!=':
+                case '<>':
+                    return $result != $value;
+                case '>':
+                    return $result > $value;
+                case '>=':
+                    return $result >= $value;
+                case '<':
+                    return $result < $value;
+                case '<=':
+                    return $result <= $value;
+                case 'like':
+                    return is_string($result) && false !== strpos($result, $value);
+                case 'not like':
+                    return is_string($result) && false === strpos($result, $value);
+                case 'in':
+                    return is_scalar($result) && in_array($result, $value, true);
+                case 'not in':
+                    return is_scalar($result) && !in_array($result, $value, true);
+                case 'between':
+                    list($min, $max) = is_string($value) ? explode(',', $value) : $value;
+                    return is_scalar($result) && $result >= $min && $result <= $max;
+                case 'not between':
+                    list($min, $max) = is_string($value) ? explode(',', $value) : $value;
+                    return is_scalar($result) && $result > $max || $result < $min;
+                case '==':
+                case '=':
+                default:
+                    return $result == $value;
+            }
+        });
+    }
+
+    /**
      * 返回数据中指定的一列
      * @access public
      * @param mixed $columnKey 键名

+ 85 - 23
thinkphp/library/think/Config.php

@@ -11,19 +11,68 @@
 
 namespace think;
 
+use Yaconf;
+
 class Config implements \ArrayAccess
 {
     /**
      * 配置参数
      * @var array
      */
-    private $config = [];
+    protected $config = [];
 
     /**
      * 配置前缀
      * @var string
      */
-    private $prefix = 'app';
+    protected $prefix = 'app';
+
+    /**
+     * 配置文件目录
+     * @var string
+     */
+    protected $path;
+
+    /**
+     * 配置文件后缀
+     * @var string
+     */
+    protected $ext;
+
+    /**
+     * 是否支持Yaconf
+     * @var bool
+     */
+    protected $yaconf;
+
+    /**
+     * 构造方法
+     * @access public
+     */
+    public function __construct($path = '', $ext = '.php')
+    {
+        $this->path   = $path;
+        $this->ext    = $ext;
+        $this->yaconf = class_exists('Yaconf');
+    }
+
+    public static function __make(App $app)
+    {
+        $path = $app->getConfigPath();
+        $ext  = $app->getConfigExt();
+        return new static($path, $ext);
+    }
+
+    /**
+     * 设置开启Yaconf
+     * @access public
+     * @param  bool    $yaconf  是否使用Yaconf
+     * @return void
+     */
+    public function useYaconf($yaconf)
+    {
+        $this->yaconf = $yaconf;
+    }
 
     /**
      * 设置配置参数默认前缀
@@ -65,20 +114,34 @@ class Config implements \ArrayAccess
     public function load($file, $name = '')
     {
         if (is_file($file)) {
-            $name = strtolower($name);
-            $type = pathinfo($file, PATHINFO_EXTENSION);
+            $filename = $file;
+        } elseif (is_file($this->path . $file . $this->ext)) {
+            $filename = $this->path . $file . $this->ext;
+        }
 
-            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);
+        if (isset($filename)) {
+            return $this->loadFile($filename, $name);
+        } elseif ($this->yaconf && Yaconf::has($file)) {
+            return $this->set(Yaconf::get($file), $name);
         }
 
         return $this->config;
     }
 
+    protected function loadFile($file, $name)
+    {
+        $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);
+    }
+
     /**
      * 检测配置是否存在
      * @access public
@@ -91,10 +154,6 @@ class Config implements \ArrayAccess
             $name = $this->prefix . '.' . $name;
         }
 
-        if (class_exists('Yaconf')) {
-            return Yaconf::has($name);
-        }
-
         return !is_null($this->get($name));
     }
 
@@ -108,6 +167,11 @@ class Config implements \ArrayAccess
     {
         $name = strtolower($name);
 
+        if ($this->yaconf && Yaconf::has($name)) {
+            $config = Yaconf::get($name);
+            return isset($this->config[$name]) ? array_merge($this->config[$name], $config) : $config;
+        }
+
         return isset($this->config[$name]) ? $this->config[$name] : [];
     }
 
@@ -120,12 +184,8 @@ class Config implements \ArrayAccess
      */
     public function get($name = null, $default = null)
     {
-        if (class_exists('Yaconf')) {
-            if ($name && !strpos($name, '.')) {
-                $name = $this->prefix . '.' . $name;
-            }
-
-            return Yaconf::get($name, $default);
+        if ($name && !strpos($name, '.')) {
+            $name = $this->prefix . '.' . $name;
         }
 
         // 无参数时获取所有
@@ -133,12 +193,14 @@ class Config implements \ArrayAccess
             return $this->config;
         }
 
-        if (!strpos($name, '.')) {
-            $name = $this->prefix . '.' . $name;
-        } elseif ('.' == substr($name, -1)) {
+        if ('.' == substr($name, -1)) {
             return $this->pull(substr($name, 0, -1));
         }
 
+        if ($this->yaconf && Yaconf::has($name)) {
+            return Yaconf::get($name);
+        }
+
         $name    = explode('.', $name);
         $name[0] = strtolower($name[0]);
         $config  = $this->config;

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

@@ -57,6 +57,7 @@ class Container implements ArrayAccess, IteratorAggregate, Countable
         'response'              => Response::class,
         'route'                 => Route::class,
         'session'               => Session::class,
+        'template'              => Template::class,
         'url'                   => Url::class,
         'validate'              => Validate::class,
         'view'                  => View::class,

+ 1 - 1
thinkphp/library/think/Facade.php

@@ -75,7 +75,7 @@ class Facade
     }
 
     /**
-     * 获取当前Facade对应类名
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
      * @access protected
      * @return string
      */

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

@@ -18,6 +18,7 @@ use think\db\Query;
  * Class Model
  * @package think
  * @mixin Query
+ * @method \think\Model withAttr(array $name,\Closure $closure) 动态定义获取器
  */
 abstract class Model implements \JsonSerializable, \ArrayAccess
 {
@@ -1041,6 +1042,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
 
     public function __call($method, $args)
     {
+        if ('withattr' == strtolower($method)) {
+            return call_user_func_array([$this, 'withAttribute'], $args);
+        }
+
         return call_user_func_array([$this->db(), $method], $args);
     }
 

+ 1 - 1
thinkphp/library/think/cache/driver/Memcache.php

@@ -70,7 +70,7 @@ class Memcache extends Driver
     {
         $key = $this->getCacheKey($name);
 
-        return $this->handler->get($key) ? true : false;
+        return false !== $this->handler->get($key);
     }
 
     /**

+ 7 - 32
thinkphp/library/think/db/Connection.php

@@ -584,20 +584,13 @@ abstract class Connection
 
         $this->bind = $bind;
 
-        // 释放前次的查询结果
-        if (!empty($this->PDOStatement)) {
-            $this->free();
-        }
-
         Db::$queryTimes++;
 
         // 调试开始
         $this->debug(true);
 
         // 预处理
-        if (empty($this->PDOStatement)) {
-            $this->PDOStatement = $this->linkID->prepare($sql);
-        }
+        $this->PDOStatement = $this->linkID->prepare($sql);
 
         // 是否为存储过程调用
         $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
@@ -663,15 +656,8 @@ abstract class Connection
             // 调试开始
             $this->debug(true);
 
-            // 释放前次的查询结果
-            if (!empty($this->PDOStatement)) {
-                $this->free();
-            }
-
             // 预处理
-            if (empty($this->PDOStatement)) {
-                $this->PDOStatement = $this->linkID->prepare($sql);
-            }
+            $this->PDOStatement = $this->linkID->prepare($sql);
 
             // 是否为存储过程调用
             $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
@@ -742,15 +728,8 @@ abstract class Connection
             // 调试开始
             $this->debug(true);
 
-            //释放前次的查询结果
-            if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
-                $this->free();
-            }
-
             // 预处理
-            if (empty($this->PDOStatement)) {
-                $this->PDOStatement = $this->linkID->prepare($sql);
-            }
+            $this->PDOStatement = $this->linkID->prepare($sql);
 
             // 是否为存储过程调用
             $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
@@ -1680,13 +1659,9 @@ abstract class Connection
                     $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)) {
+                --$this->transTimes;
                 return $this->close()->startTrans();
             }
             throw $e;
@@ -1826,6 +1801,9 @@ abstract class Connection
         $this->linkRead  = null;
         $this->links     = [];
 
+        // 释放查询
+        $this->free();
+
         return $this;
     }
 
@@ -2074,9 +2052,6 @@ abstract class Connection
      */
     public function __destruct()
     {
-        // 释放查询
-        $this->free();
-
         // 关闭连接
         $this->close();
     }

+ 156 - 36
thinkphp/library/think/db/Query.php

@@ -1034,17 +1034,6 @@ class Query
     }
 
     /**
-     * 设置数据排除字段
-     * @access public
-     * @param  mixed $field 字段名或者数据
-     * @return $this
-     */
-    public function hidden($field)
-    {
-        return $this->field($field, true);
-    }
-
-    /**
      * 设置数据
      * @access public
      * @param  mixed $field 字段名或者数据
@@ -2124,6 +2113,46 @@ class Query
     }
 
     /**
+     * 设置需要隐藏的输出属性
+     * @access public
+     * @param  mixed $hidden 需要隐藏的字段名
+     * @return $this
+     */
+    public function hidden($hidden)
+    {
+        if ($this->model) {
+            $this->options['hidden'] = $hidden;
+            return $this;
+        }
+
+        return $this->field($hidden, true);
+    }
+
+    /**
+     * 设置需要输出的属性
+     * @access public
+     * @param  array $visible 需要输出的属性
+     * @return $this
+     */
+    public function visible(array $visible)
+    {
+        $this->options['visible'] = $visible;
+        return $this;
+    }
+
+    /**
+     * 设置需要追加输出的属性
+     * @access public
+     * @param  array $append 需要追加的属性
+     * @return $this
+     */
+    public function append(array $append)
+    {
+        $this->options['append'] = $append;
+        return $this;
+    }
+
+    /**
      * 设置数据字段获取器
      * @access public
      * @param  string|array $name       字段名
@@ -2133,14 +2162,8 @@ class Query
     public function withAttr($name, $callback = null)
     {
         if (is_array($name)) {
-            foreach ($name as $key => $val) {
-                $key = Loader::parseName($key);
-
-                $this->options['with_attr'][$key] = $val;
-            }
+            $this->options['with_attr'] = $name;
         } else {
-            $name = Loader::parseName($name);
-
             $this->options['with_attr'][$name] = $callback;
         }
 
@@ -2220,6 +2243,31 @@ class Query
     }
 
     /**
+     * 使用搜索器条件搜索字段
+     * @access public
+     * @param  array $fields 搜索字段
+     * @param  array $data   搜索数据
+     * @return $this
+     */
+    public function withSearch(array $fields, array $data = [])
+    {
+        foreach ($fields as $key => $field) {
+            if ($field instanceof \Closure) {
+                $field($this, isset($data[$key]) ? $data[$key] : null, $data);
+            } elseif ($this->model) {
+                // 检测搜索器
+                $method = 'search' . Loader::parseName($field, 1) . 'Attr';
+
+                if (method_exists($this->model, $method)) {
+                    $this->model->$method($this, isset($data[$field]) ? $data[$field] : null, $data);
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
      * 指定数据表主键
      * @access public
      * @param  string $pk 主键
@@ -2441,20 +2489,15 @@ class Query
         /** @var Model $class */
         $class = $this->model;
         foreach ($with as $key => $relation) {
-            $subRelation = '';
-            $closure     = false;
+            $closure = null;
 
             if ($relation instanceof \Closure) {
                 // 支持闭包查询过滤关联条件
-                $closure    = $relation;
-                $relation   = $key;
-                $with[$key] = $key;
+                $closure  = $relation;
+                $relation = $key;
             } elseif (is_array($relation)) {
-                $subRelation = $relation;
-                $relation    = $key;
+                $relation = $key;
             } elseif (is_string($relation) && strpos($relation, '.')) {
-                $with[$key] = $relation;
-
                 list($relation, $subRelation) = explode('.', $relation, 2);
             }
 
@@ -2463,20 +2506,74 @@ class Query
             $model    = $class->$relation();
 
             if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
-                $model->removeOption()->eagerly($this, $relation, $subRelation, $closure, $first);
+                $table = $model->getTable();
+                $model->removeOption()
+                    ->table($table)
+                    ->eagerly($this, $relation, true, '', $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;
+        $this->options['with'] = $with;
+
+        return $this;
+    }
+
+    /**
+     * 关联预载入 JOIN方式(不支持嵌套)
+     * @access protected
+     * @param  string|array $with 关联方法名
+     * @param  string       $joinType JOIN方式
+     * @return $this
+     */
+    public function withJoin($with, $joinType = '')
+    {
+        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) {
+            $closure = null;
+            $field   = true;
+
+            if ($relation instanceof \Closure) {
+                // 支持闭包查询过滤关联条件
+                $closure  = $relation;
+                $relation = $key;
+            } elseif (is_array($relation)) {
+                $field    = $relation;
+                $relation = $key;
+            } elseif (is_string($relation) && strpos($relation, '.')) {
+                list($relation, $subRelation) = explode('.', $relation, 2);
+            }
+
+            /** @var Relation $model */
+            $relation = Loader::parseName($relation, 1, false);
+            $model    = $class->$relation();
+
+            if ($model instanceof OneToOne) {
+                $model->eagerly($this, $relation, $field, $joinType, $closure, $first);
+                $first = false;
+            } else {
+                // 不支持其它关联
+                unset($with[$key]);
+            }
+        }
+
+        $this->via();
+
+        $this->options['with_join'] = $with;
+
         return $this;
     }
 
@@ -2501,7 +2598,7 @@ class Query
             }
 
             foreach ($relations as $key => $relation) {
-                $closure = false;
+                $closure = null;
                 if ($relation instanceof \Closure) {
                     $closure  = $relation;
                     $relation = $key;
@@ -2866,6 +2963,11 @@ class Query
                     $result->eagerlyResultSet($resultSet, $this->options['with'], $withRelationAttr);
                 }
 
+                if (!empty($this->options['with_join'])) {
+                    // JOIN预载入
+                    $result->eagerlyResultSet($resultSet, $this->options['with_join'], $withRelationAttr, true);
+                }
+
                 // 模型数据集转换
                 $resultSet = $result->toCollection($resultSet);
             } else {
@@ -3069,6 +3171,8 @@ class Query
     protected function getResultAttr(&$result, $withAttr = [])
     {
         foreach ($withAttr as $name => $closure) {
+            $name = Loader::parseName($name);
+
             if (strpos($name, '.')) {
                 // 支持JSON字段 获取器定义
                 list($key, $field) = explode('.', $name);
@@ -3139,7 +3243,18 @@ class Query
 
         // 动态获取器
         if (!empty($options['with_attr'])) {
-            $result->setModelAttrs($options['with_attr']);
+            $result->withAttribute($options['with_attr']);
+        }
+
+        // 输出属性控制
+        if (!empty($options['visible'])) {
+            $result->visible($options['visible']);
+        } elseif (!empty($options['hidden'])) {
+            $result->hidden($options['hidden']);
+        }
+
+        if (!empty($options['append'])) {
+            $result->append($options['append']);
         }
 
         // 关联查询
@@ -3152,6 +3267,11 @@ class Query
             $result->eagerlyResult($result, $options['with'], $withRelationAttr);
         }
 
+        // JOIN预载入查询
+        if (!$resultSet && !empty($options['with_join'])) {
+            $result->eagerlyResult($result, $options['with_join'], $withRelationAttr, true);
+        }
+
         // 关联统计
         if (!empty($options['with_count'])) {
             foreach ($options['with_count'] as $val) {

+ 9 - 0
thinkphp/library/think/facade/App.php

@@ -51,4 +51,13 @@ use think\Facade;
  */
 class App extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'app';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Build.php

@@ -21,4 +21,13 @@ use think\Facade;
  */
 class Build extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'build';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Cache.php

@@ -33,4 +33,13 @@ use think\Facade;
  */
 class Cache extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'cache';
+    }
 }

+ 10 - 1
thinkphp/library/think/facade/Config.php

@@ -18,10 +18,19 @@ use think\Facade;
  * @mixin \think\Config
  * @method bool has(string $name) static 检测配置是否存在
  * @method array pull(string $name) static 获取一级配置
- * @method mixed get(string $name) static 获取配置参数
+ * @method mixed get(string $name,mixed $default = null) static 获取配置参数
  * @method mixed set(string $name, mixed $value = null) static 设置配置参数
  * @method array reset(string $prefix ='') static 重置配置参数
  */
 class Config extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'config';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Cookie.php

@@ -27,4 +27,13 @@ use think\Facade;
  */
 class Cookie extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'cookie';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Debug.php

@@ -28,4 +28,13 @@ use think\Facade;
  */
 class Debug extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'debug';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Env.php

@@ -22,4 +22,13 @@ use think\Facade;
  */
 class Env extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'env';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Hook.php

@@ -25,4 +25,13 @@ use think\Facade;
  */
 class Hook extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'hook';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Lang.php

@@ -29,4 +29,13 @@ use think\Facade;
  */
 class Lang extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'lang';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Log.php

@@ -37,4 +37,13 @@ use think\Facade;
  */
 class Log extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'log';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Middleware.php

@@ -24,4 +24,13 @@ use think\Facade;
  */
 class Middleware extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'middleware';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Request.php

@@ -85,4 +85,13 @@ use think\Facade;
  */
 class Request extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'request';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Response.php

@@ -35,4 +35,13 @@ use think\Facade;
  */
 class Response extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'response';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Route.php

@@ -45,4 +45,13 @@ use think\Facade;
  */
 class Route extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'route';
+    }
 }

+ 9 - 0
thinkphp/library/think/facade/Session.php

@@ -34,4 +34,13 @@ use think\Facade;
  */
 class Session extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'session';
+    }
 }

+ 36 - 0
thinkphp/library/think/facade/Template.php

@@ -0,0 +1,36 @@
+<?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\facade;
+
+use think\Facade;
+
+/**
+ * @see \think\Template
+ * @mixin \think\Template
+ * @method void assign(mixed $name, mixed $value = '') static 模板变量赋值
+ * @method mixed get(string $name = '') static 获取模板变量
+ * @method void fetch(string $template, array $vars = [], array $config = []) static 渲染模板文件
+ * @method void display(string $content, array $vars = [], array $config = []) static 渲染模板内容
+ * @method mixed layout(string $name, string $replace = '') static 设置模板布局
+ */
+class Template extends Facade
+{
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'template';
+    }
+}

+ 9 - 0
thinkphp/library/think/facade/Url.php

@@ -21,4 +21,13 @@ use think\Facade;
  */
 class Url extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'url';
+    }
 }

+ 10 - 0
thinkphp/library/think/facade/Validate.php

@@ -62,4 +62,14 @@ use think\Facade;
  */
 class Validate extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'validate';
+    }
+
 }

+ 9 - 0
thinkphp/library/think/facade/View.php

@@ -28,4 +28,13 @@ use think\Facade;
  */
 class View extends Facade
 {
+    /**
+     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
+     * @access protected
+     * @return string
+     */
+    protected static function getFacadeClass()
+    {
+        return 'view';
+    }
 }

+ 16 - 0
thinkphp/library/think/model/Collection.php

@@ -93,4 +93,20 @@ class Collection extends BaseCollection
         return $this;
     }
 
+    /**
+     * 设置数据字段获取器
+     * @access public
+     * @param  string|array $name       字段名
+     * @param  callable     $callback   闭包获取器
+     * @return $this
+     */
+    public function withAttr($name, $callback = null)
+    {
+        $this->each(function ($model) use ($name, $callback) {
+            /** @var Model $model */
+            $model && $model->withAttribute($name, $callback);
+        });
+
+        return $this;
+    }
 }

+ 16 - 5
thinkphp/library/think/model/concern/Attribute.php

@@ -599,14 +599,25 @@ trait Attribute
     }
 
     /**
-     * 动态设置获取器
-     * @access protected
-     * @param  array        $attrs 值
+     * 设置数据字段获取器
+     * @access public
+     * @param  string|array $name       字段名
+     * @param  callable     $callback   闭包获取器
      * @return $this
      */
-    public function setModelAttrs(array $attrs = [])
+    public function withAttribute($name, $callback = null)
     {
-        $this->withAttr = $attrs;
+        if (is_array($name)) {
+            foreach ($name as $key => $val) {
+                $key = Loader::parseName($key);
+
+                $this->withAttr[$key] = $val;
+            }
+        } else {
+            $name = Loader::parseName($name);
+
+            $this->withAttr[$name] = $callback;
+        }
 
         return $this;
     }

+ 9 - 7
thinkphp/library/think/model/concern/RelationShip.php

@@ -219,15 +219,16 @@ trait RelationShip
      * @param  array  $resultSet        数据集
      * @param  string $relation         关联名
      * @param  array  $withRelationAttr 关联获取器
+     * @param  bool   $join             是否为JOIN方式
      * @return array
      */
-    public function eagerlyResultSet(&$resultSet, $relation, $withRelationAttr = [])
+    public function eagerlyResultSet(&$resultSet, $relation, $withRelationAttr = [], $join = false)
     {
         $relations = is_string($relation) ? explode(',', $relation) : $relation;
 
         foreach ($relations as $key => $relation) {
             $subRelation = '';
-            $closure     = false;
+            $closure     = null;
 
             if ($relation instanceof \Closure) {
                 $closure  = $relation;
@@ -250,7 +251,7 @@ trait RelationShip
                 $relationResult->withAttr($withRelationAttr[$relationName]);
             }
 
-            $relationResult->eagerlyResultSet($resultSet, $relation, $subRelation, $closure);
+            $relationResult->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $join);
         }
     }
 
@@ -260,15 +261,16 @@ trait RelationShip
      * @param  Model  $result           数据对象
      * @param  string $relation         关联名
      * @param  array  $withRelationAttr 关联获取器
+     * @param  bool   $join             是否为JOIN方式
      * @return Model
      */
-    public function eagerlyResult(&$result, $relation, $withRelationAttr = [])
+    public function eagerlyResult(&$result, $relation, $withRelationAttr = [], $join = false)
     {
         $relations = is_string($relation) ? explode(',', $relation) : $relation;
 
         foreach ($relations as $key => $relation) {
             $subRelation = '';
-            $closure     = false;
+            $closure     = null;
 
             if ($relation instanceof \Closure) {
                 $closure  = $relation;
@@ -291,7 +293,7 @@ trait RelationShip
                 $relationResult->withAttr($withRelationAttr[$relationName]);
             }
 
-            $relationResult->eagerlyResult($result, $relation, $subRelation, $closure);
+            $relationResult->eagerlyResult($result, $relation, $subRelation, $closure, $join);
         }
     }
 
@@ -307,7 +309,7 @@ trait RelationShip
     public function relationCount(&$result, $relations, $aggregate = 'sum', $field = '*')
     {
         foreach ($relations as $key => $relation) {
-            $closure = false;
+            $closure = null;
 
             if ($relation instanceof \Closure) {
                 $closure  = $relation;

+ 4 - 0
thinkphp/library/think/model/concern/TimeStamp.php

@@ -50,6 +50,10 @@ trait TimeStamp
      */
     protected function formatDateTime($time, $format, $timestamp = false)
     {
+        if (empty($time)) {
+            return;
+        }
+
         if (false !== strpos($format, '\\')) {
             $time = new $format($time);
         } elseif (!$timestamp && false !== $format) {

+ 1 - 2
thinkphp/library/think/model/relation/BelongsToMany.php

@@ -509,8 +509,7 @@ class BelongsToMany extends Relation
             } else {
                 // 保存关联表数据
                 $model = new $this->model;
-                $model->save($data);
-                $id = $model->getLastInsID();
+                $id    = $model->insertGetId($data);
             }
         } elseif (is_numeric($data) || is_string($data)) {
             // 根据关联表主键直接写入中间表

+ 34 - 28
thinkphp/library/think/model/relation/OneToOne.php

@@ -50,12 +50,13 @@ abstract class OneToOne extends Relation
      * @access public
      * @param  Query    $query       查询对象
      * @param  string   $relation    关联名
-     * @param  string   $subRelation 子关联
+     * @param  mixed    $field       关联字段
+     * @param  string   $joinType    JOIN方式
      * @param  \Closure $closure     闭包条件
      * @param  bool     $first
      * @return void
      */
-    public function eagerly(Query $query, $relation, $subRelation, $closure, $first)
+    public function eagerly(Query $query, $relation, $field, $joinType, $closure, $first)
     {
         $name = Loader::parseName(basename(str_replace('\\', '/', get_class($this->parent))));
 
@@ -64,24 +65,26 @@ abstract class OneToOne extends Relation
             $query->table([$table => $name]);
 
             if ($query->getOptions('field')) {
-                $field = $query->getOptions('field');
+                $masterField = $query->getOptions('field');
                 $query->removeOption('field');
             } else {
-                $field = true;
+                $masterField = true;
             }
 
-            $query->field($field, false, $table, $name);
+            $query->field($masterField, false, $table, $name);
         }
 
         // 预载入封装
         $joinTable = $this->query->getTable();
         $joinAlias = $relation;
+        $joinType  = $joinType ?: $this->joinType;
+
         $query->via($joinAlias);
 
         if ($this instanceof BelongsTo) {
-            $query->join([$joinTable => $joinAlias], $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType);
+            $joinOn = $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey;
         } else {
-            $query->join([$joinTable => $joinAlias], $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType);
+            $joinOn = $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey;
         }
 
         if ($closure) {
@@ -92,16 +95,11 @@ abstract class OneToOne extends Relation
             if ($query->getOptions('with_field')) {
                 $field = $query->getOptions('with_field');
                 $query->removeOption('with_field');
-            } else {
-                $field = true;
             }
-        } elseif (isset($this->option['field'])) {
-            $field = $this->option['field'];
-        } else {
-            $field = true;
         }
 
-        $query->field($field, false, $joinTable, $joinAlias, $relation . '__');
+        $query->join([$joinTable => $joinAlias], $joinOn, $joinType)
+            ->field($field, false, $joinTable, $joinAlias, $relation . '__');
     }
 
     /**
@@ -133,18 +131,19 @@ abstract class OneToOne extends Relation
      * @param  string   $relation    当前关联名
      * @param  string   $subRelation 子关联名
      * @param  \Closure $closure     闭包
+     * @param  bool     $join        是否为JOIN方式
      * @return void
      */
-    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)
+    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $join = false)
     {
-        if (1 == $this->eagerlyType) {
-            // IN查询
-            $this->eagerlySet($resultSet, $relation, $subRelation, $closure);
-        } else {
-            // 模型关联组装
+        if ($join || 0 == $this->eagerlyType) {
+            // 模型JOIN关联组装
             foreach ($resultSet as $result) {
                 $this->match($this->model, $relation, $result);
             }
+        } else {
+            // IN查询
+            $this->eagerlySet($resultSet, $relation, $subRelation, $closure);
         }
     }
 
@@ -155,16 +154,17 @@ abstract class OneToOne extends Relation
      * @param  string   $relation    当前关联名
      * @param  string   $subRelation 子关联名
      * @param  \Closure $closure     闭包
+     * @param  bool     $join        是否为JOIN方式
      * @return void
      */
-    public function eagerlyResult(&$result, $relation, $subRelation, $closure)
+    public function eagerlyResult(&$result, $relation, $subRelation, $closure, $join = false)
     {
-        if (1 == $this->eagerlyType) {
+        if (0 == $this->eagerlyType || $join) {
+            // 模型JOIN关联组装
+            $this->match($this->model, $relation, $result);
+        } else {
             // IN查询
             $this->eagerlyOne($result, $relation, $subRelation, $closure);
-        } else {
-            // 模型关联组装
-            $this->match($this->model, $relation, $result);
         }
     }
 
@@ -272,9 +272,15 @@ abstract class OneToOne extends Relation
         }
 
         if (isset($list[$relation])) {
-            $relationModel = new $model($list[$relation]);
-            $relationModel->setParent(clone $result);
-            $relationModel->isUpdate(true);
+            $array = array_unique($list[$relation]);
+
+            if (count($array) == 1 && null === current($array)) {
+                $relationModel = null;
+            } else {
+                $relationModel = new $model($list[$relation]);
+                $relationModel->setParent(clone $result);
+                $relationModel->isUpdate(true);
+            }
 
             if (!empty($this->bindAttr)) {
                 $this->bindAttr($relationModel, $result, $this->bindAttr);

+ 1 - 1
thinkphp/library/think/route/Dispatch.php

@@ -182,7 +182,7 @@ abstract class Dispatch
         } else {
             $data     = ob_get_clean();
             $content  = false === $data ? '' : $data;
-            $status   = false === $data ? 204 : 200;
+            $status   = '' === $content && $this->request->isAjax() ? 204 : 200;
             $response = Response::create($content, '', $status);
         }
 

+ 1 - 1
vendor/autoload.php

@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec::getLoader();
+return ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52::getLoader();

+ 7 - 7
vendor/composer/autoload_real.php

@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec
+class ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52
 {
     private static $loader;
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52', 'loadClassLoader'));
 
         $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
         if ($useStaticLoader) {
             require_once __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInit8153982cf21eec76f214c39086ebcf52::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit5d00137d1db4a58cf3bb528ee40ba5ec
         $loader->register(true);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequire5d00137d1db4a58cf3bb528ee40ba5ec($fileIdentifier, $file);
+            composerRequire8153982cf21eec76f214c39086ebcf52($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
 
-function composerRequire5d00137d1db4a58cf3bb528ee40ba5ec($fileIdentifier, $file)
+function composerRequire8153982cf21eec76f214c39086ebcf52($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;

+ 4 - 4
vendor/composer/autoload_static.php

@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec
+class ComposerStaticInit8153982cf21eec76f214c39086ebcf52
 {
     public static $files = array (
         '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
@@ -303,9 +303,9 @@ class ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec::$prefixDirsPsr4;
-            $loader->classMap = ComposerStaticInit5d00137d1db4a58cf3bb528ee40ba5ec::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$classMap;
 
         }, null, ClassLoader::class);
     }

+ 6 - 6
vendor/composer/installed.json

@@ -50,17 +50,17 @@
     },
     {
         "name": "topthink/framework",
-        "version": "v5.1.21",
-        "version_normalized": "5.1.21.0",
+        "version": "v5.1.22",
+        "version_normalized": "5.1.22.0",
         "source": {
             "type": "git",
             "url": "https://github.com/top-think/framework.git",
-            "reference": "e670467e24399c98581db1b1d39191848f3e6b4d"
+            "reference": "35e9878a6ba06257502c5ba664d8e3407012ad00"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/top-think/framework/zipball/e670467e24399c98581db1b1d39191848f3e6b4d",
-            "reference": "e670467e24399c98581db1b1d39191848f3e6b4d",
+            "url": "https://api.github.com/repos/top-think/framework/zipball/35e9878a6ba06257502c5ba664d8e3407012ad00",
+            "reference": "35e9878a6ba06257502c5ba664d8e3407012ad00",
             "shasum": "",
             "mirrors": [
                 {
@@ -82,7 +82,7 @@
             "sebastian/phpcpd": "2.*",
             "squizlabs/php_codesniffer": "2.*"
         },
-        "time": "2018-08-02T09:17:04+00:00",
+        "time": "2018-08-09T06:04:18+00:00",
         "type": "think-framework",
         "installation-source": "dist",
         "notification-url": "https://packagist.org/downloads/",