内核更新升级
This commit is contained in:
@@ -31,9 +31,32 @@ defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录
|
||||
defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀
|
||||
defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀
|
||||
defined('IS_API') or define('IS_API', false); // 是否API接口
|
||||
defined('APP_AUTO_RUN') or define('APP_AUTO_RUN', true); // 是否自动运行
|
||||
defined('AUTO_SCAN_PACKAGE') or define('AUTO_SCAN_PACKAGE', false); // 是否自动扫描非Composer安装类库
|
||||
|
||||
// 环境常量
|
||||
define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
|
||||
define('IS_WIN', strstr(PHP_OS, 'WIN') ? true : false);
|
||||
|
||||
// 载入Loader类
|
||||
require CORE_PATH . 'Loader.php';
|
||||
|
||||
// 加载环境变量配置文件
|
||||
if (is_file(ROOT_PATH . 'env' . EXT)) {
|
||||
$env = include ROOT_PATH . 'env' . EXT;
|
||||
foreach ($env as $key => $val) {
|
||||
$name = ENV_PREFIX . $key;
|
||||
if (is_bool($val)) {
|
||||
$val = $val ? 1 : 0;
|
||||
}
|
||||
putenv("$name=$val");
|
||||
}
|
||||
}
|
||||
|
||||
// 注册自动加载
|
||||
\think\Loader::register();
|
||||
|
||||
// 注册错误和异常处理机制
|
||||
\think\Error::register();
|
||||
|
||||
// 加载模式配置文件
|
||||
\think\Config::set(include THINK_PATH . 'convention' . EXT);
|
||||
|
||||
135
core/helper.php
135
core/helper.php
@@ -29,8 +29,8 @@ use think\View;
|
||||
|
||||
/**
|
||||
* 快速导入Traits PHP5.5以上无需调用
|
||||
* @param string $class trait库
|
||||
* @param string $ext 类库后缀
|
||||
* @param string $class trait库
|
||||
* @param string $ext 类库后缀
|
||||
* @return boolean
|
||||
*/
|
||||
function load_trait($class, $ext = EXT)
|
||||
@@ -41,9 +41,9 @@ function load_trait($class, $ext = EXT)
|
||||
/**
|
||||
* 抛出异常处理
|
||||
*
|
||||
* @param string $msg 异常消息
|
||||
* @param integer $code 异常代码 默认为0
|
||||
* @param string $exception 异常类
|
||||
* @param string $msg 异常消息
|
||||
* @param integer $code 异常代码 默认为0
|
||||
* @param string $exception 异常类
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -55,9 +55,9 @@ function exception($msg, $code = 0, $exception = '')
|
||||
|
||||
/**
|
||||
* 记录时间(微秒)和内存使用情况
|
||||
* @param string $start 开始标签
|
||||
* @param string $end 结束标签
|
||||
* @param integer|string $dec 小数位 如果是m 表示统计内存占用
|
||||
* @param string $start 开始标签
|
||||
* @param string $end 结束标签
|
||||
* @param integer|string $dec 小数位 如果是m 表示统计内存占用
|
||||
* @return mixed
|
||||
*/
|
||||
function debug($start, $end = '', $dec = 6)
|
||||
@@ -71,9 +71,9 @@ function debug($start, $end = '', $dec = 6)
|
||||
|
||||
/**
|
||||
* 获取语言变量值
|
||||
* @param string $name 语言变量名
|
||||
* @param array $vars 动态变量值
|
||||
* @param string $lang 语言
|
||||
* @param string $name 语言变量名
|
||||
* @param array $vars 动态变量值
|
||||
* @param string $lang 语言
|
||||
* @return mixed
|
||||
*/
|
||||
function lang($name, $vars = [], $lang = '')
|
||||
@@ -83,9 +83,9 @@ function lang($name, $vars = [], $lang = '')
|
||||
|
||||
/**
|
||||
* 获取和设置配置参数
|
||||
* @param string|array $name 参数名
|
||||
* @param mixed $value 参数值
|
||||
* @param string $range 作用域
|
||||
* @param string|array $name 参数名
|
||||
* @param mixed $value 参数值
|
||||
* @param string $range 作用域
|
||||
* @return mixed
|
||||
*/
|
||||
function config($name = '', $value = null, $range = '')
|
||||
@@ -99,10 +99,9 @@ function config($name = '', $value = null, $range = '')
|
||||
|
||||
/**
|
||||
* 获取输入数据 支持默认值和过滤
|
||||
* @param string $key 获取的变量名
|
||||
* @param mixed $default 默认值
|
||||
* @param string $filter 过滤方法
|
||||
* @param bool $merge 是否合并系统默认过滤方法
|
||||
* @param string $key 获取的变量名
|
||||
* @param mixed $default 默认值
|
||||
* @param string $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
function input($key, $default = null, $filter = null)
|
||||
@@ -123,17 +122,17 @@ function input($key, $default = null, $filter = null)
|
||||
// 默认为自动判断
|
||||
$method = 'param';
|
||||
}
|
||||
if(isset($has)){
|
||||
if (isset($has)) {
|
||||
return request()->has($key, $method, $default);
|
||||
}else{
|
||||
} else {
|
||||
return request()->$method($key, $default, $filter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染输出Widget
|
||||
* @param string $name Widget名称
|
||||
* @param array $data 传人的参数
|
||||
* @param string $name Widget名称
|
||||
* @param array $data 传人的参数
|
||||
* @return mixed
|
||||
*/
|
||||
function widget($name, $data = [])
|
||||
@@ -143,9 +142,9 @@ function widget($name, $data = [])
|
||||
|
||||
/**
|
||||
* 实例化Model
|
||||
* @param string $name Model名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $name Model名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @return \think\Model
|
||||
*/
|
||||
function model($name = '', $layer = 'model', $appendSuffix = false)
|
||||
@@ -155,9 +154,9 @@ function model($name = '', $layer = 'model', $appendSuffix = false)
|
||||
|
||||
/**
|
||||
* 实例化验证器
|
||||
* @param string $name 验证器名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $name 验证器名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @return \think\Validate
|
||||
*/
|
||||
function validate($name = '', $layer = 'validate', $appendSuffix = false)
|
||||
@@ -167,8 +166,8 @@ function validate($name = '', $layer = 'validate', $appendSuffix = false)
|
||||
|
||||
/**
|
||||
* 实例化数据库类
|
||||
* @param string $name 操作的数据表名称(不含前缀)
|
||||
* @param array|string $config 数据库配置参数
|
||||
* @param string $name 操作的数据表名称(不含前缀)
|
||||
* @param array|string $config 数据库配置参数
|
||||
* @return \think\db\Query
|
||||
*/
|
||||
function db($name = '', $config = [])
|
||||
@@ -178,9 +177,9 @@ function db($name = '', $config = [])
|
||||
|
||||
/**
|
||||
* 实例化控制器 格式:[模块/]控制器
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @return \think\Controller
|
||||
*/
|
||||
function controller($name, $layer = 'controller', $appendSuffix = false)
|
||||
@@ -190,10 +189,10 @@ function controller($name, $layer = 'controller', $appendSuffix = false)
|
||||
|
||||
/**
|
||||
* 调用模块的操作方法 参数格式 [模块/控制器/]操作
|
||||
* @param string $url 调用地址
|
||||
* @param string|array $vars 调用参数 支持字符串和数组
|
||||
* @param string $layer 要调用的控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $url 调用地址
|
||||
* @param string|array $vars 调用参数 支持字符串和数组
|
||||
* @param string $layer 要调用的控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @return mixed
|
||||
*/
|
||||
function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
|
||||
@@ -203,9 +202,9 @@ function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
|
||||
|
||||
/**
|
||||
* 导入所需的类库 同java的Import 本函数有缓存功能
|
||||
* @param string $class 类库命名空间字符串
|
||||
* @param string $baseUrl 起始路径
|
||||
* @param string $ext 导入的文件扩展名
|
||||
* @param string $class 类库命名空间字符串
|
||||
* @param string $baseUrl 起始路径
|
||||
* @param string $ext 导入的文件扩展名
|
||||
* @return boolean
|
||||
*/
|
||||
function import($class, $baseUrl = '', $ext = EXT)
|
||||
@@ -215,8 +214,8 @@ function import($class, $baseUrl = '', $ext = EXT)
|
||||
|
||||
/**
|
||||
* 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面
|
||||
* @param string $class 类库
|
||||
* @param string $ext 类库后缀
|
||||
* @param string $class 类库
|
||||
* @param string $ext 类库后缀
|
||||
* @return boolean
|
||||
*/
|
||||
function vendor($class, $ext = EXT)
|
||||
@@ -226,9 +225,9 @@ function vendor($class, $ext = EXT)
|
||||
|
||||
/**
|
||||
* 浏览器友好的变量输出
|
||||
* @param mixed $var 变量
|
||||
* @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串
|
||||
* @param string $label 标签 默认为空
|
||||
* @param mixed $var 变量
|
||||
* @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串
|
||||
* @param string $label 标签 默认为空
|
||||
* @return void|string
|
||||
*/
|
||||
function dump($var, $echo = true, $label = null)
|
||||
@@ -238,10 +237,10 @@ function dump($var, $echo = true, $label = null)
|
||||
|
||||
/**
|
||||
* Url生成
|
||||
* @param string $url 路由地址
|
||||
* @param string|array $value 变量
|
||||
* @param bool|string $suffix 前缀
|
||||
* @param bool|string $domain 域名
|
||||
* @param string $url 路由地址
|
||||
* @param string|array $value 变量
|
||||
* @param bool|string $suffix 前缀
|
||||
* @param bool|string $domain 域名
|
||||
* @return string
|
||||
*/
|
||||
function url($url = '', $vars = '', $suffix = true, $domain = false)
|
||||
@@ -251,9 +250,9 @@ function url($url = '', $vars = '', $suffix = true, $domain = false)
|
||||
|
||||
/**
|
||||
* Session管理
|
||||
* @param string|array $name session名称,如果为数组表示进行session设置
|
||||
* @param mixed $value session值
|
||||
* @param string $prefix 前缀
|
||||
* @param string|array $name session名称,如果为数组表示进行session设置
|
||||
* @param mixed $value session值
|
||||
* @param string $prefix 前缀
|
||||
* @return mixed
|
||||
*/
|
||||
function session($name, $value = '', $prefix = null)
|
||||
@@ -278,9 +277,9 @@ function session($name, $value = '', $prefix = null)
|
||||
|
||||
/**
|
||||
* Cookie管理
|
||||
* @param string|array $name cookie名称,如果为数组表示进行cookie设置
|
||||
* @param mixed $value cookie值
|
||||
* @param mixed $option 参数
|
||||
* @param string|array $name cookie名称,如果为数组表示进行cookie设置
|
||||
* @param mixed $value cookie值
|
||||
* @param mixed $option 参数
|
||||
* @return mixed
|
||||
*/
|
||||
function cookie($name, $value = '', $option = null)
|
||||
@@ -305,9 +304,9 @@ function cookie($name, $value = '', $option = null)
|
||||
|
||||
/**
|
||||
* 缓存管理
|
||||
* @param mixed $name 缓存名称,如果为数组表示进行缓存设置
|
||||
* @param mixed $value 缓存值
|
||||
* @param mixed $options 缓存参数
|
||||
* @param mixed $name 缓存名称,如果为数组表示进行缓存设置
|
||||
* @param mixed $value 缓存值
|
||||
* @param mixed $options 缓存参数
|
||||
* @return mixed
|
||||
*/
|
||||
function cache($name, $value = '', $options = null)
|
||||
@@ -338,8 +337,8 @@ function cache($name, $value = '', $options = null)
|
||||
|
||||
/**
|
||||
* 记录日志信息
|
||||
* @param mixed $log log信息 支持字符串和数组
|
||||
* @param string $level 日志级别
|
||||
* @param mixed $log log信息 支持字符串和数组
|
||||
* @param string $level 日志级别
|
||||
* @return void|array
|
||||
*/
|
||||
function trace($log = '[think]', $level = 'log')
|
||||
@@ -375,9 +374,9 @@ function response($data = [], $code = 200, $header = [], $type = 'html')
|
||||
|
||||
/**
|
||||
* 渲染模板输出
|
||||
* @param string $template 模板文件
|
||||
* @param array $vars 模板变量
|
||||
* @param integer $code 状态码
|
||||
* @param string $template 模板文件
|
||||
* @param array $vars 模板变量
|
||||
* @param integer $code 状态码
|
||||
* @return \think\response\View
|
||||
*/
|
||||
function view($template = '', $vars = [], $code = 200)
|
||||
@@ -426,9 +425,9 @@ function xml($data = [], $code = 200, $header = [], $options = [])
|
||||
|
||||
/**
|
||||
* 获取\think\response\Redirect对象实例
|
||||
* @param mixed $url 重定向地址 支持Url::build方法的地址
|
||||
* @param mixed $url 重定向地址 支持Url::build方法的地址
|
||||
* @param array|integer $params 额外参数
|
||||
* @param integer $code 状态码
|
||||
* @param integer $code 状态码
|
||||
* @return \think\response\Redirect
|
||||
*/
|
||||
function redirect($url = [], $params = [], $code = 302)
|
||||
@@ -442,9 +441,9 @@ function redirect($url = [], $params = [], $code = 302)
|
||||
|
||||
/**
|
||||
* 抛出HTTP异常
|
||||
* @param integer $code 状态码
|
||||
* @param string $message 错误信息
|
||||
* @param array $header 参数
|
||||
* @param integer $code 状态码
|
||||
* @param string $message 错误信息
|
||||
* @param array $header 参数
|
||||
*/
|
||||
function abort($code, $message = null, $header = [])
|
||||
{
|
||||
|
||||
@@ -41,29 +41,31 @@ class App
|
||||
|
||||
/**
|
||||
* @var bool 应用调试模式
|
||||
*/
|
||||
*/
|
||||
public static $debug = true;
|
||||
|
||||
/**
|
||||
* @var string 应用类库命名空间
|
||||
*/
|
||||
*/
|
||||
public static $namespace = 'app';
|
||||
|
||||
/**
|
||||
* @var bool 应用类库后缀
|
||||
*/
|
||||
*/
|
||||
public static $suffix = false;
|
||||
|
||||
/**
|
||||
* @var bool 应用路由检测
|
||||
*/
|
||||
*/
|
||||
protected static $routeCheck;
|
||||
|
||||
/**
|
||||
* @var bool 严格路由检测
|
||||
*/
|
||||
*/
|
||||
protected static $routeMust;
|
||||
|
||||
protected static $dispatch;
|
||||
|
||||
/**
|
||||
* 执行应用程序
|
||||
* @access public
|
||||
@@ -90,12 +92,14 @@ class App
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前请求的调度信息
|
||||
$dispatch = $request->dispatch();
|
||||
// 获取应用调度信息
|
||||
$dispatch = self::$dispatch;
|
||||
if (empty($dispatch)) {
|
||||
// 未指定调度类型 则进行URL路由检测
|
||||
// 进行URL路由检测
|
||||
$dispatch = self::routeCheck($request, $config);
|
||||
}
|
||||
// 记录当前调度信息
|
||||
$request->dispatch($dispatch);
|
||||
// 记录路由信息
|
||||
self::$debug && Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');
|
||||
// 监听app_begin
|
||||
@@ -108,7 +112,7 @@ class App
|
||||
break;
|
||||
case 'module':
|
||||
// 模块/控制器/操作
|
||||
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null );
|
||||
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
|
||||
break;
|
||||
case 'controller':
|
||||
// 执行控制器操作
|
||||
@@ -136,11 +140,11 @@ class App
|
||||
Hook::listen('app_end', $data);
|
||||
// 清空类的实例化
|
||||
Loader::clearInstance();
|
||||
|
||||
|
||||
// 输出数据到客户端
|
||||
if ($data instanceof Response) {
|
||||
return $data;
|
||||
} elseif(!is_null($data)) {
|
||||
} elseif (!is_null($data)) {
|
||||
// 默认自动识别响应输出类型
|
||||
$isAjax = $request->isAjax();
|
||||
$type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
|
||||
@@ -150,6 +154,19 @@ class App
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前请求的调度信息
|
||||
* @access public
|
||||
* @param array|string $dispatch 调度信息
|
||||
* @param string $type 调度类型
|
||||
* @param array $params 参数
|
||||
* @return void
|
||||
*/
|
||||
public static function dispatch($dispath, $type = 'module', $params = [])
|
||||
{
|
||||
self::$dispatch = ['type' => $type, $type => $dispatch, 'params' => $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行函数或者闭包方法 支持参数调用
|
||||
* @access public
|
||||
@@ -222,7 +239,7 @@ class App
|
||||
}
|
||||
}
|
||||
// 全局过滤
|
||||
array_walk_recursive($args, [Request::instance(),'filterExp']);
|
||||
array_walk_recursive($args, [Request::instance(), 'filterExp']);
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
@@ -240,10 +257,11 @@ class App
|
||||
if (is_string($result)) {
|
||||
$result = explode('/', $result);
|
||||
}
|
||||
$request = Request::instance();
|
||||
if ($config['app_multi_module']) {
|
||||
// 多模块部署
|
||||
$module = strip_tags(strtolower($result[0] ?: $config['default_module']));
|
||||
$bind = Route::bind('module');
|
||||
$bind = Route::getBind('module');
|
||||
$available = false;
|
||||
if ($bind) {
|
||||
// 绑定模块
|
||||
@@ -258,6 +276,7 @@ class App
|
||||
// 模块初始化
|
||||
if ($module && $available) {
|
||||
// 初始化模块
|
||||
$request->module($module);
|
||||
$config = self::init($module);
|
||||
} else {
|
||||
throw new HttpException(404, 'module not exists:' . $module);
|
||||
@@ -265,12 +284,13 @@ class App
|
||||
} else {
|
||||
// 单一模块部署
|
||||
$module = '';
|
||||
$request->module($module);
|
||||
}
|
||||
// 当前模块路径
|
||||
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 = $convert ? strtolower($controller) : $controller;
|
||||
@@ -279,15 +299,8 @@ class App
|
||||
$actionName = strip_tags($result[2] ?: $config['default_action']);
|
||||
$actionName = $convert ? strtolower($actionName) : $actionName;
|
||||
|
||||
// 执行操作
|
||||
if (!preg_match('/^[A-Za-z](\/|\.|\w)*$/', $controller)) {
|
||||
// 安全检测
|
||||
throw new \InvalidArgumentException('illegal controller name:' . $controller);
|
||||
}
|
||||
|
||||
// 设置当前请求的模块、控制器、操作
|
||||
$request = Request::instance();
|
||||
$request->module($module)->controller($controller)->action($actionName);
|
||||
// 设置当前请求的控制器、操作
|
||||
$request->controller($controller)->action($actionName);
|
||||
|
||||
// 监听module_init
|
||||
Hook::listen('module_init', $request);
|
||||
@@ -327,17 +340,17 @@ class App
|
||||
{
|
||||
if (empty(self::$init)) {
|
||||
// 初始化应用
|
||||
$config = self::init();
|
||||
self::$suffix = $config['class_suffix'];
|
||||
|
||||
$config = self::init();
|
||||
self::$suffix = $config['class_suffix'];
|
||||
|
||||
// 应用调试模式
|
||||
self::$debug = Config::get('app_debug');
|
||||
self::$debug = Config::get('app_debug');
|
||||
if (!self::$debug) {
|
||||
ini_set('display_errors', 'Off');
|
||||
}
|
||||
|
||||
|
||||
// 应用命名空间
|
||||
self::$namespace = $config['app_namespace'];
|
||||
self::$namespace = $config['app_namespace'];
|
||||
Loader::addNamespace($config['app_namespace'], APP_PATH);
|
||||
if (!empty($config['root_namespace'])) {
|
||||
Loader::addNamespace($config['root_namespace']);
|
||||
@@ -364,7 +377,6 @@ class App
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化应用或模块
|
||||
* @access public
|
||||
@@ -399,7 +411,7 @@ class App
|
||||
|
||||
// 加载别名文件
|
||||
if (is_file(CONF_PATH . $module . 'alias' . EXT)) {
|
||||
Loader::addMap(include CONF_PATH . $module . 'alias' . EXT);
|
||||
Loader::addClassMap(include CONF_PATH . $module . 'alias' . EXT);
|
||||
}
|
||||
|
||||
// 加载行为扩展文件
|
||||
@@ -432,14 +444,14 @@ class App
|
||||
{
|
||||
// 检测URL禁用后缀
|
||||
if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', $request->pathinfo())) {
|
||||
throw new Exception('url suffix deny:'.$request->ext());
|
||||
throw new Exception('url suffix deny:' . $request->ext());
|
||||
}
|
||||
|
||||
$path = $request->path();
|
||||
$depr = $config['pathinfo_depr'];
|
||||
$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 (!empty($config['route'])) {
|
||||
@@ -456,11 +468,9 @@ class App
|
||||
}
|
||||
if (false === $result) {
|
||||
// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
|
||||
$result = Route::parseUrl($path, $depr, $config['controller_auto_search'], $config['url_param_type']);
|
||||
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
|
||||
}
|
||||
|
||||
// 注册调度机制
|
||||
return $request->dispatch($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,7 +102,7 @@ class Lang
|
||||
public static function has($name, $range = '')
|
||||
{
|
||||
$range = $range ?: self::$range;
|
||||
return isset(self::$lang[$range][strtolower($name)]);
|
||||
return isset(self::$lang[$range][strtolower($name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,7 +169,7 @@ class Lang
|
||||
}
|
||||
if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) {
|
||||
// 合法的语言
|
||||
self::$range = $langSet;
|
||||
self::$range = $langSet ?: self::$range;
|
||||
}
|
||||
return self::$range;
|
||||
}
|
||||
|
||||
@@ -59,34 +59,38 @@ class Loader
|
||||
if (!strpos($class, '\\')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 解析命名空间
|
||||
list($name, $class) = explode('\\', $class, 2);
|
||||
if (isset(self::$namespace[$name])) {
|
||||
// 根命名空间
|
||||
$path = self::$namespace[$name];
|
||||
} elseif (is_dir(EXTEND_PATH . $name)) {
|
||||
$item = explode('\\', $class);
|
||||
// 解析命名空间所在的路径
|
||||
if (count($item) > 2 && isset(self::$namespace[$item[0] . '\\' . $item[1]])) {
|
||||
// 子命名空间定义(仅支持二级)
|
||||
list($ns1, $ns2, $class) = explode('\\', $class, 3);
|
||||
$path = self::$namespace[$ns1 . '\\' . $ns2];
|
||||
} elseif (isset(self::$namespace[$item[0]])) {
|
||||
// 根命名空间定义
|
||||
list($name, $class) = explode('\\', $class, 2);
|
||||
$path = self::$namespace[$name];
|
||||
} elseif (is_dir(EXTEND_PATH . $item[0])) {
|
||||
// 扩展类库命名空间
|
||||
$path = EXTEND_PATH . $name . DS;
|
||||
list($name, $class) = explode('\\', $class, 2);
|
||||
$path = EXTEND_PATH . $name . DS;
|
||||
} else {
|
||||
// 非根命名空间检测
|
||||
foreach (self::$namespace as $ns => $val) {
|
||||
if (strpos($ns, '\\') && 0 === strpos($name . '\\' . $class, $ns)) {
|
||||
$path = $val;
|
||||
$class = substr($name . $class, strlen($ns));
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
// 定位文件
|
||||
$match = false;
|
||||
foreach ((array) $path as $p) {
|
||||
$filename = $p . str_replace('\\', DS, $class) . EXT;
|
||||
if (is_file($filename)) {
|
||||
// Win环境严格区分大小写
|
||||
if (IS_WIN && false === strpos(realpath($filename), $class . EXT)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!isset($path)) {
|
||||
return false;
|
||||
$match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$filename = $path . str_replace('\\', DS, $class) . EXT;
|
||||
if (is_file($filename)) {
|
||||
// 开启调试模式Win环境严格区分大小写
|
||||
if (IS_WIN && false === strpos(realpath($filename), $class . EXT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($match) {
|
||||
include $filename;
|
||||
} else {
|
||||
return false;
|
||||
@@ -96,7 +100,7 @@ class Loader
|
||||
}
|
||||
|
||||
// 注册classmap
|
||||
public static function addMap($class, $map = '')
|
||||
public static function addClassMap($class, $map = '')
|
||||
{
|
||||
if (is_array($class)) {
|
||||
self::$map = array_merge(self::$map, $class);
|
||||
@@ -119,7 +123,7 @@ class Loader
|
||||
public static function addNamespaceAlias($namespace, $original = '')
|
||||
{
|
||||
if (is_array($namespace)) {
|
||||
self::$namespaceAlias = array_merge(self::$namespace, $namespace);
|
||||
self::$namespaceAlias = array_merge(self::$namespaceAlias, $namespace);
|
||||
} else {
|
||||
self::$namespaceAlias[$namespace] = $original;
|
||||
}
|
||||
@@ -130,83 +134,33 @@ class Loader
|
||||
{
|
||||
// 注册系统自动加载
|
||||
spl_autoload_register($autoload ?: 'think\\Loader::autoload');
|
||||
// 注册命名空间定义
|
||||
self::addNamespace([
|
||||
'think' => LIB_PATH . 'think' . DS,
|
||||
'behavior' => LIB_PATH . 'behavior' . DS,
|
||||
'traits' => LIB_PATH . 'traits' . DS,
|
||||
]);
|
||||
// 加载类库映射文件
|
||||
self::addClassMap(include THINK_PATH . 'classmap' . EXT);
|
||||
|
||||
// Composer自动加载支持
|
||||
if (is_dir(VENDOR_PATH . 'composer')) {
|
||||
// 注册Composer自动加载
|
||||
self::registerComposerLoader();
|
||||
self::$composerLoader = true;
|
||||
self::registerComposerLoader();
|
||||
} elseif (is_file(VENDOR_PATH . 'think_autoload.php')) {
|
||||
// 读取Composer自动加载文件
|
||||
$autoload = include VENDOR_PATH . 'think_autoload.php';
|
||||
if (is_array($autoload)) {
|
||||
self::addMap($autoload);
|
||||
}
|
||||
} elseif (AUTO_SCAN_PACKAGE) {
|
||||
if (is_file(RUNTIME_PATH . 'class_namespace.php')) {
|
||||
self::addNamespace(include RUNTIME_PATH . 'class_namespace.php');
|
||||
if (is_file(RUNTIME_PATH . 'load_files.php')) {
|
||||
$files = include RUNTIME_PATH . 'load_files.php';
|
||||
foreach ($files as $file) {
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
} elseif (is_dir(VENDOR_PATH)) {
|
||||
self::scanComposerPackage(VENDOR_PATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 扫描composer package
|
||||
private static function scanComposerPackage($path)
|
||||
{
|
||||
// 自动扫描下载Composer安装类库
|
||||
$dirs = scandir($path, 1);
|
||||
$namespace = [];
|
||||
foreach ($dirs as $dir) {
|
||||
if ('.' != $dir && '..' != $dir && is_file($path . $dir . DS . 'composer.json')) {
|
||||
// 解析 package的composer.json 文件
|
||||
$namespace = array_merge($namespace, self::parseComposerPackage($path . $dir . DS));
|
||||
}
|
||||
}
|
||||
if (!empty($namespace)) {
|
||||
self::addNamespace($namespace);
|
||||
// 生成缓存
|
||||
file_put_contents(RUNTIME_PATH . 'class_namespace.php', "<?php\nreturn " . var_export($namespace, true) . ';');
|
||||
}
|
||||
if (!empty(self::$load)) {
|
||||
// 生成缓存
|
||||
file_put_contents(RUNTIME_PATH . 'load_files.php', "<?php\nreturn " . var_export(self::$load, true) . ';');
|
||||
}
|
||||
}
|
||||
|
||||
// 解析Composer Package
|
||||
private static function parseComposerPackage($package)
|
||||
{
|
||||
$content = file_get_contents($package . 'composer.json');
|
||||
$result = json_decode($content, true);
|
||||
$namespace = [];
|
||||
if (!empty($result['autoload'])) {
|
||||
$autoload = $result['autoload'];
|
||||
if (isset($autoload['psr-0'])) {
|
||||
foreach ($autoload['psr-0'] as $ns => $path) {
|
||||
$namespace[rtrim($ns, '\\')] = realpath($package . $path . DS . str_replace('\\', DS, $ns)) . DS;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($autoload['psr-4'])) {
|
||||
foreach ($autoload['psr-4'] as $ns => $path) {
|
||||
$namespace[rtrim($ns, '\\')] = realpath($package . $path) . DS;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($autoload['files'])) {
|
||||
// 命名空间和类库映射注册
|
||||
self::addNamespace($autoload['namespace']);
|
||||
self::addClassMap($autoload['classmap']);
|
||||
// 载入composer包的文件列表
|
||||
foreach ($autoload['files'] as $file) {
|
||||
self::$load[] = realpath($package . $file);
|
||||
require $package . $file;
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
// 注册composer自动加载
|
||||
@@ -234,7 +188,7 @@ class Loader
|
||||
if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {
|
||||
$classMap = require VENDOR_PATH . 'composer/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
self::addMap($classMap);
|
||||
self::addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,10 +164,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
/**
|
||||
* 获取关联模型实例
|
||||
* @access protected
|
||||
* @return Relation
|
||||
* @param string|array $relation 关联查询
|
||||
* @return Relation|Query
|
||||
*/
|
||||
protected function relation()
|
||||
protected function relation($relation = null)
|
||||
{
|
||||
if (!is_null($relation)) {
|
||||
// 执行关联查询
|
||||
return $this->db->relation($relation);
|
||||
}
|
||||
|
||||
// 获取关联对象实例
|
||||
if (is_null($this->relation)) {
|
||||
$this->relation = new Relation($this);
|
||||
}
|
||||
@@ -250,11 +257,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
switch ($type) {
|
||||
case 'timestamp':
|
||||
case 'datetime':
|
||||
$format = !empty($param) ? $param : $this->dateFormat;
|
||||
$value = date($format, $_SERVER['REQUEST_TIME']);
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$value = $_SERVER['REQUEST_TIME'];
|
||||
break;
|
||||
}
|
||||
@@ -549,6 +556,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
|
||||
// 检测字段
|
||||
if (!empty($this->field)) {
|
||||
if (true === $this->field) {
|
||||
$this->field = $this->db->getTableInfo('', 'fields');
|
||||
}
|
||||
foreach ($this->data as $key => $val) {
|
||||
if (!in_array($key, $this->field)) {
|
||||
unset($this->data[$key]);
|
||||
@@ -666,7 +676,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
/**
|
||||
* 设置允许写入的字段
|
||||
* @access public
|
||||
* @param bool $update
|
||||
* @param bool|array $field 允许写入的字段 如果为true只允许写入数据表字段
|
||||
* @return $this
|
||||
*/
|
||||
public function allowField($field)
|
||||
@@ -971,25 +981,27 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
* 命名范围
|
||||
* @access public
|
||||
* @param string|array|Closure $name 命名范围名称 逗号分隔
|
||||
* @param mixed $params 参数调用
|
||||
* @param mixed ...$params 参数调用
|
||||
* @return Model
|
||||
*/
|
||||
public static function scope($name, $params = [])
|
||||
public static function scope($name)
|
||||
{
|
||||
$model = new static();
|
||||
$query = $model->db();
|
||||
if ($name instanceof \Closure) {
|
||||
call_user_func_array($name, [ & $query, $params]);
|
||||
} elseif ($name instanceof Query) {
|
||||
if ($name instanceof Query) {
|
||||
return $name;
|
||||
} else {
|
||||
if (is_string($name)) {
|
||||
$names = explode(',', $name);
|
||||
}
|
||||
foreach ($names as $scope) {
|
||||
}
|
||||
$model = new static();
|
||||
$params = func_get_args();
|
||||
$params[0] = $model->db();
|
||||
if ($name instanceof \Closure) {
|
||||
call_user_func_array($name, $params);
|
||||
} elseif (is_string($name)) {
|
||||
$name = explode(',', $name);
|
||||
}
|
||||
if (is_array($name)) {
|
||||
foreach ($name as $scope) {
|
||||
$method = 'scope' . trim($scope);
|
||||
if (method_exists($model, $method)) {
|
||||
$model->$method($query, $params);
|
||||
call_user_func_array([$model, $method], $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ class Request
|
||||
'csv' => 'text/csv',
|
||||
];
|
||||
|
||||
protected $content;
|
||||
|
||||
// 全局过滤规则
|
||||
protected $filter;
|
||||
// Hook扩展方法
|
||||
@@ -126,6 +128,7 @@ class Request
|
||||
$this->$name = $item;
|
||||
}
|
||||
}
|
||||
$this->filter = Config::get('default_filter');
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
@@ -177,9 +180,10 @@ class Request
|
||||
* @param array $cookie
|
||||
* @param array $files
|
||||
* @param array $server
|
||||
* @param string $content
|
||||
* @return \think\Request
|
||||
*/
|
||||
public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [])
|
||||
public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null)
|
||||
{
|
||||
$server['PATH_INFO'] = '';
|
||||
$server['REQUEST_METHOD'] = strtoupper($method);
|
||||
@@ -235,6 +239,7 @@ class Request
|
||||
$options['pathinfo'] = ltrim($info['path'], '/');
|
||||
$options['method'] = $server['REQUEST_METHOD'];
|
||||
$options['domain'] = $server['HTTP_HOST'];
|
||||
$options['content'] = $content;
|
||||
self::$instance = new self($options);
|
||||
return self::$instance;
|
||||
}
|
||||
@@ -983,7 +988,7 @@ class Request
|
||||
$value = $default;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
} elseif (!empty($filter)) {
|
||||
// filter函数不存在时, 则使用filter_var进行过滤
|
||||
// filter为非整形值时, 调用filter_id取得过滤id
|
||||
$value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));
|
||||
@@ -1289,14 +1294,14 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的调度信息
|
||||
* 设置或者获取当前请求的调度信息
|
||||
* @access public
|
||||
* @param array $dispatch 调度信息
|
||||
* @param array $dispatch 调度信息
|
||||
* @return array
|
||||
*/
|
||||
public function dispatch($dispatch = [])
|
||||
public function dispatch($dispatch = null)
|
||||
{
|
||||
if (!empty($dispatch)) {
|
||||
if (!is_null($dispatch)) {
|
||||
$this->dispatch = $dispatch;
|
||||
}
|
||||
return $this->dispatch;
|
||||
@@ -1366,4 +1371,16 @@ class Request
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置或者获取当前请求的content
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if (is_null($this->content)) {
|
||||
$this->content = file_get_contents('php://input');
|
||||
}
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,19 +123,26 @@ class Route
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置和读取路由绑定
|
||||
* 设置路由绑定
|
||||
* @access public
|
||||
* @param string $type 请求类型
|
||||
* @param mixed $bind 绑定信息
|
||||
* @param string $type 绑定类型 默认为module
|
||||
* @return mixed
|
||||
*/
|
||||
public static function bind($type, $bind = '')
|
||||
public static function bind($bind, $type = 'module')
|
||||
{
|
||||
if ('' == $bind) {
|
||||
return isset(self::$bind[$type]) ? self::$bind[$type] : null;
|
||||
} else {
|
||||
self::$bind = ['type' => $type, $type => $bind];
|
||||
}
|
||||
self::$bind = ['type' => $type, $type => $bind];
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取路由绑定
|
||||
* @access public
|
||||
* @param string $type 绑定类型
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getBind($type)
|
||||
{
|
||||
return isset(self::$bind[$type]) ? self::$bind[$type] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,8 +217,8 @@ class Route
|
||||
*/
|
||||
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [], $group = '')
|
||||
{
|
||||
$group = $group ?: self::$group;
|
||||
$type = strtoupper($type);
|
||||
$group = $group ?: self::$group;
|
||||
$type = strtoupper($type);
|
||||
if (strpos($type, '|')) {
|
||||
foreach (explode('|', $type) as $val) {
|
||||
self::rule($rule, $route, $val, $option, $pattern, $group);
|
||||
@@ -497,11 +504,12 @@ class Route
|
||||
* @param string $route 路由地址
|
||||
* @param string $method 请求类型
|
||||
* @param array $option 路由参数
|
||||
* @param string $group 路由分组
|
||||
* @return void
|
||||
*/
|
||||
public static function miss($route, $method = '*', $option = [])
|
||||
public static function miss($route, $method = '*', $option = [], $group = '')
|
||||
{
|
||||
self::rule('__miss__', $route, $method, $option, []);
|
||||
self::rule('__miss__', $route, $method, $option, [], $group);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,7 +530,7 @@ class Route
|
||||
/**
|
||||
* 检测子域名部署
|
||||
* @access public
|
||||
* @param Request $request Request请求对象
|
||||
* @param Request $request Request请求对象
|
||||
* @return void
|
||||
*/
|
||||
public static function checkDomain($request)
|
||||
@@ -648,13 +656,13 @@ class Route
|
||||
// 路由不匹配
|
||||
} elseif (0 === strpos($rule, '\\')) {
|
||||
// 路由到类
|
||||
return self::bindToClass($array[1], substr($rule, 1));
|
||||
return self::bindToClass($array[1], substr($rule, 1), $depr);
|
||||
} elseif (0 === strpos($url, '@')) {
|
||||
// 路由到控制器类
|
||||
return self::bindToController($array[1], substr($rule, 1));
|
||||
return self::bindToController($array[1], substr($rule, 1), $depr);
|
||||
} else {
|
||||
// 路由到模块/控制器
|
||||
return self::bindToModule($array[1], $rule);
|
||||
return self::bindToModule($array[1], $rule, $depr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,18 +679,13 @@ class Route
|
||||
self::checkDomain($request);
|
||||
}
|
||||
// 检测URL绑定
|
||||
$return = self::checkUrlBind($url, $rules);
|
||||
$return = self::checkUrlBind($url, $rules, $depr);
|
||||
if ($return) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
// 路由规则检测
|
||||
if (!empty($rules)) {
|
||||
if (isset($rules['__miss__'])) {
|
||||
// 指定未匹配路由的处理
|
||||
$miss = $rules['__miss__'];
|
||||
unset($rules['__miss__']);
|
||||
}
|
||||
foreach ($rules as $rule => $val) {
|
||||
$option = isset($val['option']) ? $val['option'] : [];
|
||||
$pattern = isset($val['pattern']) ? $val['pattern'] : [];
|
||||
@@ -691,7 +694,11 @@ class Route
|
||||
if (!self::checkOption($option, $url, $request)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('__miss__' == $rule) {
|
||||
// 指定分组MISS路由
|
||||
$miss = $val['route'];
|
||||
continue;
|
||||
}
|
||||
if (!empty($val['routes'])) {
|
||||
// 分组路由
|
||||
if (($pos = strpos($rule, ':')) || ($pos = strpos($rule, '<'))) {
|
||||
@@ -702,13 +709,12 @@ class Route
|
||||
if (0 !== strpos($url, $str)) {
|
||||
continue;
|
||||
}
|
||||
$missGroup = false;
|
||||
// 匹配到路由分组
|
||||
foreach ($val['routes'] as $key => $route) {
|
||||
if (is_numeric($key)) {
|
||||
$key = array_shift($route);
|
||||
}
|
||||
|
||||
$key = $rule . ($key ? '/' . ltrim($key, '/') : '');
|
||||
// 检查规则路由
|
||||
if (is_array($route)) {
|
||||
$option1 = $route[1];
|
||||
@@ -720,12 +726,27 @@ class Route
|
||||
$route = $route[0];
|
||||
$option = array_merge($option, $option1);
|
||||
}
|
||||
if ('__miss__' == $key) {
|
||||
// 指定分组MISS路由
|
||||
$missGroup = $route;
|
||||
continue;
|
||||
}
|
||||
$key = $rule . ($key ? '/' . ltrim($key, '/') : '');
|
||||
$result = self::checkRule($key, $route, $url, $pattern, $option);
|
||||
if (false !== $result) {
|
||||
$request->route(['rule' => $key, 'route' => $route, 'pattern' => $pattern, 'option' => $option]);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if ($missGroup) {
|
||||
// 未匹配所有路由的路由规则处理
|
||||
if ($missGroup instanceof \Closure) {
|
||||
// 执行闭包
|
||||
return ['type' => 'function', 'function' => $missGroup, 'params' => []];
|
||||
} else {
|
||||
return self::parseRule('', $missGroup, $url, []);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_numeric($rule)) {
|
||||
$rule = array_shift($val);
|
||||
@@ -742,11 +763,11 @@ class Route
|
||||
}
|
||||
if (isset($miss)) {
|
||||
// 未匹配所有路由的路由规则处理
|
||||
if ($miss['route'] instanceof \Closure) {
|
||||
if ($miss instanceof \Closure) {
|
||||
// 执行闭包
|
||||
return ['type' => 'function', 'function' => $miss['route'], 'params' => []];
|
||||
} elseif (self::checkOption($miss['option'], $url, $request)) {
|
||||
return self::parseRule('', $miss['route'], $url, []);
|
||||
return ['type' => 'function', 'function' => $miss, 'params' => []];
|
||||
} else {
|
||||
return self::parseRule('', $miss, $url, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,9 +779,10 @@ class Route
|
||||
* @access private
|
||||
* @param string $url URL地址
|
||||
* @param array $rules 路由规则
|
||||
* @param string $depr URL分隔符
|
||||
* @return false
|
||||
*/
|
||||
private static function checkUrlBind(&$url, &$rules)
|
||||
private static function checkUrlBind(&$url, &$rules, $depr = '/')
|
||||
{
|
||||
if (!empty(self::$bind['type'])) {
|
||||
// 记录绑定信息
|
||||
@@ -769,10 +791,10 @@ class Route
|
||||
switch (self::$bind['type']) {
|
||||
case 'class':
|
||||
// 绑定到类
|
||||
return self::bindToClass($url, self::$bind['class']);
|
||||
return self::bindToClass($url, self::$bind['class'], $depr);
|
||||
case 'namespace':
|
||||
// 绑定到命名空间
|
||||
return self::bindToNamespace($url, self::$bind['namespace']);
|
||||
return self::bindToNamespace($url, self::$bind['namespace'], $depr);
|
||||
case 'module':
|
||||
// 如果有模块/控制器绑定 针对路由到 模块/控制器 有效
|
||||
$url = self::$bind['module'] . '/' . $url;
|
||||
@@ -793,15 +815,17 @@ class Route
|
||||
* @access public
|
||||
* @param string $url URL地址
|
||||
* @param string $class 类名(带命名空间)
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToClass($url, $class)
|
||||
public static function bindToClass($url, $class, $depr = '/')
|
||||
{
|
||||
$array = explode('/', $url, 2);
|
||||
$array = explode($depr, $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
|
||||
if (!empty($array[1])) {
|
||||
self::parseUrlParams($array[1]);
|
||||
}
|
||||
return ['type' => 'method', 'method' => [$class, $array[0] ?: Config::get('default_action')], 'params' => []];
|
||||
return ['type' => 'method', 'method' => [$class, $action], 'params' => []];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -809,11 +833,12 @@ class Route
|
||||
* @access public
|
||||
* @param string $url URL地址
|
||||
* @param string $namespace 命名空间
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToNamespace($url, $namespace)
|
||||
public static function bindToNamespace($url, $namespace, $depr = '/')
|
||||
{
|
||||
$array = explode('/', $url, 3);
|
||||
$array = explode($depr, $url, 3);
|
||||
$class = !empty($array[0]) ? $array[0] : Config::get('default_controller');
|
||||
$method = !empty($array[1]) ? $array[1] : Config::get('default_action');
|
||||
if (!empty($array[2])) {
|
||||
@@ -822,21 +847,43 @@ class Route
|
||||
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method], 'params' => []];
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到应用 直接进行控制器类库访问
|
||||
* @access public
|
||||
* @param string $url URL地址
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToApp($url, $depr = '/')
|
||||
{
|
||||
$array = explode($depr, $url, 4);
|
||||
$module = !empty($array[0]) ? $array[0] : Config::get('default_module');
|
||||
$controller = !empty($array[1]) ? $array[1] : Config::get('default_controller');
|
||||
$method = !empty($array[2]) ? $array[2] : Config::get('default_action');
|
||||
$layer = Config::get('url_controller_layer');
|
||||
$class = App::$namespace . '\\' . $module . '\\' . $layer . '\\' . $controller;
|
||||
if (!empty($array[3])) {
|
||||
self::parseUrlParams($array[3]);
|
||||
}
|
||||
return ['type' => 'method', 'method' => [$class, $method], 'params' => []];
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到控制器类
|
||||
* @access public
|
||||
* @param string $url URL地址
|
||||
* @param string $module 模块名
|
||||
* @param string $controller 控制器名 (支持带模块名 index/user )
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToController($url, $controller)
|
||||
public static function bindToController($url, $controller, $depr = '/')
|
||||
{
|
||||
$array = explode('/', $url, 2);
|
||||
$array = explode($depr, $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
|
||||
if (!empty($array[1])) {
|
||||
self::parseUrlParams($array[1]);
|
||||
}
|
||||
return ['type' => 'method', 'method' => [$controller, $action], 'params' => []];
|
||||
return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'params' => []];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -844,11 +891,12 @@ class Route
|
||||
* @access public
|
||||
* @param string $url URL地址
|
||||
* @param string $class 控制器类名(带命名空间)
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToModule($url, $controller)
|
||||
public static function bindToModule($url, $controller, $depr = '/')
|
||||
{
|
||||
$array = explode('/', $url, 2);
|
||||
$array = explode($depr, $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
|
||||
if (!empty($array[1])) {
|
||||
self::parseUrlParams($array[1]);
|
||||
@@ -883,8 +931,8 @@ class Route
|
||||
* 检测路由规则
|
||||
* @access private
|
||||
* @param string $rule 路由规则
|
||||
* @param string $url URL地址
|
||||
* @param string $route 路由地址
|
||||
* @param string $url URL地址
|
||||
* @param array $pattern 变量规则
|
||||
* @param array $option 路由参数
|
||||
* @return array|false
|
||||
@@ -910,7 +958,7 @@ class Route
|
||||
if ($len1 >= $len2 || strpos($rule, '[')) {
|
||||
if ('$' == substr($rule, -1, 1)) {
|
||||
// 完整匹配
|
||||
if (!$merge && $len1 != $len2 && false === strpos($rule, '[')) {
|
||||
if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) {
|
||||
return false;
|
||||
} else {
|
||||
$rule = substr($rule, 0, -1);
|
||||
@@ -924,12 +972,12 @@ class Route
|
||||
if ($option['after_behavior'] instanceof \Closure) {
|
||||
$result = call_user_func_array($option['after_behavior'], [$route]);
|
||||
} else {
|
||||
foreach((array)$option['after_behavior'] as $behavior){
|
||||
foreach ((array) $option['after_behavior'] as $behavior) {
|
||||
$result = Hook::exec($behavior, '', $route);
|
||||
if (!is_null($result)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 路由规则重定向
|
||||
if ($result instanceof Response) {
|
||||
@@ -954,10 +1002,9 @@ class Route
|
||||
* @param string $url URL地址
|
||||
* @param string $depr URL分隔符
|
||||
* @param bool $autoSearch 是否自动深度搜索控制器
|
||||
* @param integer $paramType URL参数解析方式 0 名称解析 1 顺序解析
|
||||
* @return array
|
||||
*/
|
||||
public static function parseUrl($url, $depr = '/', $autoSearch = false, $paramType = 0)
|
||||
public static function parseUrl($url, $depr = '/', $autoSearch = false)
|
||||
{
|
||||
if (isset(self::$bind['module'])) {
|
||||
// 如果有模块/控制器绑定
|
||||
@@ -968,24 +1015,46 @@ class Route
|
||||
$url = str_replace($depr, '/', $url);
|
||||
}
|
||||
|
||||
$result = self::parseRoute($url, $autoSearch, true, $paramType);
|
||||
|
||||
if (!empty($result['var'])) {
|
||||
$_GET = array_merge($result['var'], $_GET);
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
$route = [null, null, null];
|
||||
if (isset($path)) {
|
||||
// 解析模块
|
||||
$module = Config::get('app_multi_module') ? array_shift($path) : null;
|
||||
if ($autoSearch) {
|
||||
// 自动搜索控制器
|
||||
$dir = APP_PATH . ($module ? $module . DS : '') . 'controller';
|
||||
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||
$item = [];
|
||||
foreach ($path as $val) {
|
||||
$item[] = array_shift($path);
|
||||
if (is_file($dir . DS . $val . $suffix . EXT)) {
|
||||
break;
|
||||
} else {
|
||||
$dir .= DS . $val;
|
||||
}
|
||||
}
|
||||
$controller = implode('.', $item);
|
||||
} else {
|
||||
// 解析控制器
|
||||
$controller = !empty($path) ? array_shift($path) : null;
|
||||
}
|
||||
// 解析操作
|
||||
$action = !empty($path) ? array_shift($path) : null;
|
||||
// 解析额外参数
|
||||
self::parseUrlParams(empty($path) ? '' : implode('/', $path));
|
||||
// 封装路由
|
||||
$route = [$module, $controller, $action];
|
||||
}
|
||||
return ['type' => 'module', 'module' => $result['route']];
|
||||
return ['type' => 'module', 'module' => $route];
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析规范的路由地址 地址格式 [模块/控制器/操作?]参数1=值1&参数2=值2...
|
||||
* 解析URL的pathinfo参数和变量
|
||||
* @access private
|
||||
* @param string $url URL地址
|
||||
* @param bool $autoSearch 是否自动深度搜索控制器
|
||||
* @param bool $reverse 是否反转解析URL
|
||||
* @param integer $paramType URL参数解析方式 0 名称解析 1 顺序解析
|
||||
* @return array
|
||||
*/
|
||||
private static function parseRoute($url, $autoSearch = false, $reverse = false, $paramType = 0)
|
||||
private static function parseUrlPath($url)
|
||||
{
|
||||
$url = trim($url, '/');
|
||||
$var = [];
|
||||
@@ -1003,58 +1072,7 @@ class Route
|
||||
} else {
|
||||
$path = [$url];
|
||||
}
|
||||
$route = [null, null, null];
|
||||
if (isset($path)) {
|
||||
if ($reverse) {
|
||||
// 解析模块
|
||||
$module = Config::get('app_multi_module') ? array_shift($path) : null;
|
||||
if ($autoSearch) {
|
||||
// 自动搜索控制器
|
||||
$dir = APP_PATH . ($module ? $module . DS : '') . 'controller';
|
||||
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||
$item = [];
|
||||
foreach ($path as $val) {
|
||||
$item[] = array_shift($path);
|
||||
if (is_file($dir . DS . $val . $suffix . EXT)) {
|
||||
break;
|
||||
} else {
|
||||
$dir .= DS . $val;
|
||||
}
|
||||
}
|
||||
$controller = implode('.', $item);
|
||||
} else {
|
||||
// 解析控制器
|
||||
$controller = !empty($path) ? array_shift($path) : null;
|
||||
}
|
||||
// 解析操作
|
||||
$action = !empty($path) ? array_shift($path) : null;
|
||||
// 解析额外参数
|
||||
if (!empty($path)) {
|
||||
if ($paramType) {
|
||||
$var += $path;
|
||||
} else {
|
||||
preg_replace_callback('/([^\/]+)\/([^\/]+)/', function ($match) use (&$var) {
|
||||
$var[strtolower($match[1])] = strip_tags($match[2]);
|
||||
}, implode('/', $path));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$action = array_pop($path);
|
||||
$controller = !empty($path) ? array_pop($path) : null;
|
||||
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
|
||||
$method = Request::instance()->method();
|
||||
// REST 操作方法支持
|
||||
if ('[rest]' == $action) {
|
||||
$action = $method;
|
||||
} elseif (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
|
||||
// 操作方法前缀支持
|
||||
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
|
||||
}
|
||||
}
|
||||
// 封装路由
|
||||
$route = [$module, $controller, $action];
|
||||
}
|
||||
return ['route' => $route, 'var' => $var];
|
||||
return [$path, $var];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,14 +1184,22 @@ class Route
|
||||
// 路由到控制器
|
||||
$result = ['type' => 'controller', 'controller' => substr($url, 1), 'params' => $matches];
|
||||
} else {
|
||||
// 解析路由地址
|
||||
$result = self::parseRoute($url);
|
||||
$var = array_merge($matches, $result['var']);
|
||||
// 解析剩余的URL参数
|
||||
self::parseUrlParams(implode('/', $paths), $var);
|
||||
// 路由到模块/控制器/操作
|
||||
$result = ['type' => 'module', 'module' => $result['route'], 'convert' => false];
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
$action = array_pop($path);
|
||||
$controller = !empty($path) ? array_pop($path) : null;
|
||||
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
|
||||
$method = Request::instance()->method();
|
||||
if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
|
||||
// 操作方法前缀支持
|
||||
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
|
||||
}
|
||||
$_GET = array_merge($_GET, $var);
|
||||
// 路由到模块/控制器/操作
|
||||
$result = ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];
|
||||
}
|
||||
// 解析额外参数
|
||||
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -1191,11 +1217,10 @@ class Route
|
||||
$var += explode('/', $url);
|
||||
} else {
|
||||
preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {
|
||||
$var[strtolower($match[1])] = strip_tags($match[2]);
|
||||
$var[$match[1]] = strip_tags($match[2]);
|
||||
}, $url);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置当前请求的参数
|
||||
Request::instance()->param(array_merge($var, $_GET));
|
||||
}
|
||||
|
||||
@@ -672,7 +672,7 @@ class Template
|
||||
*/
|
||||
public function parseTagLib($tagLib, &$content, $hide = false)
|
||||
{
|
||||
if (strpos($tagLib, '\\')) {
|
||||
if (false !== strpos($tagLib, '\\')) {
|
||||
// 支持指定标签库的命名空间
|
||||
$className = $tagLib;
|
||||
$tagLib = substr($tagLib, strrpos($tagLib, '\\') + 1);
|
||||
|
||||
@@ -78,9 +78,9 @@ class Url
|
||||
}
|
||||
|
||||
// 检测URL绑定
|
||||
$type = Route::bind('type');
|
||||
$type = Route::getBind('type');
|
||||
if ($type) {
|
||||
$bind = Route::bind($type);
|
||||
$bind = Route::getBind($type);
|
||||
if (0 === strpos($url, $bind)) {
|
||||
$url = substr($url, strlen($bind) + 1);
|
||||
}
|
||||
@@ -153,9 +153,10 @@ class Url
|
||||
protected static function parseDomain(&$url, $domain)
|
||||
{
|
||||
if ($domain) {
|
||||
$request = Request::instance();
|
||||
if (true === $domain) {
|
||||
// 自动判断域名
|
||||
$domain = $_SERVER['HTTP_HOST'];
|
||||
$domain = $request->host();
|
||||
if (Config::get('url_domain_deploy')) {
|
||||
// 根域名
|
||||
$urlDomainRoot = Config::get('url_domain_root');
|
||||
@@ -184,9 +185,9 @@ class Url
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$domain .= strpos($domain, '.') ? '' : strstr($_SERVER['HTTP_HOST'], '.');
|
||||
$domain .= strpos($domain, '.') ? '' : strstr($request->host(), '.');
|
||||
}
|
||||
$domain = (self::isSsl() ? 'https://' : 'http://') . $domain;
|
||||
$domain = ($request->isSsl() ? 'https://' : 'http://') . $domain;
|
||||
} else {
|
||||
$domain = '';
|
||||
}
|
||||
@@ -217,20 +218,6 @@ class Url
|
||||
return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否SSL协议
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isSsl()
|
||||
{
|
||||
if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) {
|
||||
return true;
|
||||
} elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 匹配路由地址
|
||||
public static function getRouteUrl($alias, &$vars = [])
|
||||
{
|
||||
@@ -253,11 +240,13 @@ class Url
|
||||
}
|
||||
}
|
||||
$match = true;
|
||||
} elseif (empty($pattern) && array_intersect_assoc($param, $array) == $param) {
|
||||
$match = true;
|
||||
}
|
||||
if (empty($pattern) && empty($param)) {
|
||||
// 没有任何变量
|
||||
return $url;
|
||||
} elseif ($match && (empty($param) || array_intersect_assoc($param, $array) == $param)) {
|
||||
if (!empty($param) && array_intersect_assoc($param, $array) != $param) {
|
||||
$match = false;
|
||||
}
|
||||
if ($match) {
|
||||
// 存在变量定义
|
||||
$vars = array_diff_key($array, $param);
|
||||
return $url;
|
||||
|
||||
@@ -16,11 +16,11 @@ use PDOStatement;
|
||||
use think\App;
|
||||
use think\Collection;
|
||||
use think\Db;
|
||||
use think\db\exception\BindParamException;
|
||||
use think\db\Query;
|
||||
use think\Debug;
|
||||
use think\Exception;
|
||||
use think\exception\PDOException;
|
||||
use think\db\exception\BindParamException;
|
||||
use think\Log;
|
||||
|
||||
abstract class Connection
|
||||
@@ -102,7 +102,7 @@ abstract class Connection
|
||||
|
||||
// PDO连接参数
|
||||
protected $params = [
|
||||
PDO::ATTR_CASE => PDO::CASE_LOWER,
|
||||
PDO::ATTR_CASE => PDO::CASE_NATURAL,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
@@ -188,7 +188,7 @@ abstract class Connection
|
||||
* @param array $info 字段信息
|
||||
* @return array
|
||||
*/
|
||||
protected function fieldCase($info)
|
||||
public function fieldCase($info)
|
||||
{
|
||||
// 字段大小写转换
|
||||
switch ($this->attrCase) {
|
||||
@@ -330,7 +330,7 @@ abstract class Connection
|
||||
}
|
||||
// 根据参数绑定组装最终的SQL语句
|
||||
$this->queryStr = $this->getRealSql($sql, $bind);
|
||||
|
||||
|
||||
//释放前次的查询结果
|
||||
if (!empty($this->PDOStatement)) {
|
||||
$this->free();
|
||||
@@ -474,6 +474,7 @@ abstract class Connection
|
||||
return $this->PDOStatement;
|
||||
}
|
||||
if ($procedure) {
|
||||
// 存储过程返回结果
|
||||
return $this->procedure($class);
|
||||
}
|
||||
$result = $this->PDOStatement->fetchAll($this->fetchType);
|
||||
@@ -482,11 +483,10 @@ abstract class Connection
|
||||
if (!empty($class)) {
|
||||
// 返回指定数据集对象类
|
||||
$result = new $class($result);
|
||||
} elseif ('collection' == $this->resultSetType){
|
||||
} elseif ('collection' == $this->resultSetType) {
|
||||
// 返回数据集Collection对象
|
||||
$result = new Collection($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ abstract class Connection
|
||||
|
||||
++$this->transTimes;
|
||||
|
||||
if ($this->transTimes == 1) {
|
||||
if (1 == $this->transTimes) {
|
||||
$this->linkID->beginTransaction();
|
||||
} elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
|
||||
$this->linkID->exec(
|
||||
@@ -570,7 +570,7 @@ abstract class Connection
|
||||
{
|
||||
$this->initConnect(true);
|
||||
|
||||
if ($this->transTimes == 1) {
|
||||
if (1 == $this->transTimes) {
|
||||
$this->linkID->commit();
|
||||
}
|
||||
|
||||
@@ -587,7 +587,7 @@ abstract class Connection
|
||||
{
|
||||
$this->initConnect(true);
|
||||
|
||||
if ($this->transTimes == 1) {
|
||||
if (1 == $this->transTimes) {
|
||||
$this->linkID->rollBack();
|
||||
} elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
|
||||
$this->linkID->exec(
|
||||
@@ -647,9 +647,9 @@ abstract class Connection
|
||||
}
|
||||
// 提交事务
|
||||
$this->commit();
|
||||
} catch (\PDOException $e) {
|
||||
} catch (\Exception $e) {
|
||||
$this->rollback();
|
||||
return false;
|
||||
throw $e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ use think\db\Builder;
|
||||
*/
|
||||
class Sqlsrv extends Builder
|
||||
{
|
||||
protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%';
|
||||
protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%';
|
||||
protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%';
|
||||
protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
|
||||
/**
|
||||
* order分析
|
||||
@@ -79,9 +79,10 @@ class Sqlsrv extends Builder
|
||||
}
|
||||
return 'WHERE ' . $limitStr;
|
||||
}
|
||||
public function selectInsert($fields, $table, $options)
|
||||
|
||||
public function selectInsert($fields, $table, $options)
|
||||
{
|
||||
$this->selectSql=$this->selectInsertSql;
|
||||
$this->selectSql = $this->selectInsertSql;
|
||||
return parent::selectInsert($fields, $table, $options);
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ class Merge extends Model
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
return false;
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,9 +283,9 @@ class Merge extends Model
|
||||
$this->trigger('after_delete', $this);
|
||||
$db->commit();
|
||||
return $result;
|
||||
} catch (\PDOException $e) {
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
return false;
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use think\Exception;
|
||||
|
||||
class Redis extends SessionHandler
|
||||
{
|
||||
/** @var \Redis */
|
||||
protected $handler = null;
|
||||
protected $config = [
|
||||
'host' => '127.0.0.1', // redis主机
|
||||
@@ -35,8 +36,10 @@ class Redis extends SessionHandler
|
||||
/**
|
||||
* 打开Session
|
||||
* @access public
|
||||
* @param string $savePath
|
||||
* @param mixed $sessName
|
||||
* @param string $savePath
|
||||
* @param mixed $sessName
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function open($savePath, $sessName)
|
||||
{
|
||||
@@ -72,6 +75,7 @@ class Redis extends SessionHandler
|
||||
* 读取Session
|
||||
* @access public
|
||||
* @param string $sessID
|
||||
* @return bool|string
|
||||
*/
|
||||
public function read($sessID)
|
||||
{
|
||||
@@ -83,6 +87,7 @@ class Redis extends SessionHandler
|
||||
* @access public
|
||||
* @param string $sessID
|
||||
* @param String $sessData
|
||||
* @return bool
|
||||
*/
|
||||
public function write($sessID, $sessData)
|
||||
{
|
||||
@@ -97,16 +102,18 @@ class Redis extends SessionHandler
|
||||
* 删除Session
|
||||
* @access public
|
||||
* @param string $sessID
|
||||
* @return bool|void
|
||||
*/
|
||||
public function destroy($sessID)
|
||||
{
|
||||
return $this->handler->delete($this->config['session_name'] . $sessID) ? true : false;
|
||||
$this->handler->delete($this->config['session_name'] . $sessID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Session 垃圾回收
|
||||
* @access public
|
||||
* @param string $sessMaxLifeTime
|
||||
* @return bool
|
||||
*/
|
||||
public function gc($sessMaxLifeTime)
|
||||
{
|
||||
|
||||
@@ -87,15 +87,15 @@ class TagLib
|
||||
public function parseTag(&$content, $lib = '')
|
||||
{
|
||||
$tags = [];
|
||||
$_lib = $lib ? $lib . ':' : '';
|
||||
$lib = $lib ? strtolower($lib) . ':' : '';
|
||||
foreach ($this->tags as $name => $val) {
|
||||
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
|
||||
$tags[$close][$_lib . $name] = $name;
|
||||
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
|
||||
$tags[$close][$lib . $name] = $name;
|
||||
if (isset($val['alias'])) {
|
||||
// 别名设置
|
||||
$array = (array) $val['alias'];
|
||||
foreach (explode(',', $array[0]) as $v) {
|
||||
$tags[$close][$_lib . $v] = $name;
|
||||
$tags[$close][$lib . $v] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class TagLib
|
||||
$right = [];
|
||||
foreach ($matches as $match) {
|
||||
if ('' == $match[1][0]) {
|
||||
$name = $match[2][0];
|
||||
$name = strtolower($match[2][0]);
|
||||
// 如果有没闭合的标签头则取出最后一个
|
||||
if (!empty($right[$name])) {
|
||||
// $match[0][1]为标签结束符在模板中的位置
|
||||
@@ -120,7 +120,7 @@ class TagLib
|
||||
}
|
||||
} else {
|
||||
// 标签头压入栈
|
||||
$right[$match[1][0]][] = $match[0];
|
||||
$right[strtolower($match[1][0])][] = $match[0];
|
||||
}
|
||||
}
|
||||
unset($right, $matches);
|
||||
@@ -135,10 +135,10 @@ class TagLib
|
||||
foreach ($nodes as $pos => $node) {
|
||||
// 对应的标签名
|
||||
$name = $tags[1][$node['name']];
|
||||
$alias = $_lib . $name != $node['name'] ? ($_lib ? strstr($node['name'], $_lib) : $node['name']) : '';
|
||||
$alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : '';
|
||||
// 解析标签属性
|
||||
$attrs = $this->parseAttr($node['begin'][0], $name, $alias);
|
||||
$method = '_' . $name;
|
||||
$method = 'tag' . $name;
|
||||
// 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾
|
||||
$replace = explode($break, $this->$method($attrs, $break));
|
||||
if (count($replace) > 1) {
|
||||
@@ -170,13 +170,13 @@ class TagLib
|
||||
// 自闭合标签
|
||||
if (!empty($tags[0])) {
|
||||
$regex = $this->getRegex(array_keys($tags[0]), 0);
|
||||
$content = preg_replace_callback($regex, function ($matches) use (&$tags, &$_lib) {
|
||||
$content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) {
|
||||
// 对应的标签名
|
||||
$name = $tags[0][$matches[1]];
|
||||
$alias = $_lib . $name != $matches[1] ? ($_lib ? strstr($matches[1], $_lib) : $matches[1]) : '';
|
||||
$name = $tags[0][strtolower($matches[1])];
|
||||
$alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : '';
|
||||
// 解析标签属性
|
||||
$attrs = $this->parseAttr($matches[0], $name, $alias);
|
||||
$method = '_' . $name;
|
||||
$method = 'tag' . $name;
|
||||
return $this->$method($attrs, '');
|
||||
}, $content);
|
||||
}
|
||||
@@ -286,6 +286,9 @@ class TagLib
|
||||
*/
|
||||
public function parseCondition($condition)
|
||||
{
|
||||
if (strpos($condition, ':')) {
|
||||
$condition = ' ' . substr(strstr($condition, ':'), 1);
|
||||
}
|
||||
$condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);
|
||||
$this->tpl->parseVar($condition);
|
||||
// $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异
|
||||
|
||||
@@ -43,8 +43,7 @@ class Cx extends Taglib
|
||||
'notpresent' => ['attr' => 'name'],
|
||||
'defined' => ['attr' => 'name'],
|
||||
'notdefined' => ['attr' => 'name'],
|
||||
'import' => ['attr' => 'file,href,type,value,basepath', 'close' => 0],
|
||||
'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['css,js', 'type']],
|
||||
'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['import,css,js', 'type']],
|
||||
'assign' => ['attr' => 'name,value', 'close' => 0],
|
||||
'define' => ['attr' => 'name,value', 'close' => 0],
|
||||
'for' => ['attr' => 'start,end,name,comparison,step'],
|
||||
@@ -61,7 +60,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _php($tag, $content)
|
||||
public function tagPhp($tag, $content)
|
||||
{
|
||||
$parseStr = '<?php ' . $content . ' ?>';
|
||||
return $parseStr;
|
||||
@@ -79,7 +78,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string|void
|
||||
*/
|
||||
public function _volist($tag, $content)
|
||||
public function tagVolist($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$id = $tag['id'];
|
||||
@@ -131,7 +130,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string|void
|
||||
*/
|
||||
public function _foreach($tag, $content)
|
||||
public function tagForeach($tag, $content)
|
||||
{
|
||||
// 直接使用表达式
|
||||
if (!empty($tag['expression'])) {
|
||||
@@ -212,7 +211,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _if($tag, $content)
|
||||
public function tagIf($tag, $content)
|
||||
{
|
||||
$condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];
|
||||
$condition = $this->parseCondition($condition);
|
||||
@@ -228,7 +227,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _elseif($tag, $content)
|
||||
public function tagElseif($tag, $content)
|
||||
{
|
||||
$condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];
|
||||
$condition = $this->parseCondition($condition);
|
||||
@@ -243,7 +242,7 @@ class Cx extends Taglib
|
||||
* @param array $tag 标签属性
|
||||
* @return string
|
||||
*/
|
||||
public function _else($tag)
|
||||
public function tagElse($tag)
|
||||
{
|
||||
$parseStr = '<?php else: ?>';
|
||||
return $parseStr;
|
||||
@@ -262,7 +261,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _switch($tag, $content)
|
||||
public function tagSwitch($tag, $content)
|
||||
{
|
||||
$name = !empty($tag['expression']) ? $tag['expression'] : $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
@@ -277,7 +276,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _case($tag, $content)
|
||||
public function tagCase($tag, $content)
|
||||
{
|
||||
$value = !empty($tag['expression']) ? $tag['expression'] : $tag['value'];
|
||||
$flag = substr($value, 0, 1);
|
||||
@@ -309,7 +308,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _default($tag)
|
||||
public function tagDefault($tag)
|
||||
{
|
||||
$parseStr = '<?php default: ?>';
|
||||
return $parseStr;
|
||||
@@ -324,7 +323,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _compare($tag, $content)
|
||||
public function tagCompare($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$value = $tag['value'];
|
||||
@@ -359,7 +358,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _range($tag, $content)
|
||||
public function tagRange($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$value = $tag['value'];
|
||||
@@ -394,7 +393,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _present($tag, $content)
|
||||
public function tagPresent($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
@@ -411,7 +410,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _notpresent($tag, $content)
|
||||
public function tagNotpresent($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
@@ -428,7 +427,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _empty($tag, $content)
|
||||
public function tagEmpty($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
@@ -445,7 +444,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _notempty($tag, $content)
|
||||
public function tagNotempty($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
@@ -460,7 +459,7 @@ class Cx extends Taglib
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function _defined($tag, $content)
|
||||
public function tagDefined($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$parseStr = '<?php if(defined("' . $name . '")): ?>' . $content . '<?php endif; ?>';
|
||||
@@ -474,7 +473,7 @@ class Cx extends Taglib
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function _notdefined($tag, $content)
|
||||
public function tagNotdefined($tag, $content)
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$parseStr = '<?php if(!defined("' . $name . '")): ?>' . $content . '<?php endif; ?>';
|
||||
@@ -482,19 +481,17 @@ class Cx extends Taglib
|
||||
}
|
||||
|
||||
/**
|
||||
* import 标签解析 {import file="Js.Base" /}
|
||||
* 格式:{import file="Css.Base" type="css" /}
|
||||
* load 标签解析 {load file="/static/js/base.js" /}
|
||||
* 格式:{load file="/static/css/base.css" /}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @param boolean $isFile 是否文件方式
|
||||
* @param string $type 类型
|
||||
* @return string
|
||||
*/
|
||||
public function _import($tag, $content, $isFile = false)
|
||||
public function tagLoad($tag, $content)
|
||||
{
|
||||
$file = isset($tag['file']) ? $tag['file'] : $tag['href'];
|
||||
$type = isset($tag['type']) ? strtolower($tag['type']) : ($isFile ? null : 'js');
|
||||
$type = isset($tag['type']) ? strtolower($tag['type']) : '';
|
||||
$parseStr = '';
|
||||
$endStr = '';
|
||||
// 判断是否存在加载条件 允许使用函数判断(默认为isset)
|
||||
@@ -505,58 +502,26 @@ class Cx extends Taglib
|
||||
$parseStr .= '<?php if(' . $name . '): ?>';
|
||||
$endStr = '<?php endif; ?>';
|
||||
}
|
||||
if ($isFile) {
|
||||
// 文件方式导入
|
||||
$array = explode(',', $file);
|
||||
foreach ($array as $val) {
|
||||
if (!$type || isset($reset)) {
|
||||
$type = $reset = strtolower(substr(strrchr($val, '.'), 1));
|
||||
}
|
||||
switch ($type) {
|
||||
case 'js':
|
||||
$parseStr .= '<script type="text/javascript" src="' . $val . '"></script>';
|
||||
break;
|
||||
case 'css':
|
||||
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $val . '" />';
|
||||
break;
|
||||
case 'php':
|
||||
$parseStr .= '<?php include "' . $val . '"; ?>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 命名空间导入模式
|
||||
$basepath = !empty($tag['basepath']) ? $tag['basepath'] : '/public';
|
||||
// 命名空间方式导入外部文件
|
||||
$array = explode(',', $file);
|
||||
foreach ($array as $val) {
|
||||
if (strpos($val, '?')) {
|
||||
list($val, $version) = explode('?', $val);
|
||||
} else {
|
||||
$version = '';
|
||||
}
|
||||
switch ($type) {
|
||||
case 'js':
|
||||
$parseStr .= '<script type="text/javascript" src="' . $basepath . '/' . str_replace(['.', '#'], ['/', '.'], $val) . '.js' . ($version ? '?' . $version : '') . '"></script>';
|
||||
break;
|
||||
case 'css':
|
||||
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $basepath . '/' . str_replace(['.', '#'], ['/', '.'], $val) . '.css' . ($version ? '?' . $version : '') . '" />';
|
||||
break;
|
||||
case 'php':
|
||||
$parseStr .= '<?php \think\Loader::import("' . $val . '"); ?>';
|
||||
break;
|
||||
}
|
||||
|
||||
// 文件方式导入
|
||||
$array = explode(',', $file);
|
||||
foreach ($array as $val) {
|
||||
$type = strtolower(substr(strrchr($val, '.'), 1));
|
||||
switch ($type) {
|
||||
case 'js':
|
||||
$parseStr .= '<script type="text/javascript" src="' . $val . '"></script>';
|
||||
break;
|
||||
case 'css':
|
||||
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $val . '" />';
|
||||
break;
|
||||
case 'php':
|
||||
$parseStr .= '<?php include "' . $val . '"; ?>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $parseStr . $endStr;
|
||||
}
|
||||
|
||||
// import别名 采用文件方式加载(要使用命名空间必须用import) 例如 <load file="__PUBLIC__/Js/Base.js" />
|
||||
public function _load($tag, $content)
|
||||
{
|
||||
return $this->_import($tag, $content, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* assign标签解析
|
||||
* 在模板中给某个变量赋值 支持变量赋值
|
||||
@@ -566,7 +531,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _assign($tag, $content)
|
||||
public function tagAssign($tag, $content)
|
||||
{
|
||||
$name = $this->autoBuildVar($tag['name']);
|
||||
$flag = substr($tag['value'], 0, 1);
|
||||
@@ -588,7 +553,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _define($tag, $content)
|
||||
public function tagDefine($tag, $content)
|
||||
{
|
||||
$name = '\'' . $tag['name'] . '\'';
|
||||
$flag = substr($tag['value'], 0, 1);
|
||||
@@ -612,7 +577,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _for($tag, $content)
|
||||
public function tagFor($tag, $content)
|
||||
{
|
||||
//设置默认值
|
||||
$start = 0;
|
||||
@@ -663,7 +628,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _url($tag, $content)
|
||||
public function tagUrl($tag, $content)
|
||||
{
|
||||
$url = isset($tag['link']) ? $tag['link'] : '';
|
||||
$vars = isset($tag['vars']) ? $tag['vars'] : '';
|
||||
@@ -689,7 +654,7 @@ class Cx extends Taglib
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function _function($tag, $content)
|
||||
public function tagFunction($tag, $content)
|
||||
{
|
||||
$name = !empty($tag['name']) ? $tag['name'] : 'func';
|
||||
$vars = !empty($tag['vars']) ? $tag['vars'] : '';
|
||||
|
||||
@@ -11,43 +11,8 @@
|
||||
|
||||
namespace think;
|
||||
|
||||
// ThinkPHP 实际引导文件
|
||||
// ThinkPHP 引导文件
|
||||
// 加载基础文件
|
||||
require __DIR__ . '/base.php';
|
||||
require CORE_PATH . 'Loader.php';
|
||||
|
||||
// 加载环境变量配置文件
|
||||
if (is_file(ROOT_PATH . 'env' . EXT)) {
|
||||
$env = include ROOT_PATH . 'env' . EXT;
|
||||
foreach ($env as $key => $val) {
|
||||
$name = ENV_PREFIX . $key;
|
||||
if (is_bool($val)) {
|
||||
$val = $val ? 1 : 0;
|
||||
}
|
||||
putenv("$name=$val");
|
||||
}
|
||||
}
|
||||
|
||||
// 注册命名空间定义
|
||||
Loader::addNamespace([
|
||||
'think' => LIB_PATH . 'think' . DS,
|
||||
'behavior' => LIB_PATH . 'behavior' . DS,
|
||||
'traits' => LIB_PATH . 'traits' . DS,
|
||||
]);
|
||||
|
||||
// 注册自动加载
|
||||
Loader::register();
|
||||
|
||||
// 加载别名定义
|
||||
Loader::addMap(include THINK_PATH . 'alias' . EXT);
|
||||
|
||||
// 注册错误和异常处理机制
|
||||
Error::register();
|
||||
|
||||
// 加载模式配置文件
|
||||
Config::set(include THINK_PATH . 'convention' . EXT);
|
||||
|
||||
// 是否自动运行
|
||||
if (APP_AUTO_RUN) {
|
||||
App::run()->send();
|
||||
}
|
||||
// 执行应用
|
||||
App::run()->send();
|
||||
|
||||
@@ -1,3 +1,80 @@
|
||||
<?php
|
||||
if(!function_exists('parse_padding')){
|
||||
function parse_padding($source)
|
||||
{
|
||||
$length = strlen(strval(count($source['source']) + $source['first']));
|
||||
return 40 + ($length - 1) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('parse_class')){
|
||||
function parse_class($name)
|
||||
{
|
||||
$names = explode('\\', $name);
|
||||
return '<abbr title="'.$name.'">'.end($names).'</abbr>';
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('parse_file')){
|
||||
function parse_file($file, $line)
|
||||
{
|
||||
return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('parse_args')){
|
||||
function parse_args($args)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($args as $key => $item) {
|
||||
switch (true) {
|
||||
case is_object($item):
|
||||
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
|
||||
break;
|
||||
case is_array($item):
|
||||
if(count($item) > 3){
|
||||
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
|
||||
} else {
|
||||
$value = sprintf('[%s]', parse_args($item));
|
||||
}
|
||||
break;
|
||||
case is_string($item):
|
||||
if(strlen($item) > 20){
|
||||
$value = sprintf(
|
||||
'\'<a class="toggle" title="%s">%s...</a>\'',
|
||||
htmlentities($item),
|
||||
htmlentities(substr($item, 0, 20))
|
||||
);
|
||||
} else {
|
||||
$value = sprintf("'%s'", htmlentities($item));
|
||||
}
|
||||
break;
|
||||
case is_int($item):
|
||||
case is_float($item):
|
||||
$value = $item;
|
||||
break;
|
||||
case is_null($item):
|
||||
$value = '<em>null</em>';
|
||||
break;
|
||||
case is_bool($item):
|
||||
$value = '<em>' . ($item ? 'true' : 'false') . '</em>';
|
||||
break;
|
||||
case is_resource($item):
|
||||
$value = '<em>resource</em>';
|
||||
break;
|
||||
default:
|
||||
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
|
||||
break;
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $value : "'{$key}' => {$value}";
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -399,72 +476,4 @@
|
||||
</script>
|
||||
<?php } ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
function parse_padding($source)
|
||||
{
|
||||
$length = strlen(strval(count($source['source']) + $source['first']));
|
||||
return 40 + ($length - 1) * 8;
|
||||
}
|
||||
|
||||
function parse_class($name)
|
||||
{
|
||||
$names = explode('\\', $name);
|
||||
return '<abbr title="'.$name.'">'.end($names).'</abbr>';
|
||||
}
|
||||
|
||||
function parse_file($file, $line)
|
||||
{
|
||||
return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>';
|
||||
}
|
||||
|
||||
function parse_args($args)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($args as $key => $item) {
|
||||
switch (true) {
|
||||
case is_object($item):
|
||||
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
|
||||
break;
|
||||
case is_array($item):
|
||||
if(count($item) > 3){
|
||||
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
|
||||
} else {
|
||||
$value = sprintf('[%s]', parse_args($item));
|
||||
}
|
||||
break;
|
||||
case is_string($item):
|
||||
if(strlen($item) > 20){
|
||||
$value = sprintf(
|
||||
'\'<a class="toggle" title="%s">%s...</a>\'',
|
||||
htmlentities($item),
|
||||
htmlentities(substr($item, 0, 20))
|
||||
);
|
||||
} else {
|
||||
$value = sprintf("'%s'", htmlentities($item));
|
||||
}
|
||||
break;
|
||||
case is_int($item):
|
||||
case is_float($item):
|
||||
$value = $item;
|
||||
break;
|
||||
case is_null($item):
|
||||
$value = '<em>null</em>';
|
||||
break;
|
||||
case is_bool($item):
|
||||
$value = '<em>' . ($item ? 'true' : 'false') . '</em>';
|
||||
break;
|
||||
case is_resource($item):
|
||||
$value = '<em>resource</em>';
|
||||
break;
|
||||
default:
|
||||
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
|
||||
break;
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $value : "'{$key}' => {$value}";
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
}
|
||||
</html>
|
||||
Reference in New Issue
Block a user