mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 12:42:48 +08:00
格式化 start、base、traits 和 App、Config、Error、Loader 代码的样式。其他代码的样式待处理。
This commit is contained in:
2
base.php
2
base.php
@@ -40,8 +40,10 @@ require CORE_PATH . 'Loader.php';
|
|||||||
// 加载环境变量配置文件
|
// 加载环境变量配置文件
|
||||||
if (is_file(ROOT_PATH . '.env')) {
|
if (is_file(ROOT_PATH . '.env')) {
|
||||||
$env = parse_ini_file(ROOT_PATH . '.env', true);
|
$env = parse_ini_file(ROOT_PATH . '.env', true);
|
||||||
|
|
||||||
foreach ($env as $key => $val) {
|
foreach ($env as $key => $val) {
|
||||||
$name = ENV_PREFIX . strtoupper($key);
|
$name = ENV_PREFIX . strtoupper($key);
|
||||||
|
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$item = $name . '_' . strtoupper($k);
|
$item = $name . '_' . strtoupper($k);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use think\exception\RouteNotFoundException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* App 应用管理
|
* App 应用管理
|
||||||
* @author liu21st <liu21st@gmail.com>
|
* @author liu21st <liu21st@gmail.com>
|
||||||
*/
|
*/
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
@@ -57,24 +57,32 @@ class App
|
|||||||
*/
|
*/
|
||||||
protected static $routeMust;
|
protected static $routeMust;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array 请求调度分发
|
||||||
|
*/
|
||||||
protected static $dispatch;
|
protected static $dispatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array 额外加载文件
|
||||||
|
*/
|
||||||
protected static $file = [];
|
protected static $file = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行应用程序
|
* 执行应用程序
|
||||||
* @access public
|
* @access public
|
||||||
* @param Request $request Request对象
|
* @param Request $request 请求对象
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function run(Request $request = null)
|
public static function run(Request $request = null)
|
||||||
{
|
{
|
||||||
is_null($request) && $request = Request::instance();
|
$request = is_null($request) ? Request::instance() : $request;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$config = self::initCommon();
|
$config = self::initCommon();
|
||||||
|
|
||||||
|
// 模块/控制器绑定
|
||||||
if (defined('BIND_MODULE')) {
|
if (defined('BIND_MODULE')) {
|
||||||
// 模块/控制器绑定
|
|
||||||
BIND_MODULE && Route::bind(BIND_MODULE);
|
BIND_MODULE && Route::bind(BIND_MODULE);
|
||||||
} elseif ($config['auto_bind_module']) {
|
} elseif ($config['auto_bind_module']) {
|
||||||
// 入口自动绑定
|
// 入口自动绑定
|
||||||
@@ -88,10 +96,8 @@ class App
|
|||||||
|
|
||||||
// 默认语言
|
// 默认语言
|
||||||
Lang::range($config['default_lang']);
|
Lang::range($config['default_lang']);
|
||||||
if ($config['lang_switch_on']) {
|
// 开启多语言机制 检测当前语言
|
||||||
// 开启多语言机制 检测当前语言
|
$config['lang_switch_on'] && Lang::detect();
|
||||||
Lang::detect();
|
|
||||||
}
|
|
||||||
$request->langset(Lang::range());
|
$request->langset(Lang::range());
|
||||||
|
|
||||||
// 加载系统语言包
|
// 加载系统语言包
|
||||||
@@ -102,10 +108,11 @@ class App
|
|||||||
|
|
||||||
// 获取应用调度信息
|
// 获取应用调度信息
|
||||||
$dispatch = self::$dispatch;
|
$dispatch = self::$dispatch;
|
||||||
|
// 未设置调度信息则进行 URL 路由检测
|
||||||
if (empty($dispatch)) {
|
if (empty($dispatch)) {
|
||||||
// 进行URL路由检测
|
|
||||||
$dispatch = self::routeCheck($request, $config);
|
$dispatch = self::routeCheck($request, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录当前调度信息
|
// 记录当前调度信息
|
||||||
$request->dispatch($dispatch);
|
$request->dispatch($dispatch);
|
||||||
|
|
||||||
@@ -116,10 +123,15 @@ class App
|
|||||||
Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
|
Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听app_begin
|
// 监听 app_begin
|
||||||
Hook::listen('app_begin', $dispatch);
|
Hook::listen('app_begin', $dispatch);
|
||||||
|
|
||||||
// 请求缓存检查
|
// 请求缓存检查
|
||||||
$request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);
|
$request->cache(
|
||||||
|
$config['request_cache'],
|
||||||
|
$config['request_cache_expire'],
|
||||||
|
$config['request_cache_except']
|
||||||
|
);
|
||||||
|
|
||||||
$data = self::exec($dispatch, $config);
|
$data = self::exec($dispatch, $config);
|
||||||
} catch (HttpResponseException $exception) {
|
} catch (HttpResponseException $exception) {
|
||||||
@@ -134,24 +146,144 @@ class App
|
|||||||
$response = $data;
|
$response = $data;
|
||||||
} elseif (!is_null($data)) {
|
} elseif (!is_null($data)) {
|
||||||
// 默认自动识别响应输出类型
|
// 默认自动识别响应输出类型
|
||||||
$isAjax = $request->isAjax();
|
$type = $request->isAjax() ?
|
||||||
$type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
|
Config::get('default_ajax_return') :
|
||||||
|
Config::get('default_return_type');
|
||||||
|
|
||||||
$response = Response::create($data, $type);
|
$response = Response::create($data, $type);
|
||||||
} else {
|
} else {
|
||||||
$response = Response::create();
|
$response = Response::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听app_end
|
// 监听 app_end
|
||||||
Hook::listen('app_end', $response);
|
Hook::listen('app_end', $response);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化应用,并返回配置信息
|
||||||
|
* @access public
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function initCommon()
|
||||||
|
{
|
||||||
|
if (empty(self::$init)) {
|
||||||
|
if (defined('APP_NAMESPACE')) self::$namespace = APP_NAMESPACE;
|
||||||
|
|
||||||
|
Loader::addNamespace(self::$namespace, APP_PATH);
|
||||||
|
|
||||||
|
// 初始化应用
|
||||||
|
$config = self::init();
|
||||||
|
self::$suffix = $config['class_suffix'];
|
||||||
|
|
||||||
|
// 应用调试模式
|
||||||
|
self::$debug = Env::get('app_debug', Config::get('app_debug'));
|
||||||
|
|
||||||
|
if (!self::$debug) {
|
||||||
|
ini_set('display_errors', 'Off');
|
||||||
|
} elseif (!IS_CLI) {
|
||||||
|
// 重新申请一块比较大的 buffer
|
||||||
|
if (ob_get_level() > 0) $output = ob_get_clean();
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
if (!empty($output)) echo $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($config['root_namespace'])) {
|
||||||
|
Loader::addNamespace($config['root_namespace']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载额外文件
|
||||||
|
if (!empty($config['extra_file_list'])) {
|
||||||
|
foreach ($config['extra_file_list'] as $file) {
|
||||||
|
$file = strpos($file, '.') ? $file : APP_PATH . $file . EXT;
|
||||||
|
if (is_file($file) && !isset(self::$file[$file])) {
|
||||||
|
include $file;
|
||||||
|
self::$file[$file] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置系统时区
|
||||||
|
date_default_timezone_set($config['default_timezone']);
|
||||||
|
|
||||||
|
// 监听 app_init
|
||||||
|
Hook::listen('app_init');
|
||||||
|
|
||||||
|
self::$init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Config::get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化应用或模块
|
||||||
|
* @access public
|
||||||
|
* @param string $module 模块名
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function init($module = '')
|
||||||
|
{
|
||||||
|
// 定位模块目录
|
||||||
|
$module = $module ? $module . DS : '';
|
||||||
|
|
||||||
|
// 加载初始化文件
|
||||||
|
if (is_file(APP_PATH . $module . 'init' . EXT)) {
|
||||||
|
include APP_PATH . $module . 'init' . EXT;
|
||||||
|
} elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) {
|
||||||
|
include RUNTIME_PATH . $module . 'init' . EXT;
|
||||||
|
} else {
|
||||||
|
// 加载模块配置
|
||||||
|
$config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT);
|
||||||
|
|
||||||
|
// 读取数据库配置文件
|
||||||
|
$filename = CONF_PATH . $module . 'database' . CONF_EXT;
|
||||||
|
Config::load($filename, 'database');
|
||||||
|
|
||||||
|
// 读取扩展配置文件
|
||||||
|
if (is_dir(CONF_PATH . $module . 'extra')) {
|
||||||
|
$dir = CONF_PATH . $module . 'extra';
|
||||||
|
$files = scandir($dir);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) {
|
||||||
|
$filename = $dir . DS . $file;
|
||||||
|
Config::load($filename, pathinfo($file, PATHINFO_FILENAME));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载应用状态配置
|
||||||
|
if ($config['app_status']) {
|
||||||
|
Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载行为扩展文件
|
||||||
|
if (is_file(CONF_PATH . $module . 'tags' . EXT)) {
|
||||||
|
Hook::import(include CONF_PATH . $module . 'tags' . EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载公共文件
|
||||||
|
$path = APP_PATH . $module;
|
||||||
|
if (is_file($path . 'common' . EXT)) {
|
||||||
|
include $path . 'common' . EXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载当前模块语言包
|
||||||
|
if ($module) {
|
||||||
|
Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Config::get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置当前请求的调度信息
|
* 设置当前请求的调度信息
|
||||||
* @access public
|
* @access public
|
||||||
* @param array|string $dispatch 调度信息
|
* @param array|string $dispatch 调度信息
|
||||||
* @param string $type 调度类型
|
* @param string $type 调度类型
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function dispatch($dispatch, $type = 'module')
|
public static function dispatch($dispatch, $type = 'module')
|
||||||
@@ -170,8 +302,10 @@ class App
|
|||||||
{
|
{
|
||||||
$reflect = new \ReflectionFunction($function);
|
$reflect = new \ReflectionFunction($function);
|
||||||
$args = self::bindParams($reflect, $vars);
|
$args = self::bindParams($reflect, $vars);
|
||||||
|
|
||||||
// 记录执行信息
|
// 记录执行信息
|
||||||
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
|
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
|
||||||
|
|
||||||
return $reflect->invokeArgs($args);
|
return $reflect->invokeArgs($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,28 +325,27 @@ class App
|
|||||||
// 静态方法
|
// 静态方法
|
||||||
$reflect = new \ReflectionMethod($method);
|
$reflect = new \ReflectionMethod($method);
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = self::bindParams($reflect, $vars);
|
$args = self::bindParams($reflect, $vars);
|
||||||
|
|
||||||
self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');
|
self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');
|
||||||
|
|
||||||
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
|
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用反射执行类的实例化 支持依赖注入
|
* 调用反射执行类的实例化 支持依赖注入
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $class 类名
|
* @param string $class 类名
|
||||||
* @param array $vars 变量
|
* @param array $vars 变量
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function invokeClass($class, $vars = [])
|
public static function invokeClass($class, $vars = [])
|
||||||
{
|
{
|
||||||
$reflect = new \ReflectionClass($class);
|
$reflect = new \ReflectionClass($class);
|
||||||
$constructor = $reflect->getConstructor();
|
$constructor = $reflect->getConstructor();
|
||||||
if ($constructor) {
|
$args = $constructor ? self::bindParams($constructor, $vars) : [];
|
||||||
$args = self::bindParams($constructor, $vars);
|
|
||||||
} else {
|
|
||||||
$args = [];
|
|
||||||
}
|
|
||||||
return $reflect->newInstanceArgs($args);
|
return $reflect->newInstanceArgs($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,52 +358,58 @@ class App
|
|||||||
*/
|
*/
|
||||||
private static function bindParams($reflect, $vars = [])
|
private static function bindParams($reflect, $vars = [])
|
||||||
{
|
{
|
||||||
|
// 自动获取请求变量
|
||||||
if (empty($vars)) {
|
if (empty($vars)) {
|
||||||
// 自动获取请求变量
|
$vars = Config::get('url_param_type') ?
|
||||||
if (Config::get('url_param_type')) {
|
Request::instance()->route() :
|
||||||
$vars = Request::instance()->route();
|
Request::instance()->param();
|
||||||
} else {
|
|
||||||
$vars = Request::instance()->param();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = [];
|
$args = [];
|
||||||
if ($reflect->getNumberOfParameters() > 0) {
|
if ($reflect->getNumberOfParameters() > 0) {
|
||||||
// 判断数组类型 数字数组时按顺序绑定参数
|
// 判断数组类型 数字数组时按顺序绑定参数
|
||||||
reset($vars);
|
reset($vars);
|
||||||
$type = key($vars) === 0 ? 1 : 0;
|
$type = key($vars) === 0 ? 1 : 0;
|
||||||
$params = $reflect->getParameters();
|
|
||||||
foreach ($params as $param) {
|
foreach ($reflect->getParameters() as $param) {
|
||||||
$args[] = self::getParamValue($param, $vars, $type);
|
$args[] = self::getParamValue($param, $vars, $type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取参数值
|
* 获取参数值
|
||||||
* @access private
|
* @access private
|
||||||
* @param \ReflectionParameter $param
|
* @param \ReflectionParameter $param 参数
|
||||||
* @param array $vars 变量
|
* @param array $vars 变量
|
||||||
* @param string $type
|
* @param string $type 类别
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static function getParamValue($param, &$vars, $type)
|
private static function getParamValue($param, &$vars, $type)
|
||||||
{
|
{
|
||||||
$name = $param->getName();
|
$name = $param->getName();
|
||||||
$class = $param->getClass();
|
$class = $param->getClass();
|
||||||
|
|
||||||
if ($class) {
|
if ($class) {
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
$bind = Request::instance()->$name;
|
$bind = Request::instance()->$name;
|
||||||
|
|
||||||
if ($bind instanceof $className) {
|
if ($bind instanceof $className) {
|
||||||
$result = $bind;
|
$result = $bind;
|
||||||
} else {
|
} else {
|
||||||
if (method_exists($className, 'invoke')) {
|
if (method_exists($className, 'invoke')) {
|
||||||
$method = new \ReflectionMethod($className, 'invoke');
|
$method = new \ReflectionMethod($className, 'invoke');
|
||||||
|
|
||||||
if ($method->isPublic() && $method->isStatic()) {
|
if ($method->isPublic() && $method->isStatic()) {
|
||||||
return $className::invoke(Request::instance());
|
return $className::invoke(Request::instance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$result = method_exists($className, 'instance') ? $className::instance() : new $className;
|
|
||||||
|
$result = method_exists($className, 'instance') ?
|
||||||
|
$className::instance() :
|
||||||
|
new $className;
|
||||||
}
|
}
|
||||||
} elseif (1 == $type && !empty($vars)) {
|
} elseif (1 == $type && !empty($vars)) {
|
||||||
$result = array_shift($vars);
|
$result = array_shift($vars);
|
||||||
@@ -281,65 +420,83 @@ class App
|
|||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('method param miss:' . $name);
|
throw new \InvalidArgumentException('method param miss:' . $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行调用分发
|
||||||
|
* @access protected
|
||||||
|
* @param array $dispatch 调用信息
|
||||||
|
* @param array $config 配置信息
|
||||||
|
* @return Response|mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
protected static function exec($dispatch, $config)
|
protected static function exec($dispatch, $config)
|
||||||
{
|
{
|
||||||
switch ($dispatch['type']) {
|
switch ($dispatch['type']) {
|
||||||
case 'redirect':
|
case 'redirect': // 重定向跳转
|
||||||
// 执行重定向跳转
|
$data = Response::create($dispatch['url'], 'redirect')
|
||||||
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
|
->code($dispatch['status']);
|
||||||
break;
|
break;
|
||||||
case 'module':
|
case 'module': // 模块/控制器/操作
|
||||||
// 模块/控制器/操作
|
$data = self::module(
|
||||||
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
|
$dispatch['module'],
|
||||||
|
$config,
|
||||||
|
isset($dispatch['convert']) ? $dispatch['convert'] : null
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'controller':
|
case 'controller': // 执行控制器操作
|
||||||
// 执行控制器操作
|
|
||||||
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
$data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);
|
$data = Loader::action(
|
||||||
|
$dispatch['controller'],
|
||||||
|
$vars,
|
||||||
|
$config['url_controller_layer'],
|
||||||
|
$config['controller_suffix']
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'method':
|
case 'method': // 回调方法
|
||||||
// 执行回调方法
|
|
||||||
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
$vars = array_merge(Request::instance()->param(), $dispatch['var']);
|
||||||
$data = self::invokeMethod($dispatch['method'], $vars);
|
$data = self::invokeMethod($dispatch['method'], $vars);
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function': // 闭包
|
||||||
// 执行闭包
|
|
||||||
$data = self::invokeFunction($dispatch['function']);
|
$data = self::invokeFunction($dispatch['function']);
|
||||||
break;
|
break;
|
||||||
case 'response':
|
case 'response': // Response 实例
|
||||||
$data = $dispatch['response'];
|
$data = $dispatch['response'];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException('dispatch type not support');
|
throw new \InvalidArgumentException('dispatch type not support');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行模块
|
* 执行模块
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $result 模块/控制器/操作
|
* @param array $result 模块/控制器/操作
|
||||||
* @param array $config 配置参数
|
* @param array $config 配置参数
|
||||||
* @param bool $convert 是否自动转换控制器和操作名
|
* @param bool $convert 是否自动转换控制器和操作名
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
* @throws HttpException
|
||||||
*/
|
*/
|
||||||
public static function module($result, $config, $convert = null)
|
public static function module($result, $config, $convert = null)
|
||||||
{
|
{
|
||||||
if (is_string($result)) {
|
if (is_string($result)) $result = explode('/', $result);
|
||||||
$result = explode('/', $result);
|
|
||||||
}
|
|
||||||
$request = Request::instance();
|
$request = Request::instance();
|
||||||
|
|
||||||
if ($config['app_multi_module']) {
|
if ($config['app_multi_module']) {
|
||||||
// 多模块部署
|
// 多模块部署
|
||||||
$module = strip_tags(strtolower($result[0] ?: $config['default_module']));
|
$module = strip_tags(strtolower($result[0] ?: $config['default_module']));
|
||||||
$bind = Route::getBind('module');
|
$bind = Route::getBind('module');
|
||||||
$available = false;
|
$available = false;
|
||||||
|
|
||||||
if ($bind) {
|
if ($bind) {
|
||||||
// 绑定模块
|
// 绑定模块
|
||||||
list($bindModule) = explode('/', $bind);
|
list($bindModule) = explode('/', $bind);
|
||||||
|
|
||||||
if (empty($result[0])) {
|
if (empty($result[0])) {
|
||||||
$module = $bindModule;
|
$module = $bindModule;
|
||||||
$available = true;
|
$available = true;
|
||||||
@@ -355,8 +512,13 @@ class App
|
|||||||
// 初始化模块
|
// 初始化模块
|
||||||
$request->module($module);
|
$request->module($module);
|
||||||
$config = self::init($module);
|
$config = self::init($module);
|
||||||
|
|
||||||
// 模块请求缓存检查
|
// 模块请求缓存检查
|
||||||
$request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);
|
$request->cache(
|
||||||
|
$config['request_cache'],
|
||||||
|
$config['request_cache_expire'],
|
||||||
|
$config['request_cache_except']
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new HttpException(404, 'module not exists:' . $module);
|
throw new HttpException(404, 'module not exists:' . $module);
|
||||||
}
|
}
|
||||||
@@ -365,11 +527,13 @@ class App
|
|||||||
$module = '';
|
$module = '';
|
||||||
$request->module($module);
|
$request->module($module);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前模块路径
|
// 当前模块路径
|
||||||
App::$modulePath = APP_PATH . ($module ? $module . DS : '');
|
App::$modulePath = APP_PATH . ($module ? $module . DS : '');
|
||||||
|
|
||||||
// 是否自动转换控制器和操作名
|
// 是否自动转换控制器和操作名
|
||||||
$convert = is_bool($convert) ? $convert : $config['url_convert'];
|
$convert = is_bool($convert) ? $convert : $config['url_convert'];
|
||||||
|
|
||||||
// 获取控制器名
|
// 获取控制器名
|
||||||
$controller = strip_tags($result[1] ?: $config['default_controller']);
|
$controller = strip_tags($result[1] ?: $config['default_controller']);
|
||||||
$controller = $convert ? strtolower($controller) : $controller;
|
$controller = $convert ? strtolower($controller) : $controller;
|
||||||
@@ -385,7 +549,12 @@ class App
|
|||||||
Hook::listen('module_init', $request);
|
Hook::listen('module_init', $request);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
|
$instance = Loader::controller(
|
||||||
|
$controller,
|
||||||
|
$config['url_controller_layer'],
|
||||||
|
$config['controller_suffix'],
|
||||||
|
$config['empty_controller']
|
||||||
|
);
|
||||||
} catch (ClassNotFoundException $e) {
|
} catch (ClassNotFoundException $e) {
|
||||||
throw new HttpException(404, 'controller not exists:' . $e->getClass());
|
throw new HttpException(404, 'controller not exists:' . $e->getClass());
|
||||||
}
|
}
|
||||||
@@ -411,125 +580,11 @@ class App
|
|||||||
return self::invokeMethod($call, $vars);
|
return self::invokeMethod($call, $vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化应用
|
|
||||||
*/
|
|
||||||
public static function initCommon()
|
|
||||||
{
|
|
||||||
if (empty(self::$init)) {
|
|
||||||
if (defined('APP_NAMESPACE')) {
|
|
||||||
self::$namespace = APP_NAMESPACE;
|
|
||||||
}
|
|
||||||
Loader::addNamespace(self::$namespace, APP_PATH);
|
|
||||||
|
|
||||||
// 初始化应用
|
|
||||||
$config = self::init();
|
|
||||||
self::$suffix = $config['class_suffix'];
|
|
||||||
|
|
||||||
// 应用调试模式
|
|
||||||
self::$debug = Env::get('app_debug', Config::get('app_debug'));
|
|
||||||
if (!self::$debug) {
|
|
||||||
ini_set('display_errors', 'Off');
|
|
||||||
} elseif (!IS_CLI) {
|
|
||||||
//重新申请一块比较大的buffer
|
|
||||||
if (ob_get_level() > 0) {
|
|
||||||
$output = ob_get_clean();
|
|
||||||
}
|
|
||||||
ob_start();
|
|
||||||
if (!empty($output)) {
|
|
||||||
echo $output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($config['root_namespace'])) {
|
|
||||||
Loader::addNamespace($config['root_namespace']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载额外文件
|
|
||||||
if (!empty($config['extra_file_list'])) {
|
|
||||||
foreach ($config['extra_file_list'] as $file) {
|
|
||||||
$file = strpos($file, '.') ? $file : APP_PATH . $file . EXT;
|
|
||||||
if (is_file($file) && !isset(self::$file[$file])) {
|
|
||||||
include $file;
|
|
||||||
self::$file[$file] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置系统时区
|
|
||||||
date_default_timezone_set($config['default_timezone']);
|
|
||||||
|
|
||||||
// 监听app_init
|
|
||||||
Hook::listen('app_init');
|
|
||||||
|
|
||||||
self::$init = true;
|
|
||||||
}
|
|
||||||
return Config::get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化应用或模块
|
|
||||||
* @access public
|
|
||||||
* @param string $module 模块名
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private static function init($module = '')
|
|
||||||
{
|
|
||||||
// 定位模块目录
|
|
||||||
$module = $module ? $module . DS : '';
|
|
||||||
|
|
||||||
// 加载初始化文件
|
|
||||||
if (is_file(APP_PATH . $module . 'init' . EXT)) {
|
|
||||||
include APP_PATH . $module . 'init' . EXT;
|
|
||||||
} elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) {
|
|
||||||
include RUNTIME_PATH . $module . 'init' . EXT;
|
|
||||||
} else {
|
|
||||||
$path = APP_PATH . $module;
|
|
||||||
// 加载模块配置
|
|
||||||
$config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT);
|
|
||||||
// 读取数据库配置文件
|
|
||||||
$filename = CONF_PATH . $module . 'database' . CONF_EXT;
|
|
||||||
Config::load($filename, 'database');
|
|
||||||
// 读取扩展配置文件
|
|
||||||
if (is_dir(CONF_PATH . $module . 'extra')) {
|
|
||||||
$dir = CONF_PATH . $module . 'extra';
|
|
||||||
$files = scandir($dir);
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) {
|
|
||||||
$filename = $dir . DS . $file;
|
|
||||||
Config::load($filename, pathinfo($file, PATHINFO_FILENAME));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载应用状态配置
|
|
||||||
if ($config['app_status']) {
|
|
||||||
$config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载行为扩展文件
|
|
||||||
if (is_file(CONF_PATH . $module . 'tags' . EXT)) {
|
|
||||||
Hook::import(include CONF_PATH . $module . 'tags' . EXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载公共文件
|
|
||||||
if (is_file($path . 'common' . EXT)) {
|
|
||||||
include $path . 'common' . EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载当前模块语言包
|
|
||||||
if ($module) {
|
|
||||||
Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Config::get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL路由检测(根据PATH_INFO)
|
* URL路由检测(根据PATH_INFO)
|
||||||
* @access public
|
* @access public
|
||||||
* @param \think\Request $request
|
* @param \think\Request $request 请求实例
|
||||||
* @param array $config
|
* @param array $config 配置信息
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \think\Exception
|
* @throws \think\Exception
|
||||||
*/
|
*/
|
||||||
@@ -538,6 +593,7 @@ class App
|
|||||||
$path = $request->path();
|
$path = $request->path();
|
||||||
$depr = $config['pathinfo_depr'];
|
$depr = $config['pathinfo_depr'];
|
||||||
$result = false;
|
$result = false;
|
||||||
|
|
||||||
// 路由检测
|
// 路由检测
|
||||||
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
|
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
|
||||||
if ($check) {
|
if ($check) {
|
||||||
@@ -545,34 +601,33 @@ class App
|
|||||||
if (is_file(RUNTIME_PATH . 'route.php')) {
|
if (is_file(RUNTIME_PATH . 'route.php')) {
|
||||||
// 读取路由缓存
|
// 读取路由缓存
|
||||||
$rules = include RUNTIME_PATH . 'route.php';
|
$rules = include RUNTIME_PATH . 'route.php';
|
||||||
if (is_array($rules)) {
|
is_array($rules) && Route::rules($rules);
|
||||||
Route::rules($rules);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$files = $config['route_config_file'];
|
$files = $config['route_config_file'];
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (is_file(CONF_PATH . $file . CONF_EXT)) {
|
if (is_file(CONF_PATH . $file . CONF_EXT)) {
|
||||||
// 导入路由配置
|
// 导入路由配置
|
||||||
$rules = include CONF_PATH . $file . CONF_EXT;
|
$rules = include CONF_PATH . $file . CONF_EXT;
|
||||||
if (is_array($rules)) {
|
is_array($rules) && Route::import($rules);
|
||||||
Route::import($rules);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路由检测(根据路由定义返回不同的URL调度)
|
// 路由检测(根据路由定义返回不同的URL调度)
|
||||||
$result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
|
$result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
|
||||||
$must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];
|
$must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];
|
||||||
|
|
||||||
if ($must && false === $result) {
|
if ($must && false === $result) {
|
||||||
// 路由无效
|
// 路由无效
|
||||||
throw new RouteNotFoundException();
|
throw new RouteNotFoundException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
|
||||||
if (false === $result) {
|
if (false === $result) {
|
||||||
// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
|
|
||||||
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
|
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,70 +13,84 @@ namespace think;
|
|||||||
|
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
// 配置参数
|
/**
|
||||||
|
* @var array 配置参数
|
||||||
|
*/
|
||||||
private static $config = [];
|
private static $config = [];
|
||||||
// 参数作用域
|
|
||||||
|
/**
|
||||||
|
* @var string 参数作用域
|
||||||
|
*/
|
||||||
private static $range = '_sys_';
|
private static $range = '_sys_';
|
||||||
|
|
||||||
// 设定配置参数的作用域
|
/**
|
||||||
|
* 设定配置参数的作用域
|
||||||
|
* @param string $range 作用域
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public static function range($range)
|
public static function range($range)
|
||||||
{
|
{
|
||||||
self::$range = $range;
|
self::$range = $range;
|
||||||
if (!isset(self::$config[$range])) {
|
|
||||||
self::$config[$range] = [];
|
if (!isset(self::$config[$range])) self::$config[$range] = [];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析配置文件或内容
|
* 解析配置文件或内容
|
||||||
* @param string $config 配置文件路径或内容
|
* @param string $config 配置文件路径或内容
|
||||||
* @param string $type 配置解析类型
|
* @param string $type 配置解析类型
|
||||||
* @param string $name 配置名(如设置即表示二级配置)
|
* @param string $name 配置名(如设置即表示二级配置)
|
||||||
* @param string $range 作用域
|
* @param string $range 作用域
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function parse($config, $type = '', $name = '', $range = '')
|
public static function parse($config, $type = '', $name = '', $range = '')
|
||||||
{
|
{
|
||||||
$range = $range ?: self::$range;
|
$range = $range ?: self::$range;
|
||||||
if (empty($type)) {
|
|
||||||
$type = pathinfo($config, PATHINFO_EXTENSION);
|
if (empty($type)) $type = pathinfo($config, PATHINFO_EXTENSION);
|
||||||
}
|
|
||||||
$class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type);
|
$class = false !== strpos($type, '\\') ?
|
||||||
|
$type :
|
||||||
|
'\\think\\config\\driver\\' . ucwords($type);
|
||||||
|
|
||||||
return self::set((new $class())->parse($config), $name, $range);
|
return self::set((new $class())->parse($config), $name, $range);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载配置文件(PHP格式)
|
* 加载配置文件(PHP格式)
|
||||||
* @param string $file 配置文件名
|
* @param string $file 配置文件名
|
||||||
* @param string $name 配置名(如设置即表示二级配置)
|
* @param string $name 配置名(如设置即表示二级配置)
|
||||||
* @param string $range 作用域
|
* @param string $range 作用域
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function load($file, $name = '', $range = '')
|
public static function load($file, $name = '', $range = '')
|
||||||
{
|
{
|
||||||
$range = $range ?: self::$range;
|
$range = $range ?: self::$range;
|
||||||
if (!isset(self::$config[$range])) {
|
|
||||||
self::$config[$range] = [];
|
if (!isset(self::$config[$range])) self::$config[$range] = [];
|
||||||
}
|
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
$type = pathinfo($file, PATHINFO_EXTENSION);
|
$type = pathinfo($file, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
if ('php' == $type) {
|
if ('php' == $type) {
|
||||||
return self::set(include $file, $name, $range);
|
return self::set(include $file, $name, $range);
|
||||||
} elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
|
|
||||||
return self::set(yaml_parse_file($file), $name, $range);
|
|
||||||
} else {
|
|
||||||
return self::parse($file, $type, $name, $range);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return self::$config[$range];
|
if ('yaml' == $type && function_exists('yaml_parse_file')) {
|
||||||
|
return self::set(yaml_parse_file($file), $name, $range);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::parse($file, $type, $name, $range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self::$config[$range];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测配置是否存在
|
* 检测配置是否存在
|
||||||
* @param string $name 配置参数名(支持二级配置 .号分割)
|
* @param string $name 配置参数名(支持二级配置 . 号分割)
|
||||||
* @param string $range 作用域
|
* @param string $range 作用域
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function has($name, $range = '')
|
public static function has($name, $range = '')
|
||||||
@@ -85,90 +99,105 @@ class Config
|
|||||||
|
|
||||||
if (!strpos($name, '.')) {
|
if (!strpos($name, '.')) {
|
||||||
return isset(self::$config[$range][strtolower($name)]);
|
return isset(self::$config[$range][strtolower($name)]);
|
||||||
} else {
|
|
||||||
// 二维数组设置和获取支持
|
|
||||||
$name = explode('.', $name, 2);
|
|
||||||
return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 二维数组设置和获取支持
|
||||||
|
$name = explode('.', $name, 2);
|
||||||
|
return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取配置参数 为空则获取所有配置
|
* 获取配置参数 为空则获取所有配置
|
||||||
* @param string $name 配置参数名(支持二级配置 .号分割)
|
* @param string $name 配置参数名(支持二级配置 . 号分割)
|
||||||
* @param string $range 作用域
|
* @param string $range 作用域
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function get($name = null, $range = '')
|
public static function get($name = null, $range = '')
|
||||||
{
|
{
|
||||||
$range = $range ?: self::$range;
|
$range = $range ?: self::$range;
|
||||||
|
|
||||||
// 无参数时获取所有
|
// 无参数时获取所有
|
||||||
if (empty($name) && isset(self::$config[$range])) {
|
if (empty($name) && isset(self::$config[$range])) {
|
||||||
return self::$config[$range];
|
return self::$config[$range];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 非二级配置时直接返回
|
||||||
if (!strpos($name, '.')) {
|
if (!strpos($name, '.')) {
|
||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;
|
return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;
|
||||||
} else {
|
|
||||||
// 二维数组设置和获取支持
|
|
||||||
$name = explode('.', $name, 2);
|
|
||||||
$name[0] = strtolower($name[0]);
|
|
||||||
|
|
||||||
if (!isset(self::$config[$range][$name[0]])) {
|
|
||||||
// 动态载入额外配置
|
|
||||||
$module = Request::instance()->module();
|
|
||||||
$file = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT;
|
|
||||||
|
|
||||||
is_file($file) && self::load($file, $name[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 二维数组设置和获取支持
|
||||||
|
$name = explode('.', $name, 2);
|
||||||
|
$name[0] = strtolower($name[0]);
|
||||||
|
|
||||||
|
if (!isset(self::$config[$range][$name[0]])) {
|
||||||
|
// 动态载入额外配置
|
||||||
|
$module = Request::instance()->module();
|
||||||
|
$file = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT;
|
||||||
|
|
||||||
|
is_file($file) && self::load($file, $name[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset(self::$config[$range][$name[0]][$name[1]]) ?
|
||||||
|
self::$config[$range][$name[0]][$name[1]] :
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置配置参数 name为数组则为批量设置
|
* 设置配置参数 name 为数组则为批量设置
|
||||||
* @param string|array $name 配置参数名(支持二级配置 .号分割)
|
* @param string|array $name 配置参数名(支持二级配置 . 号分割)
|
||||||
* @param mixed $value 配置值
|
* @param mixed $value 配置值
|
||||||
* @param string $range 作用域
|
* @param string $range 作用域
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function set($name, $value = null, $range = '')
|
public static function set($name, $value = null, $range = '')
|
||||||
{
|
{
|
||||||
$range = $range ?: self::$range;
|
$range = $range ?: self::$range;
|
||||||
if (!isset(self::$config[$range])) {
|
|
||||||
self::$config[$range] = [];
|
if (!isset(self::$config[$range])) self::$config[$range] = [];
|
||||||
}
|
|
||||||
|
// 字符串则表示单个配置设置
|
||||||
if (is_string($name)) {
|
if (is_string($name)) {
|
||||||
if (!strpos($name, '.')) {
|
if (!strpos($name, '.')) {
|
||||||
self::$config[$range][strtolower($name)] = $value;
|
self::$config[$range][strtolower($name)] = $value;
|
||||||
} else {
|
} else {
|
||||||
// 二维数组设置和获取支持
|
// 二维数组
|
||||||
$name = explode('.', $name, 2);
|
$name = explode('.', $name, 2);
|
||||||
self::$config[$range][strtolower($name[0])][$name[1]] = $value;
|
self::$config[$range][strtolower($name[0])][$name[1]] = $value;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} elseif (is_array($name)) {
|
return $value;
|
||||||
// 批量设置
|
}
|
||||||
|
|
||||||
|
// 数组则表示批量设置
|
||||||
|
if (is_array($name)) {
|
||||||
if (!empty($value)) {
|
if (!empty($value)) {
|
||||||
self::$config[$range][$value] = isset(self::$config[$range][$value]) ?
|
self::$config[$range][$value] = isset(self::$config[$range][$value]) ?
|
||||||
array_merge(self::$config[$range][$value], $name) : $name;
|
array_merge(self::$config[$range][$value], $name) :
|
||||||
|
$name;
|
||||||
|
|
||||||
return self::$config[$range][$value];
|
return self::$config[$range][$value];
|
||||||
} else {
|
|
||||||
return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 为空直接返回 已有配置
|
return self::$config[$range] = array_merge(
|
||||||
return self::$config[$range];
|
self::$config[$range], array_change_key_case($name)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为空直接返回已有配置
|
||||||
|
return self::$config[$range];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置配置参数
|
* 重置配置参数
|
||||||
|
* @param string $range 作用域
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function reset($range = '')
|
public static function reset($range = '')
|
||||||
{
|
{
|
||||||
$range = $range ?: self::$range;
|
$range = $range ?: self::$range;
|
||||||
|
|
||||||
if (true === $range) {
|
if (true === $range) {
|
||||||
self::$config = [];
|
self::$config = [];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,53 +31,55 @@ class Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception Handler
|
* 异常处理
|
||||||
* @param \Exception|\Throwable $e
|
* @param \Exception|\Throwable $e 异常
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function appException($e)
|
public static function appException($e)
|
||||||
{
|
{
|
||||||
if (!$e instanceof \Exception) {
|
if (!$e instanceof \Exception) $e = new ThrowableError($e);
|
||||||
$e = new ThrowableError($e);
|
|
||||||
}
|
$handler = self::getExceptionHandler();
|
||||||
|
$handler->report($e);
|
||||||
|
|
||||||
self::getExceptionHandler()->report($e);
|
|
||||||
if (IS_CLI) {
|
if (IS_CLI) {
|
||||||
self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
|
$handler->renderForConsole(new ConsoleOutput, $e);
|
||||||
} else {
|
} else {
|
||||||
self::getExceptionHandler()->render($e)->send();
|
$handler->render($e)->send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error Handler
|
* 错误处理
|
||||||
* @param integer $errno 错误编号
|
* @param integer $errno 错误编号
|
||||||
* @param integer $errstr 详细错误信息
|
* @param integer $errstr 详细错误信息
|
||||||
* @param string $errfile 出错的文件
|
* @param string $errfile 出错的文件
|
||||||
* @param integer $errline 出错行号
|
* @param integer $errline 出错行号
|
||||||
* @param array $errcontext
|
* @param array $errcontext 出错上下文
|
||||||
|
* @return void
|
||||||
* @throws ErrorException
|
* @throws ErrorException
|
||||||
*/
|
*/
|
||||||
public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
|
public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
|
||||||
{
|
{
|
||||||
$exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext);
|
$exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext);
|
||||||
if (error_reporting() & $errno) {
|
|
||||||
// 将错误信息托管至 think\exception\ErrorException
|
// 符合异常处理的则将错误信息托管至 think\exception\ErrorException
|
||||||
throw $exception;
|
if (error_reporting() & $errno) throw $exception;
|
||||||
} else {
|
|
||||||
self::getExceptionHandler()->report($exception);
|
self::getExceptionHandler()->report($exception);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown Handler
|
* 异常中止处理
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function appShutdown()
|
public static function appShutdown()
|
||||||
{
|
{
|
||||||
|
// 将错误信息托管至 think\ErrorException
|
||||||
if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
|
if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
|
||||||
// 将错误信息托管至think\ErrorException
|
self::appException(new ErrorException(
|
||||||
$exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']);
|
$error['type'], $error['message'], $error['file'], $error['line']
|
||||||
|
));
|
||||||
self::appException($exception);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 写入日志
|
// 写入日志
|
||||||
@@ -86,8 +88,7 @@ class Error
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 确定错误类型是否致命
|
* 确定错误类型是否致命
|
||||||
*
|
* @param int $type
|
||||||
* @param int $type
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected static function isFatal($type)
|
protected static function isFatal($type)
|
||||||
@@ -96,25 +97,28 @@ class Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instance of the exception handler.
|
* 获取异常处理的实例
|
||||||
*
|
|
||||||
* @return Handle
|
* @return Handle
|
||||||
*/
|
*/
|
||||||
public static function getExceptionHandler()
|
public static function getExceptionHandler()
|
||||||
{
|
{
|
||||||
static $handle;
|
static $handle;
|
||||||
|
|
||||||
if (!$handle) {
|
if (!$handle) {
|
||||||
// 异常处理handle
|
// 异常处理 handle
|
||||||
$class = Config::get('exception_handle');
|
$class = Config::get('exception_handle');
|
||||||
if ($class && is_string($class) && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) {
|
|
||||||
|
if ($class && is_string($class) && class_exists($class) &&
|
||||||
|
is_subclass_of($class, "\\think\\exception\\Handle")
|
||||||
|
) {
|
||||||
$handle = new $class;
|
$handle = new $class;
|
||||||
} else {
|
} else {
|
||||||
$handle = new Handle;
|
$handle = new Handle;
|
||||||
if ($class instanceof \Closure) {
|
|
||||||
$handle->setRender($class);
|
if ($class instanceof \Closure) $handle->setRender($class);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $handle;
|
return $handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ use think\exception\ClassNotFoundException;
|
|||||||
|
|
||||||
class Loader
|
class Loader
|
||||||
{
|
{
|
||||||
|
// 实例
|
||||||
protected static $instance = [];
|
protected static $instance = [];
|
||||||
|
|
||||||
// 类名映射
|
// 类名映射
|
||||||
protected static $map = [];
|
protected static $map = [];
|
||||||
|
|
||||||
@@ -34,7 +36,12 @@ class Loader
|
|||||||
// 自动加载的文件
|
// 自动加载的文件
|
||||||
private static $autoloadFiles = [];
|
private static $autoloadFiles = [];
|
||||||
|
|
||||||
// 自动加载
|
/**
|
||||||
|
* 自动加载
|
||||||
|
* @access public
|
||||||
|
* @param string $class 类名
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public static function autoload($class)
|
public static function autoload($class)
|
||||||
{
|
{
|
||||||
// 检测命名空间别名
|
// 检测命名空间别名
|
||||||
@@ -48,34 +55,34 @@ class Loader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($file = self::findFile($class)) {
|
$file = self::findFile($class);
|
||||||
|
$path = pathinfo($file, PATHINFO_FILENAME);
|
||||||
// Win环境严格区分大小写
|
$realPath = pathinfo(realpath($file), PATHINFO_FILENAME);
|
||||||
if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 非 Win 环境不严格区分大小写
|
||||||
|
if ($file && (!IS_WIN || $path == $realPath)) {
|
||||||
__include_file($file);
|
__include_file($file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找文件
|
* 查找文件
|
||||||
* @param $class
|
* @access private
|
||||||
|
* @param string $class 类名
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private static function findFile($class)
|
private static function findFile($class)
|
||||||
{
|
{
|
||||||
if (!empty(self::$map[$class])) {
|
// 类库映射
|
||||||
// 类库映射
|
if (!empty(self::$map[$class])) return self::$map[$class];
|
||||||
return self::$map[$class];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找 PSR-4
|
// 查找 PSR-4
|
||||||
$logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
|
$logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
|
||||||
|
|
||||||
$first = $class[0];
|
$first = $class[0];
|
||||||
|
|
||||||
if (isset(self::$prefixLengthsPsr4[$first])) {
|
if (isset(self::$prefixLengthsPsr4[$first])) {
|
||||||
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
|
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||||
if (0 === strpos($class, $prefix)) {
|
if (0 === strpos($class, $prefix)) {
|
||||||
@@ -97,9 +104,9 @@ class Loader
|
|||||||
|
|
||||||
// 查找 PSR-0
|
// 查找 PSR-0
|
||||||
if (false !== $pos = strrpos($class, '\\')) {
|
if (false !== $pos = strrpos($class, '\\')) {
|
||||||
// namespaced class name
|
// namespace class name
|
||||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
|
||||||
} else {
|
} else {
|
||||||
// PEAR-like class name
|
// PEAR-like class name
|
||||||
$logicalPathPsr0 = strtr($class, '_', DS) . EXT;
|
$logicalPathPsr0 = strtr($class, '_', DS) . EXT;
|
||||||
@@ -127,7 +134,13 @@ class Loader
|
|||||||
return self::$map[$class] = false;
|
return self::$map[$class] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册classmap
|
/**
|
||||||
|
* 注册 classmap
|
||||||
|
* @access public
|
||||||
|
* @param string|array $class 类名
|
||||||
|
* @param string $map 映射
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public static function addClassMap($class, $map = '')
|
public static function addClassMap($class, $map = '')
|
||||||
{
|
{
|
||||||
if (is_array($class)) {
|
if (is_array($class)) {
|
||||||
@@ -137,7 +150,13 @@ class Loader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册命名空间
|
/**
|
||||||
|
* 注册命名空间
|
||||||
|
* @access public
|
||||||
|
* @param string|array $namespace 命名空间
|
||||||
|
* @param string $path 路径
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public static function addNamespace($namespace, $path = '')
|
public static function addNamespace($namespace, $path = '')
|
||||||
{
|
{
|
||||||
if (is_array($namespace)) {
|
if (is_array($namespace)) {
|
||||||
@@ -149,84 +168,77 @@ class Loader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加Ps0空间
|
/**
|
||||||
|
* 添加 Ps0 空间
|
||||||
|
* @access private
|
||||||
|
* @param array|null $prefix 空间前缀
|
||||||
|
* @param array $paths 路径
|
||||||
|
* @param bool $prepend 预先设置的优先级更高
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private static function addPsr0($prefix, $paths, $prepend = false)
|
private static function addPsr0($prefix, $paths, $prepend = false)
|
||||||
{
|
{
|
||||||
if (!$prefix) {
|
if (!$prefix) {
|
||||||
if ($prepend) {
|
self::$fallbackDirsPsr0 = $prepend ?
|
||||||
self::$fallbackDirsPsr0 = array_merge(
|
array_merge((array) $paths, self::$fallbackDirsPsr0) :
|
||||||
(array) $paths,
|
array_merge(self::$fallbackDirsPsr0, (array) $paths);
|
||||||
self::$fallbackDirsPsr0
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
self::$fallbackDirsPsr0 = array_merge(
|
|
||||||
self::$fallbackDirsPsr0,
|
|
||||||
(array) $paths
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$first = $prefix[0];
|
|
||||||
if (!isset(self::$prefixesPsr0[$first][$prefix])) {
|
|
||||||
self::$prefixesPsr0[$first][$prefix] = (array) $paths;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($prepend) {
|
|
||||||
self::$prefixesPsr0[$first][$prefix] = array_merge(
|
|
||||||
(array) $paths,
|
|
||||||
self::$prefixesPsr0[$first][$prefix]
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
self::$prefixesPsr0[$first][$prefix] = array_merge(
|
$first = $prefix[0];
|
||||||
self::$prefixesPsr0[$first][$prefix],
|
|
||||||
(array) $paths
|
if (!isset(self::$prefixesPsr0[$first][$prefix])) {
|
||||||
);
|
self::$prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||||
|
} else {
|
||||||
|
self::$prefixesPsr0[$first][$prefix] = $prepend ?
|
||||||
|
array_merge((array) $paths, self::$prefixesPsr0[$first][$prefix]) :
|
||||||
|
array_merge(self::$prefixesPsr0[$first][$prefix], (array) $paths);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加Psr4空间
|
/**
|
||||||
|
* 添加 Ps4 空间
|
||||||
|
* @access private
|
||||||
|
* @param array|string $prefix 空间前缀
|
||||||
|
* @param string $paths 路径
|
||||||
|
* @param bool $prepend 预先设置的优先级更高
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private static function addPsr4($prefix, $paths, $prepend = false)
|
private static function addPsr4($prefix, $paths, $prepend = false)
|
||||||
{
|
{
|
||||||
if (!$prefix) {
|
if (!$prefix) {
|
||||||
// Register directories for the root namespace.
|
// Register directories for the root namespace.
|
||||||
if ($prepend) {
|
self::$fallbackDirsPsr4 = $prepend ?
|
||||||
self::$fallbackDirsPsr4 = array_merge(
|
array_merge((array) $paths, self::$fallbackDirsPsr4) :
|
||||||
(array) $paths,
|
array_merge(self::$fallbackDirsPsr4, (array) $paths);
|
||||||
self::$fallbackDirsPsr4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
self::$fallbackDirsPsr4 = array_merge(
|
|
||||||
self::$fallbackDirsPsr4,
|
|
||||||
(array) $paths
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
|
} elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
|
||||||
// Register directories for a new namespace.
|
// Register directories for a new namespace.
|
||||||
$length = strlen($prefix);
|
$length = strlen($prefix);
|
||||||
if ('\\' !== $prefix[$length - 1]) {
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
throw new \InvalidArgumentException(
|
||||||
|
"A non-empty PSR-4 prefix must end with a namespace separator."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
self::$prefixDirsPsr4[$prefix] = (array) $paths;
|
self::$prefixDirsPsr4[$prefix] = (array) $paths;
|
||||||
} elseif ($prepend) {
|
|
||||||
// Prepend directories for an already registered namespace.
|
|
||||||
self::$prefixDirsPsr4[$prefix] = array_merge(
|
|
||||||
(array) $paths,
|
|
||||||
self::$prefixDirsPsr4[$prefix]
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// Append directories for an already registered namespace.
|
self::$prefixDirsPsr4[$prefix] = $prepend ?
|
||||||
self::$prefixDirsPsr4[$prefix] = array_merge(
|
// Prepend directories for an already registered namespace.
|
||||||
self::$prefixDirsPsr4[$prefix],
|
array_merge((array) $paths, self::$prefixDirsPsr4[$prefix]) :
|
||||||
(array) $paths
|
// Append directories for an already registered namespace.
|
||||||
);
|
array_merge(self::$prefixDirsPsr4[$prefix], (array) $paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册命名空间别名
|
/**
|
||||||
|
* 注册命名空间别名
|
||||||
|
* @access public
|
||||||
|
* @param array|string $namespace 命名空间
|
||||||
|
* @param string $original 源文件
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public static function addNamespaceAlias($namespace, $original = '')
|
public static function addNamespaceAlias($namespace, $original = '')
|
||||||
{
|
{
|
||||||
if (is_array($namespace)) {
|
if (is_array($namespace)) {
|
||||||
@@ -236,32 +248,41 @@ class Loader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册自动加载机制
|
/**
|
||||||
public static function register($autoload = '')
|
* 注册自动加载机制
|
||||||
|
* @access public
|
||||||
|
* @param callable $autoload 自动加载处理方法
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function register($autoload = null)
|
||||||
{
|
{
|
||||||
// 注册系统自动加载
|
// 注册系统自动加载
|
||||||
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
|
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
|
||||||
|
|
||||||
|
// 加载类库映射文件
|
||||||
|
if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {
|
||||||
|
self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Composer 自动加载支持
|
||||||
|
if (is_dir(VENDOR_PATH . 'composer')) self::registerComposerLoader();
|
||||||
|
|
||||||
// 注册命名空间定义
|
// 注册命名空间定义
|
||||||
self::addNamespace([
|
self::addNamespace([
|
||||||
'think' => LIB_PATH . 'think' . DS,
|
'think' => LIB_PATH . 'think' . DS,
|
||||||
'behavior' => LIB_PATH . 'behavior' . DS,
|
'behavior' => LIB_PATH . 'behavior' . DS,
|
||||||
'traits' => LIB_PATH . 'traits' . DS,
|
'traits' => LIB_PATH . 'traits' . DS,
|
||||||
]);
|
]);
|
||||||
// 加载类库映射文件
|
|
||||||
if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {
|
|
||||||
self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Composer自动加载支持
|
// 自动加载 extend 目录
|
||||||
if (is_dir(VENDOR_PATH . 'composer')) {
|
|
||||||
self::registerComposerLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动加载extend目录
|
|
||||||
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
|
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册composer自动加载
|
/**
|
||||||
|
* 注册 composer 自动加载
|
||||||
|
* @access private
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private static function registerComposerLoader()
|
private static function registerComposerLoader()
|
||||||
{
|
{
|
||||||
if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {
|
if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {
|
||||||
@@ -280,9 +301,7 @@ class Loader
|
|||||||
|
|
||||||
if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {
|
if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {
|
||||||
$classMap = require VENDOR_PATH . 'composer/autoload_classmap.php';
|
$classMap = require VENDOR_PATH . 'composer/autoload_classmap.php';
|
||||||
if ($classMap) {
|
if ($classMap) self::addClassMap($classMap);
|
||||||
self::addClassMap($classMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
|
if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
|
||||||
@@ -297,20 +316,20 @@ class Loader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入所需的类库 同java的Import 本函数有缓存功能
|
* 导入所需的类库 同 Java 的 Import 本函数有缓存功能
|
||||||
|
* @access public
|
||||||
* @param string $class 类库命名空间字符串
|
* @param string $class 类库命名空间字符串
|
||||||
* @param string $baseUrl 起始路径
|
* @param string $baseUrl 起始路径
|
||||||
* @param string $ext 导入的文件扩展名
|
* @param string $ext 导入的文件扩展名
|
||||||
* @return boolean
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function import($class, $baseUrl = '', $ext = EXT)
|
public static function import($class, $baseUrl = '', $ext = EXT)
|
||||||
{
|
{
|
||||||
static $_file = [];
|
static $_file = [];
|
||||||
$key = $class . $baseUrl;
|
$key = $class . $baseUrl;
|
||||||
$class = str_replace(['.', '#'], [DS, '.'], $class);
|
$class = str_replace(['.', '#'], [DS, '.'], $class);
|
||||||
if (isset($_file[$key])) {
|
|
||||||
return true;
|
if (isset($_file[$key])) return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($baseUrl)) {
|
if (empty($baseUrl)) {
|
||||||
list($name, $class) = explode(DS, $class, 2);
|
list($name, $class) = explode(DS, $class, 2);
|
||||||
@@ -319,7 +338,7 @@ class Loader
|
|||||||
// 注册的命名空间
|
// 注册的命名空间
|
||||||
$baseUrl = self::$prefixDirsPsr4[$name . '\\'];
|
$baseUrl = self::$prefixDirsPsr4[$name . '\\'];
|
||||||
} elseif ('@' == $name) {
|
} elseif ('@' == $name) {
|
||||||
//加载当前模块应用类库
|
// 加载当前模块应用类库
|
||||||
$baseUrl = App::$modulePath;
|
$baseUrl = App::$modulePath;
|
||||||
} elseif (is_dir(EXTEND_PATH . $name)) {
|
} elseif (is_dir(EXTEND_PATH . $name)) {
|
||||||
$baseUrl = EXTEND_PATH . $name . DS;
|
$baseUrl = EXTEND_PATH . $name . DS;
|
||||||
@@ -330,32 +349,34 @@ class Loader
|
|||||||
} elseif (substr($baseUrl, -1) != DS) {
|
} elseif (substr($baseUrl, -1) != DS) {
|
||||||
$baseUrl .= DS;
|
$baseUrl .= DS;
|
||||||
}
|
}
|
||||||
// 如果类存在 则导入类库文件
|
|
||||||
|
// 如果类存在则导入类库文件
|
||||||
if (is_array($baseUrl)) {
|
if (is_array($baseUrl)) {
|
||||||
foreach ($baseUrl as $path) {
|
foreach ($baseUrl as $path) {
|
||||||
$filename = $path . DS . $class . $ext;
|
$filename = $path . DS . $class . $ext;
|
||||||
if (is_file($filename)) {
|
|
||||||
break;
|
if (is_file($filename)) break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$filename = $baseUrl . $class . $ext;
|
$filename = $baseUrl . $class . $ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($filename) && is_file($filename)) {
|
if (!empty($filename) &&
|
||||||
// 开启调试模式Win环境严格区分大小写
|
is_file($filename) &&
|
||||||
if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) {
|
(!IS_WIN || pathinfo($filename, PATHINFO_FILENAME) == pathinfo(realpath($filename), PATHINFO_FILENAME))
|
||||||
return false;
|
) {
|
||||||
}
|
|
||||||
__include_file($filename);
|
__include_file($filename);
|
||||||
$_file[$key] = true;
|
$_file[$key] = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例化(分层)模型
|
* 实例化(分层)模型
|
||||||
|
* @access public
|
||||||
* @param string $name Model名称
|
* @param string $name Model名称
|
||||||
* @param string $layer 业务层名称
|
* @param string $layer 业务层名称
|
||||||
* @param bool $appendSuffix 是否添加类名后缀
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
@@ -365,27 +386,30 @@ class Loader
|
|||||||
*/
|
*/
|
||||||
public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
|
public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
|
||||||
{
|
{
|
||||||
$guid = $name . $layer;
|
$uid = $name . $layer;
|
||||||
if (isset(self::$instance[$guid])) {
|
|
||||||
return self::$instance[$guid];
|
if (isset(self::$instance[$uid])) return self::$instance[$uid];
|
||||||
}
|
|
||||||
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
||||||
|
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$model = new $class();
|
$model = new $class();
|
||||||
} else {
|
} else {
|
||||||
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
||||||
|
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$model = new $class();
|
$model = new $class();
|
||||||
} else {
|
} else {
|
||||||
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$instance[$guid] = $model;
|
|
||||||
return $model;
|
return self::$instance[$uid] = $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例化(分层)控制器 格式:[模块名/]控制器名
|
* 实例化(分层)控制器 格式:[模块名/]控制器名
|
||||||
|
* @access public
|
||||||
* @param string $name 资源地址
|
* @param string $name 资源地址
|
||||||
* @param string $layer 控制层名称
|
* @param string $layer 控制层名称
|
||||||
* @param bool $appendSuffix 是否添加类名后缀
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
@@ -396,17 +420,23 @@ class Loader
|
|||||||
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
|
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
|
||||||
{
|
{
|
||||||
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
||||||
if (class_exists($class)) {
|
|
||||||
return App::invokeClass($class);
|
if (class_exists($class)) return App::invokeClass($class);
|
||||||
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
|
|
||||||
return new $emptyClass(Request::instance());
|
if ($empty) {
|
||||||
} else {
|
$emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix);
|
||||||
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
|
||||||
|
if (class_exists($emptyClass)) {
|
||||||
|
return new $emptyClass(Request::instance());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例化验证类 格式:[模块名/]验证器名
|
* 实例化验证类 格式:[模块名/]验证器名
|
||||||
|
* @access public
|
||||||
* @param string $name 资源地址
|
* @param string $name 资源地址
|
||||||
* @param string $layer 验证层名称
|
* @param string $layer 验证层名称
|
||||||
* @param bool $appendSuffix 是否添加类名后缀
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
@@ -417,30 +447,31 @@ class Loader
|
|||||||
public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')
|
public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')
|
||||||
{
|
{
|
||||||
$name = $name ?: Config::get('default_validate');
|
$name = $name ?: Config::get('default_validate');
|
||||||
if (empty($name)) {
|
if (empty($name)) return new Validate;
|
||||||
return new Validate;
|
|
||||||
}
|
$uid = $name . $layer;
|
||||||
$guid = $name . $layer;
|
if (isset(self::$instance[$uid])) return self::$instance[$uid];
|
||||||
if (isset(self::$instance[$guid])) {
|
|
||||||
return self::$instance[$guid];
|
|
||||||
}
|
|
||||||
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
||||||
|
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$validate = new $class;
|
$validate = new $class;
|
||||||
} else {
|
} else {
|
||||||
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
||||||
|
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
$validate = new $class;
|
$validate = new $class;
|
||||||
} else {
|
} else {
|
||||||
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$instance[$guid] = $validate;
|
|
||||||
return $validate;
|
return self::$instance[$uid] = $validate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析模块和类名
|
* 解析模块和类名
|
||||||
|
* @access protected
|
||||||
* @param string $name 资源地址
|
* @param string $name 资源地址
|
||||||
* @param string $layer 验证层名称
|
* @param string $layer 验证层名称
|
||||||
* @param bool $appendSuffix 是否添加类名后缀
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
@@ -457,15 +488,18 @@ class Loader
|
|||||||
} else {
|
} else {
|
||||||
$module = Request::instance()->module();
|
$module = Request::instance()->module();
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
$class = self::parseClass($module, $layer, $name, $appendSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$module, $class];
|
return [$module, $class];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库初始化 并取得数据库类实例
|
* 数据库初始化 并取得数据库类实例
|
||||||
* @param mixed $config 数据库配置
|
* @access public
|
||||||
* @param bool|string $name 连接标识 true 强制重新连接
|
* @param mixed $config 数据库配置
|
||||||
|
* @param bool|string $name 连接标识 true 强制重新连接
|
||||||
* @return \think\db\Connection
|
* @return \think\db\Connection
|
||||||
*/
|
*/
|
||||||
public static function db($config = [], $name = false)
|
public static function db($config = [], $name = false)
|
||||||
@@ -475,6 +509,7 @@ class Loader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
|
* 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
|
||||||
|
* @access public
|
||||||
* @param string $url 调用地址
|
* @param string $url 调用地址
|
||||||
* @param string|array $vars 调用参数 支持字符串和数组
|
* @param string|array $vars 调用参数 支持字符串和数组
|
||||||
* @param string $layer 要调用的控制层名称
|
* @param string $layer 要调用的控制层名称
|
||||||
@@ -487,6 +522,7 @@ class Loader
|
|||||||
$action = $info['basename'];
|
$action = $info['basename'];
|
||||||
$module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();
|
$module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();
|
||||||
$class = self::controller($module, $layer, $appendSuffix);
|
$class = self::controller($module, $layer, $appendSuffix);
|
||||||
|
|
||||||
if ($class) {
|
if ($class) {
|
||||||
if (is_scalar($vars)) {
|
if (is_scalar($vars)) {
|
||||||
if (strpos($vars, '=')) {
|
if (strpos($vars, '=')) {
|
||||||
@@ -495,15 +531,19 @@ class Loader
|
|||||||
$vars = [$vars];
|
$vars = [$vars];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);
|
return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串命名风格转换
|
* 字符串命名风格转换
|
||||||
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
* type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格
|
||||||
* @param string $name 字符串
|
* @access public
|
||||||
* @param integer $type 转换类型
|
* @param string $name 字符串
|
||||||
|
* @param integer $type 转换类型
|
||||||
* @param bool $ucfirst 首字母是否大写(驼峰规则)
|
* @param bool $ucfirst 首字母是否大写(驼峰规则)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -513,31 +553,38 @@ class Loader
|
|||||||
$name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
$name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
||||||
return strtoupper($match[1]);
|
return strtoupper($match[1]);
|
||||||
}, $name);
|
}, $name);
|
||||||
|
|
||||||
return $ucfirst ? ucfirst($name) : lcfirst($name);
|
return $ucfirst ? ucfirst($name) : lcfirst($name);
|
||||||
} else {
|
|
||||||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析应用类的类名
|
* 解析应用类的类名
|
||||||
* @param string $module 模块名
|
* @access public
|
||||||
* @param string $layer 层名 controller model ...
|
* @param string $module 模块名
|
||||||
* @param string $name 类名
|
* @param string $layer 层名 controller model ...
|
||||||
* @param bool $appendSuffix
|
* @param string $name 类名
|
||||||
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function parseClass($module, $layer, $name, $appendSuffix = false)
|
public static function parseClass($module, $layer, $name, $appendSuffix = false)
|
||||||
{
|
{
|
||||||
$name = str_replace(['/', '.'], '\\', $name);
|
|
||||||
$array = explode('\\', $name);
|
$array = explode('\\', str_replace(['/', '.'], '\\', $name));
|
||||||
$class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');
|
$class = self::parseName(array_pop($array), 1);
|
||||||
|
$class = $class . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');
|
||||||
$path = $array ? implode('\\', $array) . '\\' : '';
|
$path = $array ? implode('\\', $array) . '\\' : '';
|
||||||
return App::$namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class;
|
|
||||||
|
return App::$namespace . '\\' .
|
||||||
|
($module ? $module . '\\' : '') .
|
||||||
|
$layer . '\\' . $path . $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化类的实例
|
* 初始化类的实例
|
||||||
|
* @access public
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function clearInstance()
|
public static function clearInstance()
|
||||||
@@ -546,10 +593,11 @@ class Loader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 作用范围隔离
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 作用范围隔离
|
* include
|
||||||
*
|
* @param string $file 文件路径
|
||||||
* @param $file
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function __include_file($file)
|
function __include_file($file)
|
||||||
@@ -557,6 +605,11 @@ function __include_file($file)
|
|||||||
return include $file;
|
return include $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* require
|
||||||
|
* @param string $file 文件路径
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
function __require_file($file)
|
function __require_file($file)
|
||||||
{
|
{
|
||||||
return require $file;
|
return require $file;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用法:
|
* 用法:
|
||||||
* load_trait('controller/Jump');
|
* load_trait('controller/Jump');
|
||||||
@@ -27,20 +26,23 @@ trait Jump
|
|||||||
/**
|
/**
|
||||||
* 操作成功跳转的快捷方法
|
* 操作成功跳转的快捷方法
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param mixed $msg 提示信息
|
* @param mixed $msg 提示信息
|
||||||
* @param string $url 跳转的URL地址
|
* @param string $url 跳转的 URL 地址
|
||||||
* @param mixed $data 返回的数据
|
* @param mixed $data 返回的数据
|
||||||
* @param integer $wait 跳转等待时间
|
* @param int $wait 跳转等待时间
|
||||||
* @param array $header 发送的Header信息
|
* @param array $header 发送的 Header 信息
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HttpResponseException
|
||||||
*/
|
*/
|
||||||
protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
|
protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
|
||||||
{
|
{
|
||||||
if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) {
|
if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) {
|
||||||
$url = Request::instance()->server('HTTP_REFERER');
|
$url = Request::instance()->server('HTTP_REFERER');
|
||||||
} elseif ('' !== $url) {
|
} elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) {
|
||||||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url);
|
$url = Url::build($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$type = $this->getResponseType();
|
||||||
$result = [
|
$result = [
|
||||||
'code' => 1,
|
'code' => 1,
|
||||||
'msg' => $msg,
|
'msg' => $msg,
|
||||||
@@ -49,32 +51,39 @@ trait Jump
|
|||||||
'wait' => $wait,
|
'wait' => $wait,
|
||||||
];
|
];
|
||||||
|
|
||||||
$type = $this->getResponseType();
|
|
||||||
if ('html' == strtolower($type)) {
|
if ('html' == strtolower($type)) {
|
||||||
$result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str'))
|
$template = Config::get('template');
|
||||||
|
$view = Config::get('view_replace_str');
|
||||||
|
|
||||||
|
$result = ViewTemplate::instance($template, $view)
|
||||||
->fetch(Config::get('dispatch_success_tmpl'), $result);
|
->fetch(Config::get('dispatch_success_tmpl'), $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = Response::create($result, $type)->header($header);
|
$response = Response::create($result, $type)->header($header);
|
||||||
|
|
||||||
throw new HttpResponseException($response);
|
throw new HttpResponseException($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作错误跳转的快捷方法
|
* 操作错误跳转的快捷方法
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param mixed $msg 提示信息
|
* @param mixed $msg 提示信息
|
||||||
* @param string $url 跳转的URL地址
|
* @param string $url 跳转的 URL 地址
|
||||||
* @param mixed $data 返回的数据
|
* @param mixed $data 返回的数据
|
||||||
* @param integer $wait 跳转等待时间
|
* @param int $wait 跳转等待时间
|
||||||
* @param array $header 发送的Header信息
|
* @param array $header 发送的 Header 信息
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HttpResponseException
|
||||||
*/
|
*/
|
||||||
protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
|
protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
|
||||||
{
|
{
|
||||||
if (is_null($url)) {
|
if (is_null($url)) {
|
||||||
$url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);';
|
$url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);';
|
||||||
} elseif ('' !== $url) {
|
} elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) {
|
||||||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url);
|
$url = Url::build($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$type = $this->getResponseType();
|
||||||
$result = [
|
$result = [
|
||||||
'code' => 0,
|
'code' => 0,
|
||||||
'msg' => $msg,
|
'msg' => $msg,
|
||||||
@@ -83,24 +92,29 @@ trait Jump
|
|||||||
'wait' => $wait,
|
'wait' => $wait,
|
||||||
];
|
];
|
||||||
|
|
||||||
$type = $this->getResponseType();
|
|
||||||
if ('html' == strtolower($type)) {
|
if ('html' == strtolower($type)) {
|
||||||
$result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str'))
|
$template = Config::get('template');
|
||||||
|
$view = Config::get('view_replace_str');
|
||||||
|
|
||||||
|
$result = ViewTemplate::instance($template, $view)
|
||||||
->fetch(Config::get('dispatch_error_tmpl'), $result);
|
->fetch(Config::get('dispatch_error_tmpl'), $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = Response::create($result, $type)->header($header);
|
$response = Response::create($result, $type)->header($header);
|
||||||
|
|
||||||
throw new HttpResponseException($response);
|
throw new HttpResponseException($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回封装后的API数据到客户端
|
* 返回封装后的 API 数据到客户端
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param mixed $data 要返回的数据
|
* @param mixed $data 要返回的数据
|
||||||
* @param integer $code 返回的code
|
* @param int $code 返回的 code
|
||||||
* @param mixed $msg 提示信息
|
* @param mixed $msg 提示信息
|
||||||
* @param string $type 返回数据格式
|
* @param string $type 返回数据格式
|
||||||
* @param array $header 发送的Header信息
|
* @param array $header 发送的 Header 信息
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HttpResponseException
|
||||||
*/
|
*/
|
||||||
protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])
|
protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])
|
||||||
{
|
{
|
||||||
@@ -112,37 +126,42 @@ trait Jump
|
|||||||
];
|
];
|
||||||
$type = $type ?: $this->getResponseType();
|
$type = $type ?: $this->getResponseType();
|
||||||
$response = Response::create($result, $type)->header($header);
|
$response = Response::create($result, $type)->header($header);
|
||||||
|
|
||||||
throw new HttpResponseException($response);
|
throw new HttpResponseException($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL重定向
|
* URL 重定向
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $url 跳转的URL表达式
|
* @param string $url 跳转的 URL 表达式
|
||||||
* @param array|integer $params 其它URL参数
|
* @param array|int $params 其它 URL 参数
|
||||||
* @param integer $code http code
|
* @param int $code http code
|
||||||
* @param array $with 隐式传参
|
* @param array $with 隐式传参
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HttpResponseException
|
||||||
*/
|
*/
|
||||||
protected function redirect($url, $params = [], $code = 302, $with = [])
|
protected function redirect($url, $params = [], $code = 302, $with = [])
|
||||||
{
|
{
|
||||||
$response = new Redirect($url);
|
|
||||||
if (is_integer($params)) {
|
if (is_integer($params)) {
|
||||||
$code = $params;
|
$code = $params;
|
||||||
$params = [];
|
$params = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response = new Redirect($url);
|
||||||
$response->code($code)->params($params)->with($with);
|
$response->code($code)->params($params)->with($with);
|
||||||
|
|
||||||
throw new HttpResponseException($response);
|
throw new HttpResponseException($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前的response 输出类型
|
* 获取当前的 response 输出类型
|
||||||
* @access protected
|
* @access protected
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getResponseType()
|
protected function getResponseType()
|
||||||
{
|
{
|
||||||
$isAjax = Request::instance()->isAjax();
|
return Request::instance()->isAjax()
|
||||||
return $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
|
? Config::get('default_ajax_return')
|
||||||
|
: Config::get('default_return_type');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use think\Model;
|
|||||||
*/
|
*/
|
||||||
trait SoftDelete
|
trait SoftDelete
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断当前实例是否被软删除
|
* 判断当前实例是否被软删除
|
||||||
* @access public
|
* @access public
|
||||||
@@ -19,22 +18,18 @@ trait SoftDelete
|
|||||||
public function trashed()
|
public function trashed()
|
||||||
{
|
{
|
||||||
$field = $this->getDeleteTimeField();
|
$field = $this->getDeleteTimeField();
|
||||||
if (!empty($this->data[$field])) {
|
|
||||||
return true;
|
return !empty($this->data[$field]);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询软删除数据
|
* 查询包含软删除的数据
|
||||||
* @access public
|
* @access public
|
||||||
* @return Query
|
* @return Query
|
||||||
*/
|
*/
|
||||||
public static function withTrashed()
|
public static function withTrashed()
|
||||||
{
|
{
|
||||||
$model = new static();
|
return (new static)->getQuery();
|
||||||
$field = $model->getDeleteTimeField(true);
|
|
||||||
return $model->getQuery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,31 +41,28 @@ trait SoftDelete
|
|||||||
{
|
{
|
||||||
$model = new static();
|
$model = new static();
|
||||||
$field = $model->getDeleteTimeField(true);
|
$field = $model->getDeleteTimeField(true);
|
||||||
return $model->getQuery()
|
|
||||||
->useSoftDelete($field, ['not null', '']);
|
return $model->getQuery()->useSoftDelete($field, ['not null', '']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除当前的记录
|
* 删除当前的记录
|
||||||
* @access public
|
* @access public
|
||||||
* @param bool $force 是否强制删除
|
* @param bool $force 是否强制删除
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function delete($force = false)
|
public function delete($force = false)
|
||||||
{
|
{
|
||||||
if (false === $this->trigger('before_delete', $this)) {
|
if (false === $this->trigger('before_delete', $this)) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$name = $this->getDeleteTimeField();
|
$name = $this->getDeleteTimeField();
|
||||||
if (!$force) {
|
if (!$force) {
|
||||||
// 软删除
|
// 软删除
|
||||||
$this->data[$name] = $this->autoWriteTimestamp($name);
|
$this->data[$name] = $this->autoWriteTimestamp($name);
|
||||||
$result = $this->isUpdate()->save();
|
$result = $this->isUpdate()->save();
|
||||||
} else {
|
} else {
|
||||||
// 删除条件
|
// 强制删除当前模型数据
|
||||||
$where = $this->getWhere();
|
$result = $this->getQuery()->where($this->getWhere())->delete();
|
||||||
// 删除当前模型数据
|
|
||||||
$result = $this->getQuery()->where($where)->delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关联删除
|
// 关联删除
|
||||||
@@ -78,47 +70,48 @@ trait SoftDelete
|
|||||||
foreach ($this->relationWrite as $key => $name) {
|
foreach ($this->relationWrite as $key => $name) {
|
||||||
$name = is_numeric($key) ? $name : $key;
|
$name = is_numeric($key) ? $name : $key;
|
||||||
$model = $this->getAttr($name);
|
$model = $this->getAttr($name);
|
||||||
if ($model instanceof Model) {
|
|
||||||
$model->delete($force);
|
if ($model instanceof Model) $model->delete();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->trigger('after_delete', $this);
|
$this->trigger('after_delete', $this);
|
||||||
|
|
||||||
// 清空原始数据
|
// 清空原始数据
|
||||||
$this->origin = [];
|
$this->origin = [];
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除记录
|
* 删除记录
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 主键列表 支持闭包查询条件
|
* @param mixed $data 主键列表(支持闭包查询条件)
|
||||||
* @param bool $force 是否强制删除
|
* @param bool $force 是否强制删除
|
||||||
* @return integer 成功删除的记录数
|
* @return integer 成功删除的记录数
|
||||||
*/
|
*/
|
||||||
public static function destroy($data, $force = false)
|
public static function destroy($data, $force = false)
|
||||||
{
|
{
|
||||||
|
if (is_null($data)) return 0;
|
||||||
|
|
||||||
// 包含软删除数据
|
// 包含软删除数据
|
||||||
$query = self::withTrashed();
|
$query = self::withTrashed();
|
||||||
if (is_array($data) && key($data) !== 0) {
|
if (is_array($data) && key($data) !== 0) {
|
||||||
$query->where($data);
|
$query->where($data);
|
||||||
$data = null;
|
$data = null;
|
||||||
} elseif ($data instanceof \Closure) {
|
} elseif ($data instanceof \Closure) {
|
||||||
call_user_func_array($data, [ & $query]);
|
call_user_func_array($data, [&$query]);
|
||||||
$data = null;
|
$data = null;
|
||||||
} elseif (is_null($data)) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$resultSet = $query->select($data);
|
$count = 0;
|
||||||
$count = 0;
|
if ($resultSet = $query->select($data)) {
|
||||||
if ($resultSet) {
|
|
||||||
foreach ($resultSet as $data) {
|
foreach ($resultSet as $data) {
|
||||||
$result = $data->delete($force);
|
$result = $data->delete($force);
|
||||||
$count += $result;
|
$count += $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,11 +123,13 @@ trait SoftDelete
|
|||||||
*/
|
*/
|
||||||
public function restore($where = [])
|
public function restore($where = [])
|
||||||
{
|
{
|
||||||
$name = $this->getDeleteTimeField();
|
|
||||||
if (empty($where)) {
|
if (empty($where)) {
|
||||||
$pk = $this->getPk();
|
$pk = $this->getPk();
|
||||||
$where[$pk] = $this->getData($pk);
|
$where[$pk] = $this->getData($pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$name = $this->getDeleteTimeField();
|
||||||
|
|
||||||
// 恢复删除
|
// 恢复删除
|
||||||
return $this->getQuery()
|
return $this->getQuery()
|
||||||
->useSoftDelete($name, ['not null', ''])
|
->useSoftDelete($name, ['not null', ''])
|
||||||
@@ -146,30 +141,32 @@ trait SoftDelete
|
|||||||
* 查询默认不包含软删除数据
|
* 查询默认不包含软删除数据
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param Query $query 查询对象
|
* @param Query $query 查询对象
|
||||||
* @return void
|
* @return Query
|
||||||
*/
|
*/
|
||||||
protected function base($query)
|
protected function base($query)
|
||||||
{
|
{
|
||||||
$field = $this->getDeleteTimeField(true);
|
return $query->useSoftDelete($this->getDeleteTimeField(true));
|
||||||
$query->useSoftDelete($field);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取软删除字段
|
* 获取软删除字段
|
||||||
* @access public
|
* @access public
|
||||||
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
|
* @param bool $read 是否查询操作(写操作的时候会自动去掉表别名)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getDeleteTimeField($read = false)
|
protected function getDeleteTimeField($read = false)
|
||||||
{
|
{
|
||||||
$field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time';
|
$field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ?
|
||||||
if (!strpos($field, '.')) {
|
$this->deleteTime :
|
||||||
$field = '__TABLE__.' . $field;
|
'delete_time';
|
||||||
}
|
|
||||||
|
if (!strpos($field, '.')) $field = '__TABLE__.' . $field;
|
||||||
|
|
||||||
if (!$read && strpos($field, '.')) {
|
if (!$read && strpos($field, '.')) {
|
||||||
$array = explode('.', $field);
|
$array = explode('.', $field);
|
||||||
$field = array_pop($array);
|
$field = array_pop($array);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,31 +15,40 @@ use think\Exception;
|
|||||||
|
|
||||||
trait Instance
|
trait Instance
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var null|static 实例对象
|
||||||
|
*/
|
||||||
protected static $instance = null;
|
protected static $instance = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $options
|
* 获取示例
|
||||||
|
* @param array $options 实例配置
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function instance($options = [])
|
public static function instance($options = [])
|
||||||
{
|
{
|
||||||
if (is_null(self::$instance)) {
|
if (is_null(self::$instance)) self::$instance = new self($options);
|
||||||
self::$instance = new self($options);
|
|
||||||
}
|
|
||||||
return self::$instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 静态调用
|
/**
|
||||||
public static function __callStatic($method, $params)
|
* 静态调用
|
||||||
|
* @param string $method 调用方法
|
||||||
|
* @param array $params 调用参数
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic($method, array $params)
|
||||||
{
|
{
|
||||||
if (is_null(self::$instance)) {
|
if (is_null(self::$instance)) self::$instance = new self();
|
||||||
self::$instance = new self();
|
|
||||||
}
|
|
||||||
$call = substr($method, 1);
|
$call = substr($method, 1);
|
||||||
if (0 === strpos($method, '_') && is_callable([self::$instance, $call])) {
|
|
||||||
return call_user_func_array([self::$instance, $call], $params);
|
if (0 !== strpos($method, '_') || !is_callable([self::$instance, $call])) {
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists:" . $method);
|
throw new Exception("method not exists:" . $method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return call_user_func_array([self::$instance, $call], $params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user