[更新]ComposerUpdate

This commit is contained in:
Anyon 2018-05-19 15:53:57 +08:00
parent d77de72c4e
commit 1316e885f8
63 changed files with 1407 additions and 938 deletions

View File

@ -28,31 +28,6 @@ if (interface_exists('Psr\Log\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,
@ -97,9 +72,3 @@ Loader::addClassAlias([
'Validate' => facade\Validate::class,
'View' => facade\View::class,
]);
// 加载惯例配置文件
facade\Config::set(include __DIR__ . '/convention.php');
// 加载composer autofile文件
Loader::loadComposerAutoloadFiles();

View File

@ -15,8 +15,8 @@ return [
'app_trace' => false,
// 应用模式状态
'app_status' => '',
// 是否支持多模块
'app_multi_module' => true,
// 是否HTTPS
'is_https' => false,
// 入口自动绑定模块
'auto_bind_module' => false,
// 注册的根命名空间
@ -33,56 +33,81 @@ return [
'default_timezone' => 'Asia/Shanghai',
// 是否开启多语言
'lang_switch_on' => false,
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 默认验证器
'default_validate' => '',
// 默认语言
'default_lang' => 'zh-cn',
// 应用类库后缀
'class_suffix' => false,
// 控制器类后缀
'controller_suffix' => false,
// +----------------------------------------------------------------------
// | 模块设置
// +----------------------------------------------------------------------
// 自动搜索控制器
'controller_auto_search' => false,
// 操作方法前缀
'use_action_prefix' => false,
// 操作方法后缀
'action_suffix' => '',
// 默认的空控制器名
'empty_controller' => 'Error',
// 默认的空模块名
'empty_module' => '',
// 默认模块名
'default_module' => 'index',
// 是否支持多模块
'app_multi_module' => true,
// 禁止访问模块
'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中的控制器和操作名
'url_convert' => true,
// 默认的访问控制器层
'url_controller_layer' => 'controller',
// 应用类库后缀
'class_suffix' => false,
// 控制器类后缀
'controller_suffix' => false,
// +----------------------------------------------------------------------
// | URL设置
// | URL请求设置
// +----------------------------------------------------------------------
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// pathinfo分隔符
'pathinfo_depr' => '/',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip' => 'X-REAL-IP',
// URL伪静态后缀
'url_html_suffix' => 'html',
// 域名根如thinkphp.cn
'url_domain_root' => '',
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
'request_cache_except' => [],
// +----------------------------------------------------------------------
// | 路由设置
// +----------------------------------------------------------------------
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL普通方式参数 用于自动生成
'url_common_param' => false,
// URL参数方式 0 按名称成对解析 1 按顺序解析
@ -97,36 +122,22 @@ return [
'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',
// 默认的路由变量规则
'default_route_pattern' => '\w+',
// 是否开启路由缓存
'route_check_cache' => false,
// 路由缓存的Key自定义设置闭包默认为当前URL和请求类型的md5
'route_check_cache_key' => '',
// +----------------------------------------------------------------------
// | 异常及错误设置
// +----------------------------------------------------------------------
// 默认跳转页面对应的模板文件
'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' => '页面错误!请稍后再试~',
// 显示错误信息
@ -180,6 +191,7 @@ return [
// +----------------------------------------------------------------------
// | Trace设置 开启 app_trace 后 有效
// +----------------------------------------------------------------------
'trace' => [
// 内置Html Console 支持扩展
'type' => 'Html',
@ -222,6 +234,7 @@ return [
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
'cookie' => [
// cookie 名称前缀
'prefix' => '',

View File

@ -101,7 +101,7 @@ if (!function_exists('bind')) {
*/
function bind($abstract, $concrete = null)
{
return Container::getInstance()->bind($abstract, $concrete);
return Container::getInstance()->bindTo($abstract, $concrete);
}
}

View File

@ -18,9 +18,9 @@ use think\route\Dispatch;
/**
* App 应用管理
*/
class App implements \ArrayAccess
class App extends Container
{
const VERSION = '5.1.13';
const VERSION = '5.1.14';
/**
* 当前模块路径
@ -32,7 +32,7 @@ class App implements \ArrayAccess
* 应用调试模式
* @var bool
*/
protected $debug = true;
protected $appDebug = true;
/**
* 应用开始时间
@ -112,22 +112,15 @@ class App implements \ArrayAccess
*/
protected $dispatch;
/**
* 容器对象实例
* @var Container
*/
protected $container;
/**
* 绑定模块(控制器)
* @var string
*/
protected $bind;
protected $bindModule;
public function __construct($appPath = '')
{
$this->appPath = $appPath ? realpath($appPath) . DIRECTORY_SEPARATOR : $this->getAppPath();
$this->container = Container::getInstance();
$this->appPath = $appPath ? realpath($appPath) . DIRECTORY_SEPARATOR : $this->getAppPath();
$this->thinkPath = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR;
$this->rootPath = dirname($this->appPath) . DIRECTORY_SEPARATOR;
@ -144,7 +137,7 @@ class App implements \ArrayAccess
*/
public function bind($bind)
{
$this->bind = $bind;
$this->bindModule = $bind;
return $this;
}
@ -160,6 +153,39 @@ class App implements \ArrayAccess
return $this;
}
/**
* 注册核心容器实例
* @access public
* @return void
*/
public function registerCoreContainer()
{
// 注册核心类到容器
$this->bindTo([
'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,
]);
}
/**
* 初始化应用
* @access public
@ -170,6 +196,15 @@ class App implements \ArrayAccess
$this->beginTime = microtime(true);
$this->beginMem = memory_get_usage();
static::setInstance($this);
$this->registerCoreContainer();
$this->instance('app', $this);
// 加载惯例配置文件
$this->config->set(include $this->thinkPath . 'convention.php');
// 设置路径环境变量
$this->env->set([
'think_path' => $this->thinkPath,
@ -202,10 +237,10 @@ class App implements \ArrayAccess
$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);
$this->appDebug = $this->env->get('app_debug', $this->config('app.app_debug'));
$this->env->set('app_debug', $this->appDebug);
if (!$this->debug) {
if (!$this->appDebug) {
ini_set('display_errors', 'Off');
} elseif (PHP_SAPI != 'cli') {
//重新申请一块比较大的buffer
@ -218,14 +253,25 @@ class App implements \ArrayAccess
}
}
// 注册异常处理类
if ($this->config('app.exception_handle')) {
Error::setExceptionHandler($this->config('app.exception_handle'));
}
// 注册根命名空间
if (!empty($this->config('app.root_namespace'))) {
Loader::addNamespace($this->config('app.root_namespace'));
}
// 加载composer autofile文件
Loader::loadComposerAutoloadFiles();
// 注册类库别名
Loader::addClassAlias($this->config->pull('alias'));
// 数据库配置初始化
Db::init($this->config->pull('database'));
// 设置系统时区
date_default_timezone_set($this->config('app.default_timezone'));
@ -284,7 +330,7 @@ class App implements \ArrayAccess
if (is_file($path . 'provider.php')) {
$provider = include $path . 'provider.php';
if (is_array($provider)) {
$this->container->bind($provider);
$this->bindTo($provider);
}
}
@ -307,7 +353,40 @@ class App implements \ArrayAccess
$this->setModulePath($path);
$this->request->filter($this->config('app.default_filter'));
if ($module) {
// 对容器中的对象实例进行配置更新
$this->containerConfigUpdate($module);
}
}
protected function containerConfigUpdate($module)
{
$config = $this->config->get();
// 注册异常处理类
if ($config['app']['exception_handle']) {
Error::setExceptionHandler($config['app']['exception_handle']);
}
Db::init($config['database']);
$this->request->init($config['app']);
$this->cookie->init($config['cookie']);
$this->view->init($config['template']);
$this->log->init($config['log']);
$this->session->setConfig($config['session']);
$this->debug->setConfig($config['trace']);
$this->cache->init($config['cache'], true);
// 加载当前模块语言包
$this->lang->load($this->appPath . $module . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php');
// 模块请求缓存检查
$this->request->cache(
$config['app']['request_cache'],
$config['app']['request_cache_expire'],
$config['app']['request_cache_except']
);
}
/**
@ -322,9 +401,9 @@ class App implements \ArrayAccess
// 初始化应用
$this->initialize();
if ($this->bind) {
if ($this->bindModule) {
// 模块/控制器绑定
$this->route->bind($this->bind);
$this->route->bind($this->bindModule);
} elseif ($this->config('app.auto_bind_module')) {
// 入口自动绑定
$name = pathinfo($this->request->baseFile(), PATHINFO_FILENAME);
@ -337,22 +416,32 @@ class App implements \ArrayAccess
$this->hook->listen('app_dispatch');
// 获取应用调度信息
if (!$this->appDebug && $this->config->get('route_check_cache')) {
$routeKey = $this->getRouteCacheKey();
if ($this->cache->has($routeKey)) {
$this->dispatch = $this->cache->get($routeKey);
}
}
$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();
try {
if (isset($routeKey)) {
$this->cache->tag('route_cache')->set($routeKey, $dispatch);
}
} catch (\Exception $e) {}
}
// 记录当前调度信息
$this->request->dispatch($dispatch);
// 记录路由和请求信息
if ($this->debug) {
if ($this->appDebug) {
$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));
@ -363,9 +452,9 @@ class App implements \ArrayAccess
// 请求缓存检查
$this->request->cache(
$this->config('app.request_cache'),
$this->config('app.request_cache_expire'),
$this->config('app.request_cache_except')
$this->config('request_cache'),
$this->config('request_cache_expire'),
$this->config('request_cache_except')
);
$data = null;
@ -407,10 +496,23 @@ class App implements \ArrayAccess
return $response;
}
protected function getRouteCacheKey()
{
if ($this->config->get('route_check_cache_key')) {
$closure = $this->config->get('route_check_cache_key');
$routeKey = $closure($this->request);
} else {
$routeKey = md5($this->request->baseUrl(true) . ':' . $this->request->method());
}
return $routeKey;
}
protected function loadLangPack()
{
// 读取默认语言
$this->lang->range($this->config('app.default_lang'));
if ($this->config('app.lang_switch_on')) {
// 开启多语言机制 检测当前语言
$this->lang->detect();
@ -446,7 +548,7 @@ class App implements \ArrayAccess
*/
public function log($msg, $type = 'info')
{
$this->debug && $this->log->record($msg, $type);
$this->appDebug && $this->log->record($msg, $type);
}
/**
@ -468,7 +570,6 @@ class App implements \ArrayAccess
public function routeCheck()
{
$path = $this->request->path();
$depr = $this->config('app.pathinfo_depr');
// 路由检测
$files = scandir($this->routePath);
@ -483,10 +584,10 @@ class App implements \ArrayAccess
}
}
if ($this->config('app.route_annotation')) {
if ($this->config('route.route_annotation')) {
// 自动生成路由定义
if ($this->debug) {
$this->build->buildRoute($this->config('app.controller_suffix'));
if ($this->appDebug) {
$this->build->buildRoute($this->config('route.controller_suffix'));
}
$filename = $this->runtimePath . 'build_route.php';
@ -501,10 +602,10 @@ class App implements \ArrayAccess
}
// 是否强制路由模式
$must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');
$must = !is_null($this->routeMust) ? $this->routeMust : $this->route->config('url_route_must');
// 路由检测 返回一个Dispatch对象
return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match'));
return $this->route->check($path, $must);
}
/**
@ -677,7 +778,7 @@ class App implements \ArrayAccess
}
}
return $this->container->invokeMethod([$class, $action . $this->config('action_suffix')], $vars);
return $this->invokeMethod([$class, $action . $this->config('action_suffix')], $vars);
}
/**
@ -716,7 +817,7 @@ class App implements \ArrayAccess
*/
public function isDebug()
{
return $this->debug;
return $this->appDebug;
}
/**
@ -867,53 +968,4 @@ class App implements \ArrayAccess
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->delete($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);
}
}

View File

@ -30,10 +30,10 @@ class Cache
protected $instance = [];
/**
* 应用对象
* @var App
* 缓存配置
* @var array
*/
protected $app;
protected $config = [];
/**
* 操作句柄
@ -41,9 +41,10 @@ class Cache
*/
protected $handler;
public function __construct(App $app)
public function __construct(array $config = [])
{
$this->app = $app;
$this->config = $config;
$this->init($config);
}
/**
@ -55,23 +56,18 @@ class Cache
*/
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);
$type = !empty($options['type']) ? $options['type'] : 'File';
if (true === $name) {
$name = md5(serialize($options));
}
$this->instance[$name] = new $class($options);
$this->instance[$name] = Loader::factory($type, '\\think\\cache\\driver\\', $options);
}
return $this->instance[$name];
@ -81,19 +77,16 @@ class Cache
* 自动初始化缓存
* @access public
* @param array $options 配置数组
* @param bool $force 强制更新
* @return Driver
*/
public function init(array $options = [])
public function init(array $options = [], $force = false)
{
if (is_null($this->handler)) {
// 自动初始化缓存
$config = $this->app['config'];
if (is_null($this->handler) || $force) {
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');
if ('complex' == $options['type']) {
$default = $options['default'];
$options = isset($options[$default['type']]) ? $options[$default['type']] : $default;
}
$this->handler = $this->connect($options);
@ -102,6 +95,16 @@ class Cache
return $this->handler;
}
public static function __make(Config $config)
{
return new static($config->pull('cache'));
}
public function setConfig(array $config)
{
$this->config = array_merge($this->config, $config);
}
/**
* 切换缓存类型 需要配置 cache.type complex
* @access public
@ -110,8 +113,8 @@ class Cache
*/
public function store($name = '')
{
if ('' !== $name && 'complex' == $this->app['config']->get('cache.type')) {
return $this->connect($this->app['config']->get('cache.' . $name), strtolower($name));
if ('' !== $name && 'complex' == $this->config['type']) {
return $this->connect($this->config[$name], strtolower($name));
}
return $this->init();

View File

@ -20,11 +20,22 @@ class Config implements \ArrayAccess
private $config = [];
/**
* 缓存前缀
* 配置前缀
* @var string
*/
private $prefix = 'app';
/**
* 应用对象
* @var App
*/
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
/**
* 设置配置参数默认前缀
* @access public
@ -50,9 +61,9 @@ class Config implements \ArrayAccess
$type = pathinfo($config, PATHINFO_EXTENSION);
}
$class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type);
$object = Loader::factory($type, '\\think\\config\\driver\\', $config);
return $this->set((new $class())->parse($config), $name);
return $this->set($object->parse(), $name);
}
/**
@ -88,15 +99,14 @@ class Config implements \ArrayAccess
protected function autoLoad($name)
{
// 如果尚未载入 则动态加载配置文件
$module = Container::get('request')->module();
$module = $this->app->request->module();
$module = $module ? $module . DIRECTORY_SEPARATOR : '';
$app = Container::get('app');
$path = $app->getAppPath() . $module;
$path = $this->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();
$file = $path . 'config' . DIRECTORY_SEPARATOR . $name . $this->app->getConfigExt();
} elseif (is_dir($this->app->getConfigPath() . $module)) {
$file = $this->app->getConfigPath() . $module . $name . $this->app->getConfigExt();
}
if (isset($file) && is_file($file)) {

View File

@ -19,7 +19,7 @@ use ReflectionFunction;
use ReflectionMethod;
use think\exception\ClassNotFoundException;
class Container
class Container implements \ArrayAccess
{
/**
* 容器对象实例
@ -37,7 +37,14 @@ class Container
* 容器绑定标识
* @var array
*/
protected $bind = [];
protected $bind = [
'app' => 'think\App',
'config' => 'think\Config',
'lang' => 'think\Lang',
'log' => 'think\Log',
'request' => 'think\Request',
'response' => 'think\Response',
];
/**
* 容器标识别名
@ -59,6 +66,17 @@ class Container
return static::$instance;
}
/**
* 设置当前容器的实例
* @access public
* @param object $instance
* @return void
*/
public static function setInstance($instance)
{
static::$instance = $instance;
}
/**
* 获取容器中的对象实例
* @access public
@ -81,7 +99,7 @@ class Container
*/
public static function set($abstract, $concrete = null)
{
return static::getInstance()->bind($abstract, $concrete);
return static::getInstance()->bindTo($abstract, $concrete);
}
/**
@ -112,7 +130,7 @@ class Container
* @param mixed $concrete 要绑定的类、闭包或者实例
* @return $this
*/
public function bind($abstract, $concrete = null)
public function bindTo($abstract, $concrete = null)
{
if (is_array($abstract)) {
$this->bind = array_merge($this->bind, $abstract);
@ -378,8 +396,7 @@ class Container
$class = $param->getClass();
if ($class) {
$className = $class->getName();
$args[] = $this->make($className);
$args[] = $this->getObjectParam($class->getName(), $vars);
} elseif (1 == $type && !empty($vars)) {
$args[] = array_shift($vars);
} elseif (0 == $type && isset($vars[$name])) {
@ -394,4 +411,64 @@ class Container
return $args;
}
/**
* 获取对象类型的参数值
* @access protected
* @param string $className 类名
* @param array $vars 参数
* @return mixed
*/
protected function getObjectParam($className, &$vars)
{
$value = array_shift($vars);
if ($value instanceof $className) {
$result = $value;
} else {
array_unshift($vars, $value);
$result = $this->make($className);
}
return $result;
}
public function __set($name, $value)
{
$this->bindTo($name, $value);
}
public function __get($name)
{
return $this->make($name);
}
public function __isset($name)
{
return $this->bound($name);
}
public function __unset($name)
{
$this->delete($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);
}
}

View File

@ -30,12 +30,6 @@ class Controller
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 验证失败是否抛出异常
* @var bool
@ -58,13 +52,11 @@ class Controller
* 构造方法
* @access public
*/
public function __construct()
public function __construct(App $app = null)
{
$this->request = Container::get('request');
$this->app = Container::get('app');
$this->view = Container::get('view')->init(
$this->app['config']->pull('template')
);
$this->app = $app ?: Container::get('app');
$this->request = $this->app['request'];
$this->view = $this->app['view'];
// 控制器初始化
$this->initialize();

View File

@ -35,10 +35,13 @@ class Cookie
];
/**
* 是否初始化
* @var bool
* 构造方法
* @access public
*/
protected $init;
public function __construct(array $config = [])
{
$this->init($config);
}
/**
* Cookie初始化
@ -48,17 +51,16 @@ class Cookie
*/
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;
public static function __make(Config $config)
{
return new static($config->pull('cookie'));
}
/**
@ -87,8 +89,6 @@ class Cookie
*/
public function set($name, $value = '', $option = null)
{
!isset($this->init) && $this->init();
// 参数设置(会覆盖黙认设置)
if (!is_null($option)) {
if (is_numeric($option)) {
@ -147,8 +147,6 @@ class Cookie
*/
public function has($name, $prefix = null)
{
!isset($this->init) && $this->init();
$prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
$name = $prefix . $name;
@ -164,8 +162,6 @@ class Cookie
*/
public function get($name = '', $prefix = null)
{
!isset($this->init) && $this->init();
$prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
$key = $prefix . $name;
@ -204,8 +200,6 @@ class Cookie
*/
public function delete($name, $prefix = null)
{
!isset($this->init) && $this->init();
$config = $this->config;
$prefix = !is_null($prefix) ? $prefix : $config['prefix'];
$name = $prefix . $name;
@ -231,8 +225,6 @@ class Cookie
return;
}
!isset($this->init) && $this->init();
// 要删除的cookie前缀不指定则删除config设置的指定前缀
$config = $this->config;
$prefix = !is_null($prefix) ? $prefix : $config['prefix'];

View File

@ -11,6 +11,8 @@
namespace think;
use think\db\Connection;
/**
* Class Db
* @package think
@ -57,6 +59,18 @@ namespace think;
*/
class Db
{
/**
* 当前数据库连接对象
* @var Connection
*/
protected static $connection;
/**
* 数据库配置
* @var array
*/
protected static $config = [];
/**
* 查询次数
* @var integer
@ -69,12 +83,108 @@ class Db
*/
public static $executeTimes = 0;
/**
* 配置
* @access public
* @param mixed $config
* @return void
*/
public static function init($config = [])
{
self::$config = $config;
if (empty($config['query'])) {
self::$config['query'] = '\\think\\db\\Query';
}
}
/**
* 获取数据库配置
* @access public
* @return array
*/
public static function getConfig()
{
return self::$config;
}
/**
* 切换数据库连接
* @access public
* @param mixed $config 连接配置
* @param bool|string $name 连接标识 true 强制重新连接
* @param string $query 查询对象类名
* @return mixed 返回查询对象实例
* @throws Exception
*/
public static function connect($config = [], $name = false, $query = '')
{
// 解析配置参数
$options = self::parseConfig($config ?: self::$config);
$query = $query ?: self::$config['query'];
// 创建数据库连接对象实例
self::$connection = Connection::instance($options, $name);
return new $query(self::$connection);
}
/**
* 数据库连接参数解析
* @access private
* @param mixed $config
* @return array
*/
private static function parseConfig($config)
{
if (is_string($config) && false === strpos($config, '/')) {
// 支持读取配置参数
$config = isset(self::$config[$config]) ? self::$config[$config] : self::$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;
}
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);
return call_user_func_array([static::connect(), $method], $args);
}
}

View File

@ -11,12 +11,17 @@
namespace think;
use think\exception\ClassNotFoundException;
use think\model\Collection as ModelCollection;
use think\response\Redirect;
class Debug
{
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* 区间时间信息
* @var array
@ -35,9 +40,20 @@ class Debug
*/
protected $app;
public function __construct(App $app)
public function __construct(App $app, array $config = [])
{
$this->app = $app;
$this->app = $app;
$this->config = $config;
}
public static function __make(App $app, Config $config)
{
return new static($app, $config->pull('trace'));
}
public function setConfig(array $config)
{
$this->config = array_merge($this->config, $config);
}
/**
@ -221,7 +237,7 @@ class Debug
$output = '<pre>' . $label . $output . '</pre>';
}
if ($echo) {
echo($output);
echo ($output);
return;
}
return $output;
@ -229,16 +245,12 @@ class Debug
public function inject(Response $response, &$content)
{
$config = $this->app['config']->pull('trace');
$config = $this->config;
$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);
}
$trace = Loader::factory($type, '\\think\\debug\\', $config);
if ($response instanceof Redirect) {
//TODO 记录

View File

@ -18,6 +18,12 @@ use think\exception\ThrowableError;
class Error
{
/**
* 配置参数
* @var array
*/
protected static $exceptionHandler;
/**
* 注册异常处理
* @access public
@ -100,6 +106,18 @@ class Error
return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);
}
/**
* 设置异常处理类
*
* @access public
* @param mixed $handle
* @return void
*/
public static function setExceptionHandler($handle)
{
self::$exceptionHandler = $handle;
}
/**
* Get an instance of the exception handler.
*
@ -112,7 +130,8 @@ class Error
if (!$handle) {
// 异常处理handle
$class = Container::get('config')->get('exception_handle');
$class = self::$exceptionHandler;
if ($class && is_string($class) && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) {
$handle = new $class;
} else {

View File

@ -85,15 +85,13 @@ class Facade
/**
* 带参数实例化当前Facade类
* @access public
* @return object
* @return mixed
*/
public static function instance(...$args)
{
if (__CLASS__ != static::class) {
return self::__callStatic('instance', $args);
return self::createFacade('', $args);
}
return self::createFacade('', $args);
}
/**
@ -102,7 +100,7 @@ class Facade
* @param string $class 类名或者标识
* @param array|true $args 变量
* @param bool $newInstance 是否每次创建新的实例
* @return object
* @return mixed
*/
public static function make($class, $args = [], $newInstance = false)
{

View File

@ -31,6 +31,17 @@ class Hook
*/
private static $portal = 'run';
/**
* 应用对象
* @var App
*/
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
/**
* 指定入口方法名称
* @access public
@ -163,7 +174,7 @@ class Hook
$method = [$class, self::$portal];
}
return Container::getInstance()->invoke($method, [$params]);
return $this->app->invoke($method, [$params]);
}
/**
@ -176,9 +187,7 @@ class Hook
*/
protected function execTag($class, $tag = '', $params = null)
{
$app = Container::get('app');
$app->isDebug() && $app['debug']->remark('behavior_start', 'time');
$this->app->isDebug() && $this->app['debug']->remark('behavior_start', 'time');
$method = Loader::parseName($tag, 1, false);
@ -198,12 +207,12 @@ class Hook
$class = $class . '->' . $method;
}
$result = Container::getInstance()->invoke($call, [$params]);
$result = $this->app->invoke($call, [$params]);
if ($app->isDebug()) {
$debug = $app['debug'];
if ($this->app->isDebug()) {
$debug = $this->app['debug'];
$debug->remark('behavior_end', 'time');
$app->log('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . $debug->getRangeTime('behavior_start', 'behavior_end') . 's ]');
$this->app->log('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . $debug->getRangeTime('behavior_start', 'behavior_end') . 's ]');
}
return $result;

View File

@ -51,6 +51,17 @@ class Lang
'zh-hans-cn' => 'zh-cn',
];
/**
* 应用对象
* @var App
*/
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
// 设定当前的语言
public function range($range = '')
{
@ -108,7 +119,7 @@ class Lang
foreach ($file as $_file) {
if (is_file($_file)) {
// 记录加载信息
Container::get('app')->log('[ LANG ] ' . $_file);
$this->app->log('[ LANG ] ' . $_file);
$_lang = include $_file;
if (is_array($_lang)) {
$lang = array_change_key_case($_lang) + $lang;
@ -200,11 +211,8 @@ class Lang
} 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 = strtolower($matches[1]);
if (isset($this->acceptLanguage[$langSet])) {
$langSet = $this->acceptLanguage[$langSet];
}
}
@ -258,8 +266,19 @@ class Lang
* @param array $list 语言列表
* @return void
*/
public function setAllowLangList($list)
public function setAllowLangList(array $list)
{
$this->allowLangList = $list;
}
/**
* 设置转义的语言列表
* @access public
* @param array $list 语言列表
* @return void
*/
public function setAcceptLanguage(array $list)
{
$this->acceptLanguage = array_merge($this->acceptLanguage, $list);
}
}

View File

@ -11,6 +11,8 @@
namespace think;
use think\exception\ClassNotFoundException;
class Loader
{
/**
@ -378,6 +380,24 @@ class Loader
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
}
/**
* 创建工厂对象实例
* @access public
* @param string $name 工厂类名
* @param string $namespace 默认命名空间
* @return mixed
*/
public static function factory($name, $namespace = '', ...$args)
{
$class = false !== strpos($name, '\\') ? $name : $namespace . ucwords($name);
if (class_exists($class)) {
return Container::getInstance()->invokeClass($class, $args);
} else {
throw new ClassNotFoundException('class not exists:' . $class, $class);
}
}
}
/**

View File

@ -11,8 +11,6 @@
namespace think;
use think\exception\ClassNotFoundException;
class Log implements LoggerInterface
{
const EMERGENCY = 'emergency';
@ -66,6 +64,11 @@ class Log implements LoggerInterface
$this->app = $app;
}
public static function __make(App $app, Config $config)
{
return (new static($app))->init($config->pull('log'));
}
/**
* 日志初始化
* @access public
@ -74,24 +77,17 @@ class Log implements LoggerInterface
*/
public function init($config = [])
{
$type = isset($config['type']) ? $config['type'] : 'File';
$class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type);
$type = isset($config['type']) ? $config['type'] : 'File';
$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);
$this->driver = Loader::factory($type, '\\think\\log\\driver\\', $config);
return $this;
}
@ -200,14 +196,10 @@ class Log implements LoggerInterface
*/
public function save()
{
if (empty($this->log) || !$this->allowWrite) {
if (empty($this->log) || !$this->allowWrite || !$this->driver) {
return true;
}
if (is_null($this->driver)) {
$this->init($this->app['config']->pull('log'));
}
if (!$this->check($this->config)) {
// 检测日志写入权限
return false;
@ -261,10 +253,6 @@ class Log implements LoggerInterface
// 监听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);

View File

@ -18,6 +18,26 @@ use think\exception\HttpResponseException;
class Middleware
{
protected $queue = [];
protected $app;
protected $config = [
'default_namespace' => 'app\\http\\middleware\\',
];
public function __construct(App $app, array $config = [])
{
$this->app = $app;
$this->config = array_merge($this->config, $config);
}
public static function __make(App $app, Config $config)
{
return new static($app, $config->pull('middleware'));
}
public function setConfig(array $config)
{
$this->config = array_merge($this->config, $config);
}
public function import(array $middlewares = [])
{
@ -89,8 +109,11 @@ class Middleware
}
if (false === strpos($middleware, '\\')) {
$value = Container::get('config')->get('middleware.' . $middleware);
$middleware = $value ?: Container::get('app')->getNamespace() . '\\http\\middleware\\' . $middleware;
if (isset($this->config[$middleware])) {
$middleware = $this->config[$middleware];
} else {
$middleware = $this->config['default_namespace'] . $middleware;
}
}
if (is_array($middleware)) {
@ -101,7 +124,7 @@ class Middleware
list($middleware, $param) = explode(':', $middleware, 2);
}
return [[Container::get($middleware), 'handle'], isset($param) ? $param : null];
return [[$this->app->make($middleware), 'handle'], isset($param) ? $param : null];
}
protected function resolve()

View File

@ -32,6 +32,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/
private $isUpdate = false;
/**
* 是否Replace
* @var bool
*/
private $replace = false;
/**
* 是否强制更新所有数据
* @var bool
@ -141,13 +147,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 记录原始数据
$this->origin = $this->data;
$config = Container::get('config');
$config = Db::getConfig();
if (empty($this->name)) {
// 当前模型名
$name = str_replace('\\', '/', static::class);
$this->name = basename($name);
if ($config->get('class_suffix')) {
if (Container::get('config')->get('class_suffix')) {
$suffix = basename(dirname($name));
$this->name = substr($this->name, 0, -strlen($suffix));
}
@ -155,26 +161,26 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (is_null($this->autoWriteTimestamp)) {
// 自动写入时间戳
$this->autoWriteTimestamp = $config->get('database.auto_timestamp');
$this->autoWriteTimestamp = $config['auto_timestamp'];
}
if (is_null($this->dateFormat)) {
// 设置时间戳格式
$this->dateFormat = $config->get('database.datetime_format');
$this->dateFormat = $config['datetime_format'];
}
if (is_null($this->resultSetType)) {
$this->resultSetType = $config->get('database.resultset_type');
$this->resultSetType = $config['resultset_type'];
}
if (is_null($this->query)) {
// 设置查询对象
$this->query = $config->get('database.query');
$this->query = $config['query'];
}
if (!empty($this->connection) && is_array($this->connection)) {
// 设置模型的数据库连接
$this->connection = array_merge($config->pull('database'), $this->connection);
$this->connection = array_merge($config, $this->connection);
}
if ($this->observerClass) {
@ -232,9 +238,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
protected function buildQuery()
{
// 设置当前模型 确保查询返回模型对象
$class = $this->query;
$query = (new $class())->connect($this->connection)
->model($this)
$query = Db::connect($this->connection, false, $this->query);
$query->model($this)
->json($this->json)
->setJsonFieldType($this->jsonType);
@ -355,6 +360,18 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
return $this;
}
/**
* 新增数据是否使用Replace
* @access public
* @param bool $replace
* @return $this
*/
public function replace($replace = true)
{
$this->replace = $replace;
return $this;
}
/**
* 保存当前数据对象
* @access public
@ -559,7 +576,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 检查允许字段
$allowFields = $this->checkAllowFields(array_merge($this->auto, $this->insert));
$result = $this->db(false)->strict(false)->field($allowFields)->insert($this->data, false, false, $sequence);
$result = $this->db(false)->strict(false)->field($allowFields)->insert($this->data, $this->replace, false, $sequence);
// 获取自动增长主键
if ($result && $insertId = $this->db(false)->getLastInsID($sequence)) {
@ -780,9 +797,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @access public
* @param array $data 数据数组
* @param array|true $field 允许字段
* @param bool $replace 使用Replace
* @return static
*/
public static function create($data = [], $field = null)
public static function create($data = [], $field = null, $replace = false)
{
$model = new static();
@ -790,7 +808,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$model->allowField($field);
}
$model->isUpdate(false)->save($data, []);
$model->isUpdate(false)->replace($replace)->save($data, []);
return $model;
}

View File

@ -22,10 +22,16 @@ class Request
protected $instance;
/**
* 配置对象
* @var Config
* 应用对象实例
* @var App
*/
protected $config;
protected $app;
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* 请求类型
@ -262,24 +268,37 @@ class Request
* @access public
* @param array $options 参数
*/
public function __construct($options = [])
public function __construct(App $app, array $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');
}
$this->app = $app;
$this->init($options);
// 保存 php://input
$this->input = file_get_contents('php://input');
}
public function init(array $options = [])
{
$this->config = array_merge($this->config, $options);
if (is_null($this->filter) && !empty($this->config['default_filter'])) {
$this->filter = $this->config['default_filter'];
}
}
public function config($name = null)
{
if (is_null($name)) {
return $this->config;
}
return isset($this->config[$name]) ? $this->config[$name] : null;
}
public static function __make(App $app, Config $config)
{
return new static($app, $config->pull('app'));
}
public function __call($method, $args)
{
if (array_key_exists($method, $this->hook)) {
@ -431,7 +450,7 @@ class Request
*/
public function rootDomain()
{
$root = $this->config->get('app.url_domain_root');
$root = $this->config['url_domain_root'];
if (!$root) {
$item = explode('.', $this->host(true));
@ -451,7 +470,7 @@ class Request
{
if (is_null($this->subDomain)) {
// 获取当前主域名
$rootDomain = $this->config->get('app.url_domain_root');
$rootDomain = $this->config['url_domain_root'];
if ($rootDomain) {
// 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置
@ -609,10 +628,10 @@ class Request
public function pathinfo()
{
if (is_null($this->pathinfo)) {
if (isset($_GET[$this->config->get('var_pathinfo')])) {
if (isset($_GET[$this->config['var_pathinfo']])) {
// 判断URL里面是否有兼容模式参数
$_SERVER['PATH_INFO'] = $_GET[$this->config->get('var_pathinfo')];
unset($_GET[$this->config->get('var_pathinfo')]);
$_SERVER['PATH_INFO'] = $_GET[$this->config['var_pathinfo']];
unset($_GET[$this->config['var_pathinfo']]);
} elseif ($this->isCli()) {
// CLI模式下 index.php module/controller/action/params/...
$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
@ -622,7 +641,7 @@ class Request
// 分析PATHINFO信息
if (!isset($_SERVER['PATH_INFO'])) {
foreach ($this->config->get('pathinfo_fetch') as $type) {
foreach ($this->config['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];
@ -645,7 +664,7 @@ class Request
public function path()
{
if (is_null($this->path)) {
$suffix = $this->config->get('url_html_suffix');
$suffix = $this->config['url_html_suffix'];
$pathinfo = $this->pathinfo();
if (false === $suffix) {
// 禁止伪静态访问
@ -736,8 +755,8 @@ class Request
// 获取原始请求类型
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')]);
if (isset($_POST[$this->config['var_method']])) {
$this->method = strtoupper($_POST[$this->config['var_method']]);
$this->{$this->method}($_POST);
} elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
@ -1033,7 +1052,7 @@ class Request
public function session($name = '', $default = null, $filter = '')
{
if (empty($this->session)) {
$this->session = Container::get('session')->get();
$this->session = $this->app['session']->get();
}
if (is_array($name)) {
@ -1053,7 +1072,7 @@ class Request
*/
public function cookie($name = '', $default = null, $filter = '')
{
$cookie = Container::get('cookie');
$cookie = $this->app['cookie'];
if (empty($this->cookie)) {
$this->cookie = $cookie->get();
@ -1190,7 +1209,7 @@ class Request
public function env($name = '', $default = null, $filter = '')
{
if (empty($this->env)) {
$this->env = Container::get('env')->get();
$this->env = $this->app['env']->get();
}
if (is_array($name)) {
@ -1514,7 +1533,7 @@ class Request
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')])) {
} elseif ($this->config['https_agent_name'] && isset($server[$this->config['https_agent_name']])) {
return true;
}
@ -1536,7 +1555,7 @@ class Request
return $result;
}
return $this->param($this->config->get('var_ajax')) ? true : $result;
return $this->param($this->config['var_ajax']) ? true : $result;
}
/**
@ -1553,7 +1572,7 @@ class Request
return $result;
}
return $this->param($this->config->get('var_pjax')) ? true : $result;
return $this->param($this->config['var_pjax']) ? true : $result;
}
/**
@ -1572,7 +1591,7 @@ class Request
return $ip[$type];
}
$httpAgentIp = $this->config->get('http_agent_ip');
$httpAgentIp = $this->config['http_agent_ip'];
if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) {
$ip = $_SERVER[$httpAgentIp];
@ -1866,7 +1885,7 @@ class Request
header($name . ': ' . $token);
}
Container::get('session')->set($name, $token);
$this->app['session']->set($name, $token);
return $token;
}
@ -1934,7 +1953,7 @@ class Request
if (isset($fun)) {
$key = $fun($key);
}
$cache = Container::get('cache');
$cache = $this->app['cache'];
if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) {
// 读取缓存

View File

@ -21,6 +21,12 @@ class Response
*/
protected $data;
/**
* 应用对象实例
* @var App
*/
protected $app;
/**
* 当前contentType
* @var string
@ -82,6 +88,7 @@ class Response
$this->contentType($this->contentType, $this->charset);
$this->code = $code;
$this->app = Container::get('app');
$this->header = array_merge($this->header, $header);
}
@ -115,24 +122,24 @@ class Response
public function send()
{
// 监听response_send
Container::get('hook')->listen('response_send', $this);
$this->app['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 ('cli' != PHP_SAPI && $this->app['env']->get('app_trace', $this->app->config('app.app_trace'))) {
$this->app['debug']->inject($this, $data);
}
if (200 == $this->code && $this->allowCache) {
$cache = Container::get('request')->getCache();
$cache = $this->app['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]);
$this->app['cache']->tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);
}
}
@ -153,11 +160,11 @@ class Response
}
// 监听response_end
Container::get('hook')->listen('response_end', $this);
$this->app['hook']->listen('response_end', $this);
// 清空当次请求有效的数据
if (!($this instanceof RedirectResponse)) {
Container::get('session')->flush();
$this->app['session']->flush();
}
}

View File

@ -48,10 +48,10 @@ class Route
];
/**
* 配置对象
* @var Config
* 应用对象
* @var App
*/
protected $config;
protected $app;
/**
* 请求对象
@ -77,6 +77,12 @@ class Route
*/
protected $group;
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* 路由绑定
* @var array
@ -119,14 +125,37 @@ class Route
*/
protected $autoSearchController = true;
public function __construct(Request $request)
public function __construct(App $app, array $config = [])
{
$this->request = $request;
$this->app = $app;
$this->request = $app['request'];
$this->config = $config;
$this->host = $this->request->host(true);
$this->setDefaultDomain();
}
public function config($name = null)
{
if (is_null($name)) {
return $this->config;
}
return isset($this->config[$name]) ? $this->config[$name] : null;
}
public static function __make(App $app, Config $config)
{
$config = $config->pull('app');
$route = new static($app, $config);
$route->lazy($config['url_lazy_route'])
->autoSearchController($config['controller_auto_search'])
->mergeRuleRegex($config['route_rule_merge']);
return $route;
}
/**
* 设置路由域名及分组(包括资源路由)是否延迟解析
* @access public
@ -346,7 +375,7 @@ class Route
*/
public function getName($name = null)
{
return Container::get('rule_name')->get($name);
return $this->app['rule_name']->get($name);
}
/**
@ -357,7 +386,7 @@ class Route
*/
public function setName($name)
{
Container::get('rule_name')->import($name);
$this->app['rule_name']->import($name);
return $this;
}
@ -761,23 +790,23 @@ class 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)
public function check($url, $must = false)
{
// 自动检测域名路由
$domain = $this->checkDomain();
$url = str_replace($depr, '|', $url);
$url = str_replace($this->config['pathinfo_depr'], '|', $url);
$result = $domain->check($this->request, $url, $depr, $completeMatch);
$completeMatch = $this->config['route_complete_match'];
$result = $domain->check($this->request, $url, $completeMatch);
if (false === $result && !empty($this->cross)) {
// 检测跨域路由
$result = $this->cross->check($this->request, $url, $depr, $completeMatch);
$result = $this->cross->check($this->request, $url, $completeMatch);
}
if (false !== $result) {
@ -789,7 +818,9 @@ class Route
}
// 默认路由解析
return new UrlDispatch($url, ['depr' => $depr, 'auto_search' => $this->autoSearchController]);
$ruleItem = new RuleItem($this, $this->group, '', '', $url);
return new UrlDispatch($this->request, $ruleItem, $url, ['auto_search' => $this->autoSearchController]);
}
/**

View File

@ -15,6 +15,12 @@ use think\exception\ClassNotFoundException;
class Session
{
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* 前缀
* @var string
@ -51,6 +57,11 @@ class Session
*/
protected $lock = false;
public function __construct(array $config = [])
{
$this->config = $config;
}
/**
* 设置或者获取session作用域前缀
* @access public
@ -68,6 +79,22 @@ class Session
}
}
public static function __make(Config $config)
{
return new static($config->pull('session'));
}
/**
* 配置
* @access public
* @param array $config
* @return void
*/
public function setConfig(array $config = [])
{
$this->config = array_merge($this->config, array_change_key_case($config));
}
/**
* session初始化
* @access public
@ -77,12 +104,8 @@ class Session
*/
public function init(array $config = [])
{
if (empty($config)) {
$config = Container::get('config')->pull('session');
}
$config = $config ?: $this->config;
// 记录初始化信息
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);
@ -161,6 +184,8 @@ class Session
} else {
$this->init = false;
}
return $this;
}
/**
@ -253,8 +278,7 @@ class Session
*/
protected function initDriver()
{
// 不在 init 方法中实例化lockDriver是因为 init 方法不一定先于 set 或 get 方法调用
$config = Container::get('config')->pull('session');
$config = $this->config;
if (!empty($config['type']) && isset($config['use_lock']) && $config['use_lock']) {
// 读取session驱动

View File

@ -20,6 +20,7 @@ use think\exception\TemplateNotFoundException;
*/
class Template
{
protected $app;
/**
* 模板变量
* @var array
@ -83,9 +84,10 @@ class Template
* @access public
* @param array $config
*/
public function __construct(array $config = [])
public function __construct(App $app, array $config = [])
{
$this->config['cache_path'] = Container::get('app')->getRuntimePath() . 'temp/';
$this->app = $app;
$this->config['cache_path'] = $app->getRuntimePath() . 'temp/';
$this->config = array_merge($this->config, $config);
$this->config['taglib_begin_origin'] = $this->config['taglib_begin'];
@ -97,10 +99,14 @@ class Template
$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);
$type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File';
$this->storage = new $class();
$this->storage = Loader::factory($type, '\\think\\template\\driver\\', null);
}
public static function __make(Config $config)
{
return new static($config->pull('template'));
}
/**
@ -189,7 +195,7 @@ class Template
$this->config($config);
}
$cache = Container::get('cache');
$cache = $this->app['cache'];
if (!empty($this->config['cache_id']) && $this->config['display_cache']) {
// 读取渲染缓存
@ -337,7 +343,7 @@ class Template
{
if ($cacheId && $this->config['display_cache']) {
// 缓存页面输出
return Container::get('cache')->has($cacheId);
return $this->app['cache']->has($cacheId);
}
return false;
@ -1218,10 +1224,10 @@ class Template
}
if ($this->config['view_base']) {
$module = isset($module) ? $module : Container::get('request')->module();
$module = isset($module) ? $module : $this->app['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'];
$path = isset($module) ? $this->app->getAppPath() . $module . DIRECTORY_SEPARATOR . basename($this->config['view_path']) . DIRECTORY_SEPARATOR : $this->config['view_path'];
}
$template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.');

View File

@ -13,6 +13,12 @@ namespace think;
class Url
{
/**
* 配置参数
* @var array
*/
protected $config = [];
/**
* ROOT地址
* @var string
@ -31,9 +37,10 @@ class Url
*/
protected $app;
public function __construct(App $app)
public function __construct(App $app, array $config = [])
{
$this->app = $app;
$this->app = $app;
$this->config = $config;
if (is_file($app->getRuntimePath() . 'route.php')) {
// 读取路由映射文件
@ -41,6 +48,22 @@ class Url
}
}
/**
* 初始化
* @access public
* @param array $config
* @return void
*/
public function init(array $config = [])
{
$this->config = array_merge($this->config, array_change_key_case($config));
}
public static function __make(App $app, Config $config)
{
return new static($app, $config->pull('app'));
}
/**
* URL生成 支持路由反射
* @access public
@ -105,7 +128,7 @@ class Url
$url = $match[0];
if (!empty($match[1])) {
$host = $this->app['config']->get('app_host') ?: $this->app['request']->host(true);
$host = $this->config['app_host'] ?: $this->app['request']->host(true);
if ($domain || $match[1] != $host) {
$domain = $match[1];
}
@ -166,7 +189,7 @@ class Url
}
// 还原URL分隔符
$depr = $this->app['config']->get('pathinfo_depr');
$depr = $this->config['pathinfo_depr'];
$url = str_replace('/', $depr, $url);
// URL后缀
@ -182,11 +205,11 @@ class Url
// 参数组装
if (!empty($vars)) {
// 添加参数
if ($this->app['config']->get('url_common_param')) {
if ($this->config['url_common_param']) {
$vars = http_build_query($vars);
$url .= $suffix . '?' . $vars . $anchor;
} else {
$paramType = $this->app['config']->get('url_param_type');
$paramType = $this->config['url_param_type'];
foreach ($vars as $var => $val) {
if ('' !== trim($val)) {
@ -244,7 +267,7 @@ class Url
$module = empty($path) ? $module : array_pop($path) . '/';
}
if ($this->app['config']->get('url_convert')) {
if ($this->config['url_convert']) {
$action = strtolower($action);
$controller = Loader::parseName($controller);
}
@ -265,7 +288,7 @@ class Url
$rootDomain = $this->app['request']->rootDomain();
if (true === $domain) {
// 自动判断域名
$domain = $this->app['config']->get('app_host') ?: $this->app['request']->host(true);
$domain = $this->config['app_host'] ?: $this->app['request']->host(true);
$domains = $this->app['route']->getDomains();
@ -302,7 +325,7 @@ class Url
if (false !== strpos($domain, '://')) {
$scheme = '';
} else {
$scheme = $this->app['request']->isSsl() || $this->app['config']->get('is_https') ? 'https://' : 'http://';
$scheme = $this->app['request']->isSsl() || $this->config['is_https'] ? 'https://' : 'http://';
}
@ -313,7 +336,7 @@ class Url
protected function parseSuffix($suffix)
{
if ($suffix) {
$suffix = true === $suffix ? $this->app['config']->get('url_html_suffix') : $suffix;
$suffix = true === $suffix ? $this->config['url_html_suffix'] : $suffix;
if ($pos = strpos($suffix, '|')) {
$suffix = substr($suffix, 0, $pos);
@ -332,7 +355,7 @@ class Url
return [rtrim($url, '?/-'), $domain, $suffix];
}
$type = $this->app['config']->get('url_common_param');
$type = $this->config['url_common_param'];
foreach ($pattern as $key => $val) {
if (isset($vars[$key])) {

View File

@ -1078,7 +1078,7 @@ class Validate
*/
public function requireCallback($value, $rule, $data)
{
$result = call_user_func_array($rule, [$value, $data]);
$result = call_user_func_array([$this, $rule], [$value, $data]);
if ($result) {
return !empty($value) || '0' == $value;
@ -1447,12 +1447,12 @@ class Validate
$scene = $this->currentScene;
}
$this->only = $this->append = $this->remove = [];
if (empty($scene)) {
return;
}
$this->only = $this->append = $this->remove = [];
if (method_exists($this, 'scene' . $scene)) {
call_user_func([$this, 'scene' . $scene]);
} elseif (isset($this->scene[$scene])) {

View File

@ -51,6 +51,11 @@ class View
return $this;
}
public static function __make(Config $config)
{
return (new static())->init($config->pull('template'));
}
/**
* 模板变量静态赋值
* @access public
@ -102,13 +107,11 @@ class View
$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);
$this->engine = Loader::factory($type, '\\think\\view\\driver\\', $options);
return $this;
}

View File

@ -13,12 +13,19 @@ namespace think\config\driver;
class Ini
{
public function parse($config)
protected $config;
public function __construct($config)
{
if (is_file($config)) {
return parse_ini_file($config, true);
$this->config = $config;
}
public function parse()
{
if (is_file($this->config)) {
return parse_ini_file($this->config, true);
} else {
return parse_ini_string($config, true);
return parse_ini_string($this->config, true);
}
}
}

View File

@ -13,14 +13,19 @@ namespace think\config\driver;
class Json
{
public function parse($config)
protected $config;
public function __construct($config)
{
if (is_file($config)) {
$config = file_get_contents($config);
}
$result = json_decode($config, true);
$this->config = $config;
}
return $result;
public function parse()
{
return json_decode($this->config, true);
}
}

View File

@ -13,12 +13,19 @@ namespace think\config\driver;
class Xml
{
public function parse($config)
protected $config;
public function __construct($config)
{
if (is_file($config)) {
$content = simplexml_load_file($config);
$this->config = $config;
}
public function parse()
{
if (is_file($this->config)) {
$content = simplexml_load_file($this->config);
} else {
$content = simplexml_load_string($config);
$content = simplexml_load_string($this->config);
}
$result = (array) $content;

View File

@ -15,6 +15,7 @@ use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\App;
use think\facade\Cache;
class Clear extends Command
{
@ -25,6 +26,7 @@ class Clear extends Command
->setName('clear')
->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null)
->addOption('cache', 'c', Option::VALUE_NONE, 'clear cache file')
->addOption('route', 'u', Option::VALUE_NONE, 'clear route cache')
->addOption('log', 'l', Option::VALUE_NONE, 'clear log file')
->addOption('dir', 'r', Option::VALUE_NONE, 'clear empty dir')
->setDescription('Clear runtime file');
@ -32,16 +34,21 @@ class Clear extends Command
protected function execute(Input $input, Output $output)
{
if ($input->getOption('cache')) {
$path = App::getRuntimePath() . 'cache';
} elseif ($input->getOption('log')) {
$path = App::getRuntimePath() . 'log';
if ($input->getOption('route')) {
Cache::clear('route_cache');
} else {
$path = $input->getOption('path') ?: App::getRuntimePath();
if ($input->getOption('cache')) {
$path = App::getRuntimePath() . 'cache';
} elseif ($input->getOption('log')) {
$path = App::getRuntimePath() . 'log';
} else {
$path = $input->getOption('path') ?: App::getRuntimePath();
}
$rmdir = $input->getOption('dir') ? true : false;
$this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir);
}
$rmdir = $input->getOption('dir') ? true : false;
$this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir);
$output->writeln("<info>Clear Successed</info>");
}

View File

@ -20,6 +20,7 @@ use think\db\exception\BindParamException;
use think\Debug;
use think\Exception;
use think\exception\PDOException;
use think\Loader;
abstract class Connection
{
@ -182,22 +183,18 @@ abstract class Connection
}
if (true === $name || !isset(self::$instance[$name])) {
// 解析连接参数 支持数组和字符串
$options = self::parseConfig($config);
if (empty($options['type'])) {
if (empty($config['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']);
Container::get('app')->log('[ DB ] INIT ' . $config['type']);
if (true === $name) {
$name = md5(serialize($config));
}
self::$instance[$name] = new $class($options);
self::$instance[$name] = Loader::factory($config['type'], '\\think\\db\\connector\\', $config);
}
return self::$instance[$name];
@ -2149,60 +2146,4 @@ abstract class Connection
}
}
/**
* 数据库连接参数解析
* @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;
}
}

View File

@ -14,6 +14,7 @@ namespace think\db;
use PDO;
use think\Collection;
use think\Container;
use think\Db;
use think\db\exception\BindParamException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
@ -28,12 +29,6 @@ use think\Paginator;
class Query
{
/**
* 数据库连接对象列表
* @var array
*/
protected static $connections = [];
/**
* 当前数据库连接对象
* @var Connection
@ -122,7 +117,7 @@ class Query
public function __construct(Connection $connection = null)
{
if (is_null($connection)) {
$this->connection = Connection::instance();
$this->connection = Db::connect();
} else {
$this->connection = $connection;
}
@ -302,29 +297,6 @@ class Query
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
@ -653,7 +625,7 @@ class Query
if (!empty($this->options['fetch_sql'])) {
return $result;
} elseif ($force) {
$result += 0;
$result = (float) $result;
}
return $result;

View File

@ -39,9 +39,9 @@ use think\Facade;
* @method \think\Route alias(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册别名路由
* @method \think\Route setMethodPrefix(mixed $method, string $prefix = '') static 设置不同请求类型下面的方法前缀
* @method \think\Route rest(string $name, array $resource = []) static rest方法定义和修改
* @method \think\RuleItem miss(string $route, string $method = '*', array $option = []) static 注册未匹配路由规则后的处理
* @method \think\RuleItem auto(string $route) static 注册一个自动解析的URL路由
* @method \think\Dispatch check(string $url, string $depr = '/', bool $must = false, bool $completeMatch = false) static 检测URL路由
* @method \think\Route\RuleItem miss(string $route, string $method = '*', array $option = []) static 注册未匹配路由规则后的处理
* @method \think\Route\RuleItem auto(string $route) static 注册一个自动解析的URL路由
* @method \think\Route\Dispatch check(string $url, string $depr = '/', bool $must = false, bool $completeMatch = false) static 检测URL路由
*/
class Route extends Facade
{

View File

@ -19,7 +19,7 @@ use think\Facade;
* @method void init(array $config = []) static session初始化
* @method bool has(string $name,string $prefix = null) static 判断session数据
* @method mixed prefix(string $prefix = '') static 设置或者获取session作用域前缀
* @method mixed get(string $name,string $prefix = null) static session获取
* @method mixed get(string $name = '',string $prefix = null) static session获取
* @method mixed pull(string $name,string $prefix = null) static session获取并删除
* @method void push(string $key, mixed $value) static 添加数据到一个session数组
* @method void set(string $name, mixed $value , string $prefix = null) static 设置session数据

View File

@ -448,7 +448,7 @@ trait Attribute
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->readTransform($value, $this->type[$name]);
} elseif (in_array($name, [$this->createTime, $this->updateTime])) {
} elseif ($this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [
'datetime',
'date',

View File

@ -11,7 +11,6 @@
namespace think\response;
use think\Container;
use think\Response;
class Jsonp extends Response
@ -36,7 +35,7 @@ class Jsonp extends Response
{
try {
// 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的故使用Request来获取<xiaobo.sun@qq.com>]
$var_jsonp_handler = Container::get('request')->param($this->options['var_jsonp_handler'], "");
$var_jsonp_handler = $this->app['request']->param($this->options['var_jsonp_handler'], "");
$handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler'];
$data = json_encode($data, $this->options['json_encode_param']);

View File

@ -11,7 +11,6 @@
namespace think\response;
use think\Container;
use think\Response;
class Jump extends Response
@ -27,10 +26,7 @@ class Jump extends Response
*/
protected function output($data)
{
$config = Container::get('config');
$data = Container::get('view')
->init($config->pull('template'))
->fetch($this->options['jump_template'], $data);
$data = $this->app['view']->fetch($this->options['jump_template'], $data);
return $data;
}
}

View File

@ -11,7 +11,6 @@
namespace think\response;
use think\Container;
use think\Response;
class Redirect extends Response
@ -51,7 +50,7 @@ class Redirect extends Response
*/
public function with($name, $value = null)
{
$session = Container::get('session');
$session = $this->app['session'];
if (is_array($name)) {
foreach ($name as $key => $val) {
@ -74,7 +73,7 @@ class Redirect extends Response
if (strpos($this->data, '://') || (0 === strpos($this->data, '/') && empty($this->params))) {
return $this->data;
} else {
return Container::get('url')->build($this->data, $this->params);
return $this->app['url']->build($this->data, $this->params);
}
}
@ -92,7 +91,7 @@ class Redirect extends Response
*/
public function remember()
{
Container::get('session')->set('redirect_url', Container::get('request')->url());
$this->app['session']->set('redirect_url', $this->app['request']->url());
return $this;
}
@ -104,7 +103,7 @@ class Redirect extends Response
*/
public function restore()
{
$session = Container::get('session');
$session = $this->app['session'];
if ($session->has('redirect_url')) {
$this->data = $session->get('redirect_url');

View File

@ -11,7 +11,6 @@
namespace think\response;
use think\Container;
use think\Response;
class View extends Response
@ -31,9 +30,7 @@ class View extends Response
protected function output($data)
{
// 渲染模板输出
$config = Container::get('config');
return Container::get('view')
->init($config->pull('template'))
return $this->app['view']
->filter($this->filter)
->fetch($data, $this->vars);
}
@ -91,9 +88,7 @@ class View extends Response
*/
public function exists($name)
{
return Container::get('view')
->init(Container::get('config')->pull('template'))
->exists($name);
return $this->app['view']->exists($name);
}
}

View File

@ -40,11 +40,10 @@ class AliasRule extends Domain
* @access public
* @param Request $request 请求对象
* @param string $url 访问地址
* @param string $depr 路径分隔符
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
public function check($request, $url, $depr = '/', $completeMatch = false)
public function check($request, $url, $completeMatch = false)
{
if ($dispatch = $this->checkCrossDomain($request)) {
// 允许跨域
@ -82,13 +81,13 @@ class AliasRule extends Domain
if (0 === strpos($this->route, '\\')) {
// 路由到类
return $this->bindToClass($bind, substr($this->route, 1));
return $this->bindToClass($request, $bind, substr($this->route, 1));
} elseif (0 === strpos($this->route, '@')) {
// 路由到控制器类
return $this->bindToController($bind, substr($this->route, 1));
return $this->bindToController($request, $bind, substr($this->route, 1));
} else {
// 路由到模块/控制器
return $this->bindToModule($bind, $this->route);
return $this->bindToModule($request, $bind, $this->route);
}
}

View File

@ -12,32 +12,291 @@
namespace think\route;
use think\Container;
use think\exception\ValidateException;
use think\Request;
use think\Response;
use think\route\dispatch\ResponseDispatch;
abstract class Dispatch
{
// 应用实例
/**
* 应用对象
* @var App
*/
protected $app;
// 调度信息
/**
* 请求对象
* @var Request
*/
protected $request;
/**
* 路由规则
* @var RuleItem
*/
protected $router;
/**
* 调度信息
* @var mixed
*/
protected $dispatch;
// 调度参数
/**
* 调度参数
* @var array
*/
protected $param;
// 状态码
/**
* 状态码
* @var string
*/
protected $code;
// 是否进行大小写转换
/**
* 是否进行大小写转换
* @var bool
*/
protected $convert;
public function __construct($dispatch, $param = [], $code = null)
public function __construct(Request $request, RuleItem $router, $dispatch, $param = [], $code = null)
{
$this->request = $request;
$this->router = $router;
$this->app = Container::get('app');
$this->dispatch = $dispatch;
$this->param = $param;
$this->code = $code;
if (isset($param['convert'])) {
$this->convert = $param['convert'];
}
// 设置请求的路由信息
$this->request->routeInfo([
'rule' => $this->router->getRule(),
'route' => $this->router->getRoute(),
'option' => $this->router->getOption(),
'var' => $this->router->getVars(),
]);
// 执行路由后置操作
$this->routeAfter();
// 初始化
$this->init();
}
protected function init()
{}
/**
* 检查路由后置操作
* @access protected
* @return void
*/
protected function routeAfter()
{
// 记录匹配的路由信息
$option = $this->router->getOption();
$matches = $this->router->getVars();
// 添加中间件
if (!empty($option['middleware'])) {
$this->app['middleware']->import($option['middleware']);
}
// 绑定模型数据
if (!empty($option['model'])) {
$this->createBindModel($option['model'], $matches);
}
// 指定Header数据
if (!empty($option['header'])) {
$header = $option['header'];
$this->app['hook']->add('response_send', function ($response) use ($header) {
$response->header($header);
});
}
// 指定Response响应数据
if (!empty($option['response'])) {
$this->app['hook']->add('response_send', $option['response']);
}
// 开启请求缓存
if (isset($option['cache']) && $this->request->isGet()) {
$this->parseRequestCache($option['cache']);
}
if (!empty($option['append'])) {
$this->request->route($option['append']);
}
}
/**
* 执行路由调度
* @access public
* @return mixed
*/
public function run()
{
$option = $this->router->getOption();
// 检测路由after行为
if (!empty($option['after'])) {
$dispatch = $this->checkAfter($option['after']);
if ($dispatch instanceof Response) {
return $dispatch;
}
}
// 数据自动验证
if (isset($option['validate'])) {
$this->autoValidate($option['validate'], $request);
}
return $this->exec();
}
/**
* 检查路由后置行为
* @access protected
* @param mixed $after 后置行为
* @return mixed
*/
protected function checkAfter($after)
{
$this->app['log']->notice('路由后置行为建议使用中间件替代!');
$hook = $this->app['hook'];
$result = null;
foreach ((array) $after as $behavior) {
$result = $hook->exec($behavior);
if (!is_null($result)) {
break;
}
}
// 路由规则重定向
if ($result instanceof Response) {
return new ResponseDispatch($result, $this->router);
}
return false;
}
/**
* 验证数据
* @access protected
* @param array $option
* @param \think\Request $request
* @return void
* @throws ValidateException
*/
protected function autoValidate($option, $request)
{
list($validate, $scene, $message, $batch) = $option;
if (is_array($validate)) {
// 指定验证规则
$v = $this->app->validate();
$v->rule($validate);
} else {
// 调用验证器
$v = $this->app->validate($validate);
if (!empty($scene)) {
$v->scene($scene);
}
}
if (!empty($message)) {
$v->message($message);
}
// 批量验证
if ($batch) {
$v->batch(true);
}
if (!$v->check($request->param())) {
throw new ValidateException($v->getError());
}
}
/**
* 处理路由请求缓存
* @access protected
* @param Request $request 请求对象
* @param string|array $cache 路由缓存
* @return void
*/
protected function parseRequestCache($cache)
{
if (is_array($cache)) {
list($key, $expire, $tag) = array_pad($cache, 3, null);
} else {
$key = str_replace('|', '/', $this->request->url());
$expire = $cache;
$tag = null;
}
$this->request->cache($key, $expire, $tag);
}
/**
* 路由绑定模型实例
* @access protected
* @param array|\Clousre $bindModel 绑定模型
* @param array $matches 路由变量
* @return void
*/
protected function createBindModel($bindModel, $matches)
{
foreach ($bindModel as $key => $val) {
if ($val instanceof \Closure) {
$result = $this->app->invokeFunction($val, $matches);
} else {
$fields = explode('&', $key);
if (is_array($val)) {
list($model, $exception) = $val;
} else {
$model = $val;
$exception = true;
}
$where = [];
$match = true;
foreach ($fields as $field) {
if (!isset($matches[$field])) {
$match = false;
break;
} else {
$where[] = [$field, '=', $matches[$field]];
}
}
if ($match) {
$query = strpos($model, '\\') ? $model::where($where) : $this->app->model($model)->where($where);
$result = $query->failException($exception)->find();
}
}
if (!empty($result)) {
// 注入容器
$this->app->instance(get_class($result), $result);
}
}
}
public function convert($convert)
{
$this->convert = $convert;
@ -55,6 +314,6 @@ abstract class Dispatch
return $this->param;
}
abstract public function run();
abstract public function exec();
}

View File

@ -45,21 +45,20 @@ class Domain extends RuleGroup
* @access public
* @param Request $request 请求对象
* @param string $url 访问地址
* @param string $depr 路径分隔符
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
public function check($request, $url, $depr = '/', $completeMatch = false)
public function check($request, $url, $completeMatch = false)
{
// 检测别名路由
$result = $this->checkRouteAlias($request, $url, $depr);
$result = $this->checkRouteAlias($request, $url);
if (false !== $result) {
return $result;
}
// 检测URL绑定
$result = $this->checkUrlBind($url, $depr);
$result = $this->checkUrlBind($request, $url);
if (!empty($this->option['append'])) {
$request->route($this->option['append']);
@ -76,7 +75,7 @@ class Domain extends RuleGroup
unset($this->option['middleware']);
}
return parent::check($request, $url, $depr, $completeMatch);
return parent::check($request, $url, $completeMatch);
}
/**
@ -98,26 +97,25 @@ class Domain extends RuleGroup
* @access private
* @param Request $request
* @param string $url URL地址
* @param string $depr URL分隔符
* @return Dispatch|false
*/
private function checkRouteAlias($request, $url, $depr)
private function checkRouteAlias($request, $url)
{
$alias = strpos($url, '|') ? strstr($url, '|', true) : $url;
$item = $this->router->getAlias($alias);
return $item ? $item->check($request, $url, $depr) : false;
return $item ? $item->check($request, $url) : false;
}
/**
* 检测URL绑定
* @access private
* @param Request $request
* @param string $url URL地址
* @param string $depr URL分隔符
* @return Dispatch|false
*/
private function checkUrlBind($url, $depr = '/')
private function checkUrlBind($request, $url)
{
if (!empty($this->bind)) {
$bind = $this->bind;
@ -137,7 +135,7 @@ class Domain extends RuleGroup
];
if (isset($bindTo[$type])) {
return $this->{$bindTo[$type]}($url, $bind, $depr);
return $this->{$bindTo[$type]}($request, $url, $bind);
}
}
@ -156,78 +154,82 @@ class Domain extends RuleGroup
/**
* 绑定到类
* @access protected
* @param Request $request
* @param string $url URL地址
* @param string $class 类名(带命名空间)
* @return CallbackDispatch
*/
protected function bindToClass($url, $class)
protected function bindToClass($request, $url, $class)
{
$array = explode('|', $url, 2);
$action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action');
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
if (!empty($array[1])) {
$this->parseUrlParams($array[1]);
$this->parseUrlParams($request, $array[1]);
}
return new CallbackDispatch([$class, $action]);
return new CallbackDispatch($request, $this->router, [$class, $action]);
}
/**
* 绑定到命名空间
* @access protected
* @param Request $request
* @param string $url URL地址
* @param string $namespace 命名空间
* @return CallbackDispatch
*/
protected function bindToNamespace($url, $namespace)
protected function bindToNamespace($request, $url, $namespace)
{
$array = explode('|', $url, 3);
$class = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_controller');
$method = !empty($array[1]) ? $array[1] : Container::get('config')->get('default_action');
$class = !empty($array[0]) ? $array[0] : $this->router->config('default_controller');
$method = !empty($array[1]) ? $array[1] : $this->router->config('default_action');
if (!empty($array[2])) {
$this->parseUrlParams($array[2]);
$this->parseUrlParams($request, $array[2]);
}
return new CallbackDispatch([$namespace . '\\' . Loader::parseName($class, 1), $method]);
return new CallbackDispatch($request, $this->router, [$namespace . '\\' . Loader::parseName($class, 1), $method]);
}
/**
* 绑定到控制器类
* @access protected
* @param Request $request
* @param string $url URL地址
* @param string $controller 控制器名 (支持带模块名 index/user
* @return ControllerDispatch
*/
protected function bindToController($url, $controller)
protected function bindToController($request, $url, $controller)
{
$array = explode('|', $url, 2);
$action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action');
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
if (!empty($array[1])) {
$this->parseUrlParams($array[1]);
$this->parseUrlParams($request, $array[1]);
}
return new ControllerDispatch($controller . '/' . $action);
return new ControllerDispatch($request, $this->router, $controller . '/' . $action);
}
/**
* 绑定到模块/控制器
* @access protected
* @param Request $request
* @param string $url URL地址
* @param string $controller 控制器类名(带命名空间)
* @return ModuleDispatch
*/
protected function bindToModule($url, $controller)
protected function bindToModule($request, $url, $controller)
{
$array = explode('|', $url, 2);
$action = !empty($array[0]) ? $array[0] : Container::get('config')->get('default_action');
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
if (!empty($array[1])) {
$this->parseUrlParams($array[1]);
$this->parseUrlParams($request, $array[1]);
}
return new ModuleDispatch($controller . '/' . $action);
return new ModuleDispatch($request, $this->router, $controller . '/' . $action);
}
}

View File

@ -12,7 +12,6 @@
namespace think\route;
use think\Container;
use think\exception\ValidateException;
use think\Request;
use think\Response;
use think\route\dispatch\Callback as CallbackDispatch;
@ -122,6 +121,27 @@ abstract class Rule
return isset($this->pattern[$name]) ? $this->pattern[$name] : null;
}
/**
* 获取路由参数
* @access public
* @param string $name 变量名
* @return mixed
*/
public function getConfig($name = '')
{
return $this->router->config($name);
}
/**
* 获取路由对象
* @access public
* @return Route
*/
public function getRouter()
{
return $this->router;
}
/**
* 获取路由参数定义
* @access public
@ -485,7 +505,7 @@ abstract class Rule
$this->option['header'] = $header;
if ($request->method(true) == 'OPTIONS') {
return new ResponseDispatch(Response::create()->code(204)->header($header));
return new ResponseDispatch($request, $this, Response::create()->code(204)->header($header));
}
}
}
@ -528,73 +548,6 @@ abstract class Rule
return $this->option;
}
/**
* 路由绑定模型实例
* @access protected
* @param array|\Clousre $bindModel 绑定模型
* @param array $matches 路由变量
* @return void
*/
protected function createBindModel($bindModel, $matches)
{
foreach ($bindModel as $key => $val) {
if ($val instanceof \Closure) {
$result = Container::getInstance()->invokeFunction($val, $matches);
} else {
$fields = explode('&', $key);
if (is_array($val)) {
list($model, $exception) = $val;
} else {
$model = $val;
$exception = true;
}
$where = [];
$match = true;
foreach ($fields as $field) {
if (!isset($matches[$field])) {
$match = false;
break;
} else {
$where[] = [$field, '=', $matches[$field]];
}
}
if ($match) {
$query = strpos($model, '\\') ? $model::where($where) : Container::get('app')->model($model)->where($where);
$result = $query->failException($exception)->find();
}
}
if (!empty($result)) {
// 注入容器
Container::getInstance()->instance(get_class($result), $result);
}
}
}
/**
* 处理路由请求缓存
* @access protected
* @param Request $request 请求对象
* @param string|array $cache 路由缓存
* @return void
*/
protected function parseRequestCache($request, $cache)
{
if (is_array($cache)) {
list($key, $expire, $tag) = array_pad($cache, 3, null);
} else {
$key = str_replace('|', '/', $request->url());
$expire = $cache;
$tag = null;
}
$request->cache($key, $expire, $tag);
}
/**
* 解析匹配到的规则路由
* @access public
@ -624,107 +577,19 @@ abstract class Rule
}
}
$this->afterMatchRule($request, $option, $matches);
// 解析额外参数
$count = substr_count($rule, '/');
$url = array_slice(explode('|', $url), $count + 1);
$this->parseUrlParams(implode('|', $url), $matches);
$this->parseUrlParams($request, implode('|', $url), $matches);
// 记录匹配的路由信息
$request->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]);
// 检测路由after行为
if (!empty($option['after'])) {
$dispatch = $this->checkAfter($option['after']);
if (false !== $dispatch) {
return $dispatch;
}
}
// 数据自动验证
if (isset($option['validate'])) {
$this->autoValidate($option['validate'], $request);
}
$this->route = $route;
$this->vars = $matches;
$this->option = $option;
// 发起路由调度
return $this->dispatch($request, $route, $option);
}
protected function afterMatchRule($request, $option = [], $matches = [])
{
// 添加中间件
if (!empty($option['middleware'])) {
Container::get('middleware')->import($option['middleware']);
}
// 绑定模型数据
if (!empty($option['model'])) {
$this->createBindModel($option['model'], $matches);
}
// 指定Header数据
if (!empty($option['header'])) {
$header = $option['header'];
Container::get('hook')->add('response_send', function ($response) use ($header) {
$response->header($header);
});
}
// 指定Response响应数据
if (!empty($option['response'])) {
Container::get('hook')->add('response_send', $option['response']);
}
// 开启请求缓存
if (isset($option['cache']) && $request->isGet()) {
$this->parseRequestCache($request, $option['cache']);
}
if (!empty($option['append'])) {
$request->route($option['append']);
}
}
/**
* 验证数据
* @access protected
* @param array $option
* @param \think\Request $request
* @return void
* @throws ValidateException
*/
protected function autoValidate($option, $request)
{
list($validate, $scene, $message, $batch) = $option;
if (is_array($validate)) {
// 指定验证规则
$v = Container::get('app')->validate();
$v->rule($validate);
} else {
// 调用验证器
$v = Container::get('app')->validate($validate);
if (!empty($scene)) {
$v->scene($scene);
}
}
if (!empty($message)) {
$v->message($message);
}
// 批量验证
if ($batch) {
$v->batch(true);
}
if (!$v->check($request->param())) {
throw new ValidateException($v->getError());
}
}
/**
* 检查路由前置行为
* @access protected
@ -744,38 +609,6 @@ abstract class Rule
}
}
/**
* 检查路由后置行为
* @access protected
* @param mixed $after 后置行为
* @return mixed
*/
protected function checkAfter($after)
{
Container::get('log')->notice('路由后置行为建议使用中间件替代!');
$hook = Container::get('hook');
$result = null;
foreach ((array) $after as $behavior) {
$result = $hook->exec($behavior);
if (!is_null($result)) {
break;
}
}
// 路由规则重定向
if ($result instanceof Response) {
return new ResponseDispatch($result);
} elseif ($result instanceof Dispatch) {
return $result;
}
return false;
}
/**
* 发起路由调度
* @access protected
@ -788,17 +621,17 @@ abstract class Rule
{
if ($route instanceof \Closure) {
// 执行闭包
$result = new CallbackDispatch($route);
$result = new CallbackDispatch($request, $this, $route);
} elseif ($route instanceof Response) {
$result = new ResponseDispatch($route);
$result = new ResponseDispatch($request, $this, $route);
} elseif (isset($option['view']) && false !== $option['view']) {
$result = new ViewDispatch($route, is_array($option['view']) ? $option['view'] : []);
$result = new ViewDispatch($request, $this, $route, is_array($option['view']) ? $option['view'] : []);
} elseif (!empty($option['redirect']) || 0 === strpos($route, '/') || strpos($route, '://')) {
// 路由到重定向地址
$result = new RedirectDispatch($route, [], isset($option['status']) ? $option['status'] : 301);
$result = new RedirectDispatch($request, $this, $route, [], isset($option['status']) ? $option['status'] : 301);
} elseif (false !== strpos($route, '\\')) {
// 路由到方法
$result = $this->dispatchMethod($route);
$result = $this->dispatchMethod($request, $route);
} elseif (0 === strpos($route, '@')) {
// 路由到控制器
$result = $this->dispatchController($request, substr($route, 1));
@ -813,17 +646,18 @@ abstract class Rule
/**
* 解析URL地址为 模块/控制器/操作
* @access protected
* @param Request $request Request对象
* @param string $route 路由地址
* @return CallbackDispatch
*/
protected function dispatchMethod($route)
protected function dispatchMethod($request, $route)
{
list($path, $var) = $this->parseUrlPath($route);
$route = str_replace('/', '@', implode('/', $path));
$method = strpos($route, '@') ? explode('@', $route) : $route;
return new CallbackDispatch($method, $var);
return new CallbackDispatch($request, $this, $method, $var);
}
/**
@ -837,13 +671,11 @@ abstract class Rule
{
list($route, $var) = $this->parseUrlPath($route);
$result = new ControllerDispatch(implode('/', $route), $var);
$result = new ControllerDispatch($request, $this, implode('/', $route), $var);
$request->action(array_pop($route));
$app = Container::get('app');
$request->controller($route ? array_pop($route) : $app->config('default_controller'));
$request->module($route ? array_pop($route) : $app->config('default_module'));
$app->setModulePath($app->getAppPath() . ($app->config('app_multi_module') ? $request->module() . DIRECTORY_SEPARATOR : ''));
$request->controller($route ? array_pop($route) : $this->getConfig('default_controller'));
$request->module($route ? array_pop($route) : $this->getConfig('default_module'));
return $result;
}
@ -859,13 +691,12 @@ abstract class Rule
{
list($path, $var) = $this->parseUrlPath($route);
$config = Container::get('config');
$action = array_pop($path);
$controller = !empty($path) ? array_pop($path) : null;
$module = $config->get('app_multi_module') && !empty($path) ? array_pop($path) : null;
$module = $this->getConfig('app_multi_module') && !empty($path) ? array_pop($path) : null;
$method = $request->method();
if ($config->get('use_action_prefix') && $this->router->getMethodPrefix($method)) {
if ($this->getConfig('use_action_prefix') && $this->router->getMethodPrefix($method)) {
$prefix = $this->router->getMethodPrefix($method);
// 操作方法前缀支持
$action = 0 !== strpos($action, $prefix) ? $prefix . $action : $action;
@ -875,7 +706,7 @@ abstract class Rule
$request->route($var);
// 路由到模块/控制器/操作
return new ModuleDispatch([$module, $controller, $action], [], false);
return new ModuleDispatch($request, $this, [$module, $controller, $action], ['convert' => false]);
}
/**
@ -927,14 +758,15 @@ abstract class Rule
/**
* 解析URL地址中的参数Request对象
* @access protected
* @param Request $request
* @param string $rule 路由规则
* @param array $var 变量
* @return void
*/
protected function parseUrlParams($url, &$var = [])
protected function parseUrlParams($request, $url, &$var = [])
{
if ($url) {
if (Container::get('config')->get('url_param_type')) {
if ($this->getConfig('url_param_type')) {
$var += explode('|', $url);
} else {
preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) {
@ -944,7 +776,7 @@ abstract class Rule
}
// 设置当前请求的参数
Container::get('request')->route($var);
$request->route($var);
}
/**
@ -1053,7 +885,7 @@ abstract class Rule
$nameRule = substr($nameRule, 1, -1);
}
} else {
$nameRule = '\w+';
$nameRule = $this->getConfig('default_route_pattern');
}
return '(' . $prefix . '(?<' . $name . $suffix . '>' . $nameRule . '))' . $optional;

View File

@ -111,11 +111,10 @@ class RuleGroup extends Rule
* @access public
* @param Request $request 请求对象
* @param string $url 访问地址
* @param string $depr 路径分隔符
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
public function check($request, $url, $depr = '/', $completeMatch = false)
public function check($request, $url, $completeMatch = false)
{
if ($dispatch = $this->checkCrossDomain($request)) {
// 跨域OPTIONS请求
@ -132,7 +131,7 @@ class RuleGroup extends Rule
$this->buildResourceRule($this->resource, $this->option);
} elseif ($this->rule) {
if ($this->rule instanceof Response) {
return new ResponseDispatch($this->rule);
return new ResponseDispatch($request, $this->router, $this->rule);
}
$this->parseGroupRule($this->rule);
@ -159,7 +158,7 @@ class RuleGroup extends Rule
if (!empty($this->option['merge_rule_regex'])) {
// 合并路由正则规则进行路由匹配检查
$result = $this->checkMergeRuleRegex($request, $rules, $url, $depr, $completeMatch);
$result = $this->checkMergeRuleRegex($request, $rules, $url, $completeMatch);
if (false !== $result) {
return $result;
@ -168,7 +167,7 @@ class RuleGroup extends Rule
// 检查分组路由
foreach ($rules as $key => $item) {
$result = $item->check($request, $url, $depr, $completeMatch);
$result = $item->check($request, $url, $completeMatch);
if (false !== $result) {
return $result;
@ -177,10 +176,12 @@ class RuleGroup extends Rule
if ($this->auto) {
// 自动解析URL地址
$result = new UrlDispatch($this->auto . '/' . $url, ['depr' => $depr, 'auto_search' => false]);
$ruleItem = new RuleItem($this->router, $this, '', '', $this->auto . '/' . $url);
$result = new UrlDispatch($request, $ruleItem, $this->auto . '/' . $url, ['auto_search' => false]);
} elseif ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) {
// 未匹配所有路由的路由规则处理
$result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption());
$ruleItem = new RuleItem($this->router, $this, '', '', $this->miss->getRoute());
$result = $ruleItem->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption());
} else {
$result = false;
}
@ -268,13 +269,13 @@ class RuleGroup extends Rule
* @param Request $request 请求对象
* @param array $rules 路由规则
* @param string $url 访问地址
* @param string $depr 路径分隔符
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
protected function checkMergeRuleRegex($request, &$rules, $url, $depr, $completeMatch)
protected function checkMergeRuleRegex($request, &$rules, $url, $completeMatch)
{
$url = $depr . str_replace('|', $depr, $url);
$depr = $this->router->config('pathinfo_depr');
$url = $depr . str_replace('|', $depr, $url);
foreach ($rules as $key => $item) {
if ($item instanceof RuleItem) {

View File

@ -35,6 +35,12 @@ class RuleItem extends Rule
*/
protected $method;
/**
* 路由变量
* @var array
*/
protected $vars = [];
/**
* 架构函数
* @access public
@ -125,6 +131,16 @@ class RuleItem extends Rule
return strtolower($this->method);
}
/**
* 获取当前路由的变量
* @access public
* @return array
*/
public function getVars()
{
return $this->vars;
}
/**
* 检查后缀
* @access public
@ -185,11 +201,10 @@ class RuleItem extends Rule
* @param Request $request 请求对象
* @param string $url 访问地址
* @param array $match 匹配路由变量
* @param string $depr 路径分隔符
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
public function checkRule($request, $url, $match = null, $depr = '/', $completeMatch = false)
public function checkRule($request, $url, $match = null, $completeMatch = false)
{
if ($dispatch = $this->checkCrossDomain($request)) {
// 允许跨域
@ -212,7 +227,7 @@ class RuleItem extends Rule
$url = $this->urlSuffixCheck($request, $url, $option);
if (is_null($match)) {
$match = $this->match($url, $option, $depr, $completeMatch);
$match = $this->match($url, $option, $completeMatch);
}
if (false !== $match) {
@ -231,9 +246,9 @@ class RuleItem extends Rule
* @param bool $completeMatch 路由是否完全匹配
* @return Dispatch|false
*/
public function check($request, $url, $depr = '/', $completeMatch = false)
public function check($request, $url, $completeMatch = false)
{
return $this->checkRule($request, $url, null, $depr, $completeMatch);
return $this->checkRule($request, $url, null, $completeMatch);
}
/**
@ -265,11 +280,10 @@ class RuleItem extends Rule
* @access private
* @param string $url URL地址
* @param array $option 路由参数
* @param string $depr URL分隔符全局
* @param bool $completeMatch 路由是否完全匹配
* @return array|false
*/
private function match($url, $option, $depr, $completeMatch)
private function match($url, $option, $completeMatch)
{
if (isset($option['complete_match'])) {
$completeMatch = $option['complete_match'];
@ -283,6 +297,7 @@ class RuleItem extends Rule
}
$var = [];
$depr = $this->router->config('pathinfo_depr');
$url = $depr . str_replace('|', $depr, $url);
$rule = $depr . str_replace('/', $depr, $this->rule);

View File

@ -11,17 +11,16 @@
namespace think\route\dispatch;
use think\Container;
use think\route\Dispatch;
class Callback extends Dispatch
{
public function run()
public function exec()
{
// 执行回调方法
$vars = array_merge($this->app['request']->param(), $this->param);
$vars = array_merge($this->request->param(), $this->param);
return Container::getInstance()->invoke($this->dispatch, $vars);
return $this->app->invoke($this->dispatch, $vars);
}
}

View File

@ -15,15 +15,15 @@ use think\route\Dispatch;
class Controller extends Dispatch
{
public function run()
public function exec()
{
// 执行控制器的操作方法
$vars = array_merge($this->app['request']->param(), $this->param);
$vars = array_merge($this->request->param(), $this->param);
return $this->app->action(
$this->dispatch, $vars,
$this->app->config('app.url_controller_layer'),
$this->app->config('app.controller_suffix')
$this->router->getConfig('url_controller_layer'),
$this->router->getConfig('controller_suffix')
);
}

View File

@ -12,7 +12,6 @@
namespace think\route\dispatch;
use ReflectionMethod;
use think\Container;
use think\exception\ClassNotFoundException;
use think\exception\HttpException;
use think\Loader;
@ -23,15 +22,6 @@ class Module extends Dispatch
protected $controller;
protected $actionName;
public function __construct($dispatch, $param = [], $convert = null)
{
$this->app = Container::get('app');
$this->dispatch = $dispatch;
$this->param = $param;
$this->convert = $convert;
$this->init();
}
protected function init()
{
$result = $this->dispatch;
@ -40,10 +30,10 @@ class Module extends Dispatch
$result = explode('/', $result);
}
if ($this->app->config('app.app_multi_module')) {
if ($this->router->getConfig('app_multi_module')) {
// 多模块部署
$module = strip_tags(strtolower($result[0] ?: $this->app->config('app.default_module')));
$bind = $this->app['route']->getBind();
$module = strip_tags(strtolower($result[0] ?: $this->router->getConfig('default_module')));
$bind = $this->router->getRouter()->getBind();
$available = false;
if ($bind && preg_match('/^[a-z]/is', $bind)) {
@ -53,48 +43,38 @@ class Module extends Dispatch
$module = $bindModule;
}
$available = true;
} elseif (!in_array($module, $this->app->config('app.deny_module_list')) && is_dir($this->app->getAppPath() . $module)) {
} elseif (!in_array($module, $this->router->getConfig('deny_module_list')) && is_dir($this->app->getAppPath() . $module)) {
$available = true;
} elseif ($this->app->config('app.empty_module')) {
$module = $this->app->config('app.empty_module');
} elseif ($this->router->getConfig('empty_module')) {
$module = $this->router->getConfig('empty_module');
$available = true;
}
// 模块初始化
if ($module && $available) {
// 初始化模块
$this->app['request']->module($module);
$this->request->module($module);
$this->app->init($module);
// 加载当前模块语言包
$this->app['lang']->load($this->app->getAppPath() . $module . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $this->app['request']->langset() . '.php');
// 模块请求缓存检查
$this->app['request']->cache(
$this->app->config('app.request_cache'),
$this->app->config('app.request_cache_expire'),
$this->app->config('app.request_cache_except')
);
} else {
throw new HttpException(404, 'module not exists:' . $module);
}
}
// 是否自动转换控制器和操作名
$convert = is_bool($this->convert) ? $this->convert : $this->app->config('app.url_convert');
$convert = is_bool($this->convert) ? $this->convert : $this->router->getConfig('url_convert');
// 获取控制器名
$controller = strip_tags($result[1] ?: $this->app->config('app.default_controller'));
$controller = strip_tags($result[1] ?: $this->router->getConfig('default_controller'));
$this->controller = $convert ? strtolower($controller) : $controller;
// 获取操作名
$this->actionName = strip_tags($result[2] ?: $this->app->config('app.default_action'));
$this->actionName = strip_tags($result[2] ?: $this->router->getConfig('default_action'));
// 设置当前请求的控制器、操作
$this->app['request']->controller(Loader::parseName($this->controller, 1))->action($this->actionName);
$this->request->controller(Loader::parseName($this->controller, 1))->action($this->actionName);
}
public function run()
public function exec()
{
// 监听module_init
$this->app['hook']->listen('module_init');
@ -102,15 +82,15 @@ class Module extends Dispatch
// 实例化控制器
try {
$instance = $this->app->controller($this->controller,
$this->app->config('app.url_controller_layer'),
$this->app->config('app.controller_suffix'),
$this->app->config('app.empty_controller'));
$this->router->getConfig('url_controller_layer'),
$this->router->getConfig('controller_suffix'),
$this->router->getConfig('empty_controller'));
} catch (ClassNotFoundException $e) {
throw new HttpException(404, 'controller not exists:' . $e->getClass());
}
// 获取当前操作名
$action = $this->actionName . $this->app->config('app.action_suffix');
$action = $this->actionName . $this->router->getConfig('action_suffix');
if (is_callable([$instance, $action])) {
// 执行操作方法
@ -119,14 +99,14 @@ class Module extends Dispatch
// 严格获取当前操作方法名
$reflect = new ReflectionMethod($instance, $action);
$methodName = $reflect->getName();
$suffix = $this->app->config('app.action_suffix');
$suffix = $this->router->getConfig('action_suffix');
$actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;
$this->app['request']->action($actionName);
$this->request->action($actionName);
// 自动获取请求变量
$vars = $this->app->config('app.url_param_type')
? $this->app['request']->route()
: $this->app['request']->param();
$vars = $this->router->getConfig('url_param_type')
? $this->request->route()
: $this->request->param();
} elseif (is_callable([$instance, '_empty'])) {
// 空操作
$call = [$instance, '_empty'];
@ -138,6 +118,7 @@ class Module extends Dispatch
}
$this->app['hook']->listen('action_begin', $call);
return Container::getInstance()->invokeReflectMethod($instance, $reflect, $vars);
return $this->app->invokeReflectMethod($instance, $reflect, $vars);
}
}

View File

@ -16,7 +16,7 @@ use think\route\Dispatch;
class Redirect extends Dispatch
{
public function run()
public function exec()
{
return Response::create($this->dispatch, 'redirect')->code($this->code);
}

View File

@ -15,7 +15,7 @@ use think\route\Dispatch;
class Response extends Dispatch
{
public function run()
public function exec()
{
return $this->dispatch;
}

View File

@ -20,28 +20,27 @@ class Url extends Dispatch
protected function init()
{
// 解析默认的URL规则
$url = str_replace($this->param['depr'], '|', $this->dispatch);
$result = $this->parseUrl($url);
$depr = $this->router->getConfig('pathinfo_depr');
$result = $this->parseUrl($this->dispatch, $depr);
$this->dispatch = new Module($result);
$this->dispatch = new Module($this->request, $this->router, $result);
}
public function run()
public function exec()
{
return $this->dispatch->run();
return $this->dispatch->exec();
}
/**
* 解析URL地址
* @access protected
* @param string $url URL
* @param string $url URL
* @param string $depr 分隔符
* @return array
*/
protected function parseUrl($url)
protected function parseUrl($url, $depr)
{
$router = $this->app['route'];
$bind = $router->getBind();
$depr = $this->param['depr'];
$bind = $this->router->getRouter()->getBind();
if (!empty($bind) && preg_match('/^[a-z]/is', $bind)) {
$bind = str_replace('/', $depr, $bind);
@ -55,7 +54,7 @@ class Url extends Dispatch
}
// 解析模块
$module = $this->app->config('app_multi_module') ? array_shift($path) : null;
$module = $this->router->getConfig('app_multi_module') ? array_shift($path) : null;
if ($this->param['auto_search']) {
$controller = $this->autoFindController($module, $path);
} else {
@ -68,7 +67,7 @@ class Url extends Dispatch
// 解析额外参数
if ($path) {
if ($this->app['config']->get('url_param_type')) {
if ($this->router->getConfig('url_param_type')) {
$var += $path;
} else {
preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) {
@ -77,14 +76,14 @@ class Url extends Dispatch
}
}
$panDomain = $this->app['request']->panDomain();
$panDomain = $this->request->panDomain();
if ($panDomain && $key = array_search('*', $var)) {
// 泛域名赋值
$var[$key] = $panDomain;
}
// 设置当前请求的参数
$this->app['request']->route($var);
$this->request->route($var);
// 封装路由
$route = [$module, $controller, $action];
@ -116,9 +115,7 @@ class Url extends Dispatch
$name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);
}
$router = $this->app['route'];
if ($router->getName($name) || $router->getName($name2)) {
if ($this->router->getRouter()->getName($name) || $this->router->getRouter()->getName($name2)) {
return true;
}
@ -134,8 +131,8 @@ class Url extends Dispatch
*/
protected function autoFindController($module, &$path)
{
$dir = $this->app->getAppPath() . ($module ? $module . '/' : '') . $this->app->config('url_controller_layer');
$suffix = $this->app->getSuffix() || $this->app->config('controller_suffix') ? ucfirst($this->app->config('url_controller_layer')) : '';
$dir = $this->app->getAppPath() . ($module ? $module . '/' : '') . $this->router->getConfig('url_controller_layer');
$suffix = $this->app->getSuffix() || $this->router->getConfig('controller_suffix') ? ucfirst($this->router->getConfig('url_controller_layer')) : '';
$item = [];
$find = false;

View File

@ -16,10 +16,10 @@ use think\route\Dispatch;
class View extends Dispatch
{
public function run()
public function exec()
{
// 渲染模板输出
$vars = array_merge($this->app['request']->param(), $this->param);
$vars = array_merge($this->request->param(), $this->param);
return Response::create($this->dispatch, 'view')->assign($vars);
}

View File

@ -11,7 +11,7 @@
namespace think\view\driver;
use think\Container;
use think\App;
use think\exception\TemplateNotFoundException;
use think\Loader;
@ -32,10 +32,12 @@ class Php
];
protected $template;
protected $app;
protected $content;
public function __construct($config = [])
public function __construct(App $app, $config = [])
{
$this->app = $app;
$this->config = array_merge($this->config, (array) $config);
}
@ -77,7 +79,7 @@ class Php
$this->template = $template;
// 记录视图信息
Container::get('app')
$this->app
->log('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]');
extract($data, EXTR_OVERWRITE);
@ -108,10 +110,10 @@ class Php
private function parseTemplate($template)
{
if (empty($this->config['view_path'])) {
$this->config['view_path'] = Container::get('app')->getModulePath() . 'view' . DIRECTORY_SEPARATOR;
$this->config['view_path'] = $this->app->getModulePath() . 'view' . DIRECTORY_SEPARATOR;
}
$request = Container::get('request');
$request = $this->app['request'];
// 获取视图根目录
if (strpos($template, '@')) {
@ -124,7 +126,7 @@ class Php
$module = isset($module) ? $module : $request->module();
$path = $this->config['view_base'] . ($module ? $module . DIRECTORY_SEPARATOR : '');
} else {
$path = isset($module) ? Container::get('app')->getAppPath() . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR : $this->config['view_path'];
$path = isset($module) ? $this->app->getAppPath() . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR : $this->config['view_path'];
}
$depr = $this->config['view_depr'];

View File

@ -11,7 +11,7 @@
namespace think\view\driver;
use think\Container;
use think\App;
use think\exception\TemplateNotFoundException;
use think\Loader;
use think\Template;
@ -20,6 +20,8 @@ class Think
{
// 模板引擎实例
private $template;
private $app;
// 模板引擎参数
protected $config = [
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
@ -36,14 +38,16 @@ class Think
'tpl_cache' => true,
];
public function __construct($config = [])
public function __construct(App $app, $config = [])
{
$this->app = $app;
$this->config = array_merge($this->config, (array) $config);
if (empty($this->config['view_path'])) {
$this->config['view_path'] = Container::get('app')->getModulePath() . 'view' . DIRECTORY_SEPARATOR;
$this->config['view_path'] = $app->getModulePath() . 'view' . DIRECTORY_SEPARATOR;
}
$this->template = new Template($this->config);
$this->template = new Template($app, $this->config);
}
/**
@ -83,7 +87,7 @@ class Think
}
// 记录视图信息
Container::get('app')
$this->app
->log('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]');
$this->template->fetch($template, $data, $config);
@ -111,7 +115,7 @@ class Think
private function parseTemplate($template)
{
// 分析模板文件规则
$request = Container::get('request');
$request = $this->app['request'];
// 获取视图根目录
if (strpos($template, '@')) {
@ -124,7 +128,7 @@ class Think
$module = isset($module) ? $module : $request->module();
$path = $this->config['view_base'] . ($module ? $module . DIRECTORY_SEPARATOR : '');
} else {
$path = isset($module) ? Container::get('app')->getAppPath() . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR : $this->config['view_path'];
$path = isset($module) ? $this->app->getAppPath() . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR : $this->config['view_path'];
}
$depr = $this->config['view_depr'];

View File

@ -20,6 +20,12 @@ use think\response\Redirect;
trait Jump
{
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 操作成功跳转的快捷方法
* @access protected
@ -52,7 +58,7 @@ trait Jump
$type = 'jump';
}
$response = Response::create($result, $type)->header($header)->options(['jump_template' => Container::get('config')->get('dispatch_success_tmpl')]);
$response = Response::create($result, $type)->header($header)->options(['jump_template' => $this->app['config']->get('dispatch_success_tmpl')]);
throw new HttpResponseException($response);
}
@ -69,10 +75,11 @@ trait Jump
*/
protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
{
$type = $this->getResponseType();
if (is_null($url)) {
$url = Container::get('request')->isAjax() ? '' : 'javascript:history.back(-1);';
$url = $this->app['request']->isAjax() ? '' : 'javascript:history.back(-1);';
} elseif ('' !== $url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Container::get('url')->build($url);
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app['url']->build($url);
}
$result = [
@ -83,12 +90,11 @@ trait Jump
'wait' => $wait,
];
$type = $this->getResponseType();
if ('html' == strtolower($type)) {
$type = 'jump';
}
$response = Response::create($result, $type)->header($header)->options(['jump_template' => Container::get('config')->get('dispatch_error_tmpl')]);
$response = Response::create($result, $type)->header($header)->options(['jump_template' => $this->app['config']->get('dispatch_error_tmpl')]);
throw new HttpResponseException($response);
}
@ -148,8 +154,12 @@ trait Jump
*/
protected function getResponseType()
{
$isAjax = Container::get('request')->isAjax();
$config = Container::get('config');
if (!$this->app) {
$this->app = Container::get('app');
}
$isAjax = $this->app['request']->isAjax();
$config = $this->app['config'];
return $isAjax
? $config->get('default_ajax_return')

2
vendor/autoload.php vendored
View File

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

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitedd8bf4bf1f017c1edc90ff3c3c5de3c
class ComposerAutoloaderInit513ee155225f84554dcc21f55f596f8f
{
private static $loader;
@ -19,15 +19,15 @@ class ComposerAutoloaderInitedd8bf4bf1f017c1edc90ff3c3c5de3c
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitedd8bf4bf1f017c1edc90ff3c3c5de3c', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit513ee155225f84554dcc21f55f596f8f', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitedd8bf4bf1f017c1edc90ff3c3c5de3c', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit513ee155225f84554dcc21f55f596f8f', '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\ComposerStaticInitedd8bf4bf1f017c1edc90ff3c3c5de3c::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit513ee155225f84554dcc21f55f596f8f::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@ -48,19 +48,19 @@ class ComposerAutoloaderInitedd8bf4bf1f017c1edc90ff3c3c5de3c
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitedd8bf4bf1f017c1edc90ff3c3c5de3c::$files;
$includeFiles = Composer\Autoload\ComposerStaticInit513ee155225f84554dcc21f55f596f8f::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireedd8bf4bf1f017c1edc90ff3c3c5de3c($fileIdentifier, $file);
composerRequire513ee155225f84554dcc21f55f596f8f($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequireedd8bf4bf1f017c1edc90ff3c3c5de3c($fileIdentifier, $file)
function composerRequire513ee155225f84554dcc21f55f596f8f($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

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

View File

@ -178,17 +178,17 @@
},
{
"name": "topthink/framework",
"version": "v5.1.13",
"version_normalized": "5.1.13.0",
"version": "v5.1.14",
"version_normalized": "5.1.14.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "1cc81707dab128e360405aa4811a27b7a5403a78"
"reference": "1adc81f2d59cd99e69d38c058527cd759531e8a8"
},
"dist": {
"type": "zip",
"url": "https://files.phpcomposer.com/files/top-think/framework/1cc81707dab128e360405aa4811a27b7a5403a78.zip",
"reference": "1cc81707dab128e360405aa4811a27b7a5403a78",
"url": "https://files.phpcomposer.com/files/top-think/framework/1adc81f2d59cd99e69d38c058527cd759531e8a8.zip",
"reference": "1adc81f2d59cd99e69d38c058527cd759531e8a8",
"shasum": ""
},
"require": {
@ -204,7 +204,7 @@
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "2.*"
},
"time": "2018-05-11T07:50:00+00:00",
"time": "2018-05-19T04:16:33+00:00",
"type": "think-framework",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
@ -433,17 +433,17 @@
},
{
"name": "qiniu/php-sdk",
"version": "v7.2.5",
"version_normalized": "7.2.5.0",
"version": "v7.2.6",
"version_normalized": "7.2.6.0",
"source": {
"type": "git",
"url": "https://github.com/qiniu/php-sdk.git",
"reference": "0a6e6c75cbc0429fac69ba9aaadb1f5d6c676fb0"
"reference": "305ce1c1c0c71f794661fe45a96facf61ef96c5d"
},
"dist": {
"type": "zip",
"url": "https://files.phpcomposer.com/files/qiniu/php-sdk/0a6e6c75cbc0429fac69ba9aaadb1f5d6c676fb0.zip",
"reference": "0a6e6c75cbc0429fac69ba9aaadb1f5d6c676fb0",
"url": "https://files.phpcomposer.com/files/qiniu/php-sdk/305ce1c1c0c71f794661fe45a96facf61ef96c5d.zip",
"reference": "305ce1c1c0c71f794661fe45a96facf61ef96c5d",
"shasum": ""
},
"require": {
@ -453,7 +453,7 @@
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.3"
},
"time": "2018-05-10T09:26:30+00:00",
"time": "2018-05-18T04:37:29+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {

View File

@ -1,5 +1,8 @@
# Changelog
## 7.2.6 (2018-05-18)
* 修复rsrsf在不同机房默认的https域名
## 7.2.5 (2018-05-10)
* 修复表单上传中多余的参数checkCrc导致的fname错位问题

View File

@ -1,4 +1,4 @@
# Qiniu Resource Storage SDK for PHP
# Qiniu Cloud SDK for PHP
[![doxygen.io](http://doxygen.io/github.com/qiniu/php-sdk/?status.svg)](http://doxygen.io/github.com/qiniu/php-sdk/)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
[![Build Status](https://travis-ci.org/qiniu/php-sdk.svg)](https://travis-ci.org/qiniu/php-sdk)

View File

@ -44,8 +44,8 @@ final class Zone
$Zone_z0 = new Zone(
array("up.qiniup.com", 'up-jjh.qiniup.com', 'up-xs.qiniup.com'),
array('upload.qiniup.com', 'upload-jjh.qiniup.com', 'upload-xs.qiniup.com'),
'rs.qiniu.com',
'rsf.qiniu.com',
'rs.qbox.me',
'rsf.qbox.me',
'api.qiniu.com',
'iovip.qbox.me'
);
@ -58,8 +58,8 @@ final class Zone
$Zone_z1 = new Zone(
array('up-z1.qiniup.com'),
array('upload-z1.qiniup.com'),
"rs-z1.qiniu.com",
"rsf-z1.qiniu.com",
"rs-z1.qbox.me",
"rsf-z1.qbox.me",
"api-z1.qiniu.com",
"iovip-z1.qbox.me"
);
@ -73,8 +73,8 @@ final class Zone
$Zone_z2 = new Zone(
array('up-z2.qiniup.com', 'up-dg.qiniup.com', 'up-fs.qiniup.com'),
array('upload-z2.qiniup.com', 'upload-dg.qiniup.com', 'upload-fs.qiniup.com'),
"rs-z2.qiniu.com",
"rsf-z2.qiniu.com",
"rs-z2.qbox.me",
"rsf-z2.qbox.me",
"api-z2.qiniu.com",
"iovip-z2.qbox.me"
);
@ -88,8 +88,8 @@ final class Zone
$Zone_na0 = new Zone(
array('up-na0.qiniup.com'),
array('upload-na0.qiniup.com'),
"rs-na0.qiniu.com",
"rsf-na0.qiniu.com",
"rs-na0.qbox.me",
"rsf-na0.qbox.me",
"api-na0.qiniu.com",
"iovip-na0.qbox.me"
);
@ -103,8 +103,8 @@ final class Zone
$Zone_as0 = new Zone(
array('up-as0.qiniup.com'),
array('upload-as0.qiniup.com'),
"rs-as0.qiniu.com",
"rsf-as0.qiniu.com",
"rs-as0.qbox.me",
"rsf-as0.qbox.me",
"api-as0.qiniu.com",
"iovip-as0.qbox.me"
);
@ -145,24 +145,24 @@ final class Zone
//set specific hosts
if (strstr($zone->iovipHost, "z1") !== false) {
$zone->rsHost = "rs-z1.qiniu.com";
$zone->rsfHost = "rsf-z1.qiniu.com";
$zone->rsHost = "rs-z1.qbox.me";
$zone->rsfHost = "rsf-z1.qbox.me";
$zone->apiHost = "api-z1.qiniu.com";
} elseif (strstr($zone->iovipHost, "z2") !== false) {
$zone->rsHost = "rs-z2.qiniu.com";
$zone->rsfHost = "rsf-z2.qiniu.com";
$zone->rsHost = "rs-z2.qbox.me";
$zone->rsfHost = "rsf-z2.qbox.me";
$zone->apiHost = "api-z2.qiniu.com";
} elseif (strstr($zone->iovipHost, "na0") !== false) {
$zone->rsHost = "rs-na0.qiniu.com";
$zone->rsfHost = "rsf-na0.qiniu.com";
$zone->rsHost = "rs-na0.qbox.me";
$zone->rsfHost = "rsf-na0.qbox.me";
$zone->apiHost = "api-na0.qiniu.com";
} elseif (strstr($zone->iovipHost, "as0") !== false) {
$zone->rsHost = "rs-as0.qiniu.com";
$zone->rsfHost = "rsf-as0.qiniu.com";
$zone->rsHost = "rs-as0.qbox.me";
$zone->rsfHost = "rsf-as0.qbox.me";
$zone->apiHost = "api-as0.qiniu.com";
} else {
$zone->rsHost = "rs.qiniu.com";
$zone->rsfHost = "rsf.qiniu.com";
$zone->rsHost = "rs.qbox.me";
$zone->rsfHost = "rsf.qbox.me";
$zone->apiHost = "api.qiniu.com";
}