1.修复后台无法退出的bug
2.更新tp内核
This commit is contained in:
@@ -44,19 +44,19 @@
|
|||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu dropdown-menu-right">
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
<li>
|
<li>
|
||||||
<a href="{:url('User/edit')}">
|
<a href="{:url('admin/User/edit')}">
|
||||||
<i class="fa fa-user"></i>
|
<i class="fa fa-user"></i>
|
||||||
修改资料
|
修改资料
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{:url('User/editpwd')}">
|
<a href="{:url('admin/User/editpwd')}">
|
||||||
<i class="fa fa-cog"></i>
|
<i class="fa fa-cog"></i>
|
||||||
修改密码
|
修改密码
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{:url('index/logout')}">
|
<a href="{:url('admin/login/logout')}">
|
||||||
<i class="fa fa-power-off"></i>
|
<i class="fa fa-power-off"></i>
|
||||||
退出后台
|
退出后台
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -135,15 +135,15 @@ class App
|
|||||||
break;
|
break;
|
||||||
case 'controller':
|
case 'controller':
|
||||||
// 执行控制器操作
|
// 执行控制器操作
|
||||||
$data = Loader::action($dispatch['controller'], $dispatch['params']);
|
$data = Loader::action($dispatch['controller']);
|
||||||
break;
|
break;
|
||||||
case 'method':
|
case 'method':
|
||||||
// 执行回调方法
|
// 执行回调方法
|
||||||
$data = self::invokeMethod($dispatch['method'], $dispatch['params']);
|
$data = self::invokeMethod($dispatch['method']);
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function':
|
||||||
// 执行闭包
|
// 执行闭包
|
||||||
$data = self::invokeFunction($dispatch['function'], $dispatch['params']);
|
$data = self::invokeFunction($dispatch['function']);
|
||||||
break;
|
break;
|
||||||
case 'response':
|
case 'response':
|
||||||
$data = $dispatch['response'];
|
$data = $dispatch['response'];
|
||||||
@@ -181,12 +181,11 @@ class App
|
|||||||
* @access public
|
* @access public
|
||||||
* @param array|string $dispatch 调度信息
|
* @param array|string $dispatch 调度信息
|
||||||
* @param string $type 调度类型
|
* @param string $type 调度类型
|
||||||
* @param array $params 参数
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function dispatch($dispatch, $type = 'module', $params = [])
|
public static function dispatch($dispatch, $type = 'module')
|
||||||
{
|
{
|
||||||
self::$dispatch = ['type' => $type, $type => $dispatch, 'params' => $params];
|
self::$dispatch = ['type' => $type, $type => $dispatch];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,10 +213,6 @@ class App
|
|||||||
*/
|
*/
|
||||||
public static function invokeMethod($method, $vars = [])
|
public static function invokeMethod($method, $vars = [])
|
||||||
{
|
{
|
||||||
if (empty($vars)) {
|
|
||||||
// 自动获取请求变量
|
|
||||||
$vars = Request::instance()->param();
|
|
||||||
}
|
|
||||||
if (is_array($method)) {
|
if (is_array($method)) {
|
||||||
$class = is_object($method[0]) ? $method[0] : new $method[0];
|
$class = is_object($method[0]) ? $method[0] : new $method[0];
|
||||||
$reflect = new \ReflectionMethod($class, $method[1]);
|
$reflect = new \ReflectionMethod($class, $method[1]);
|
||||||
@@ -238,8 +233,12 @@ class App
|
|||||||
* @param array $vars 变量
|
* @param array $vars 变量
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static function bindParams($reflect, $vars)
|
private static function bindParams($reflect, $vars = [])
|
||||||
{
|
{
|
||||||
|
if (empty($vars)) {
|
||||||
|
// 自动获取请求变量
|
||||||
|
$vars = Request::instance()->param();
|
||||||
|
}
|
||||||
$args = [];
|
$args = [];
|
||||||
// 判断数组类型 数字数组时按顺序绑定参数
|
// 判断数组类型 数字数组时按顺序绑定参数
|
||||||
reset($vars);
|
reset($vars);
|
||||||
@@ -251,7 +250,12 @@ class App
|
|||||||
$class = $param->getClass();
|
$class = $param->getClass();
|
||||||
if ($class) {
|
if ($class) {
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
$args[] = method_exists($className, 'instance') ? $className::instance() : new $className();
|
if (isset($vars[$name]) && $vars[$name] instanceof $className) {
|
||||||
|
$args[] = $vars[$name];
|
||||||
|
unset($vars[$name]);
|
||||||
|
} else {
|
||||||
|
$args[] = method_exists($className, 'instance') ? $className::instance() : new $className();
|
||||||
|
}
|
||||||
} elseif (1 == $type && !empty($vars)) {
|
} elseif (1 == $type && !empty($vars)) {
|
||||||
$args[] = array_shift($vars);
|
$args[] = array_shift($vars);
|
||||||
} elseif (0 == $type && isset($vars[$name])) {
|
} elseif (0 == $type && isset($vars[$name])) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@@ -18,135 +19,112 @@ use think\Log;
|
|||||||
class Hook
|
class Hook
|
||||||
{
|
{
|
||||||
|
|
||||||
private static $tags = [];
|
private static $tags = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态添加行为扩展到某个标签
|
* 动态添加行为扩展到某个标签
|
||||||
* @param string $tag 标签名称
|
* @param string $tag 标签名称
|
||||||
* @param mixed $behavior 行为名称
|
* @param mixed $behavior 行为名称
|
||||||
* @param bool $first 是否放到开头执行
|
* @param bool $first 是否放到开头执行
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function add($tag, $behavior, $first = false)
|
public static function add($tag, $behavior, $first = false)
|
||||||
{
|
{
|
||||||
if (!isset(self::$tags[$tag])) {
|
isset(self::$tags[$tag]) || self::$tags[$tag] = [];
|
||||||
self::$tags[$tag] = [];
|
if (is_array($behavior) && !is_callable($behavior)) {
|
||||||
}
|
if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) {
|
||||||
if (is_array($behavior)) {
|
unset($behavior['_overlay']);
|
||||||
self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior);
|
self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior);
|
||||||
} elseif ($first) {
|
} else {
|
||||||
array_unshift(self::$tags[$tag], $behavior);
|
unset($behavior['_overlay']);
|
||||||
} else {
|
self::$tags[$tag] = $behavior;
|
||||||
self::$tags[$tag][] = $behavior;
|
}
|
||||||
}
|
} elseif ($first) {
|
||||||
}
|
array_unshift(self::$tags[$tag], $behavior);
|
||||||
|
} else {
|
||||||
|
self::$tags[$tag][] = $behavior;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量导入插件
|
* 批量导入插件
|
||||||
* @param array $tags 插件信息
|
* @param array $tags 插件信息
|
||||||
* @param boolean $recursive 是否递归合并
|
* @param boolean $recursive 是否递归合并
|
||||||
*/
|
*/
|
||||||
public static function import($tags, $recursive = true)
|
public static function import(array $tags, $recursive = true)
|
||||||
{
|
{
|
||||||
empty($tags) && $tags = [];
|
if ($recursive) {
|
||||||
if (!$recursive) {
|
foreach ($tags as $tag => $behavior) {
|
||||||
// 覆盖导入
|
self::add($tag, $behavior);
|
||||||
self::$tags = array_merge(self::$tags, $tags);
|
}
|
||||||
} else {
|
} else {
|
||||||
// 合并导入
|
self::$tags = $tags + self::$tags;
|
||||||
foreach ($tags as $tag => $val) {
|
}
|
||||||
if (!isset(self::$tags[$tag])) {
|
}
|
||||||
self::$tags[$tag] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($val['_overlay'])) {
|
/**
|
||||||
// 可以针对某个标签指定覆盖模式
|
* 获取插件信息
|
||||||
unset($val['_overlay']);
|
* @param string $tag 插件位置 留空获取全部
|
||||||
self::$tags[$tag] = $val;
|
* @return array
|
||||||
} else {
|
*/
|
||||||
// 合并模式
|
public static function get($tag = '')
|
||||||
self::$tags[$tag] = array_merge(self::$tags[$tag], $val);
|
{
|
||||||
}
|
if (empty($tag)) {//获取全部的插件信息
|
||||||
}
|
return self::$tags;
|
||||||
}
|
} else {
|
||||||
}
|
return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取插件信息
|
* 监听标签的行为
|
||||||
* @param string $tag 插件位置 留空获取全部
|
* @param string $tag 标签名称
|
||||||
* @return array
|
* @param mixed $params 传入参数
|
||||||
*/
|
* @param mixed $extra 额外参数
|
||||||
public static function get($tag = '')
|
* @param bool $once 只获取一个有效返回值
|
||||||
{
|
* @return mixed
|
||||||
if (empty($tag)) {
|
*/
|
||||||
// 获取全部的插件信息
|
public static function listen($tag, &$params = null, $extra = null, $once = false)
|
||||||
return self::$tags;
|
{
|
||||||
} else {
|
$results = [];
|
||||||
return self::$tags[$tag];
|
$tags = static::get($tag);
|
||||||
}
|
foreach ($tags as $key => $name) {
|
||||||
}
|
$results[$key] = self::exec($name, $tag, $params, $extra);
|
||||||
|
if (false === $results[$key]) {// 如果返回false 则中断行为执行
|
||||||
|
break;
|
||||||
|
} elseif (!is_null($results[$key]) && $once) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $once ? end($results) : $results;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听标签的行为
|
* 执行某个行为
|
||||||
* @param string $tag 标签名称
|
* @param mixed $class 要执行的行为
|
||||||
* @param mixed $params 传入参数
|
* @param string $tag 方法名(标签名)
|
||||||
* @param mixed $extra 额外参数
|
* @param Mixed $params 传人的参数
|
||||||
* @param bool $once 只获取一个有效返回值
|
* @param mixed $extra 额外参数
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function listen($tag, &$params = null, $extra = null, $once = false)
|
public static function exec($class, $tag = '', &$params = null, $extra = null)
|
||||||
{
|
{
|
||||||
$results = [];
|
App::$debug && Debug::remark('behavior_start', 'time');
|
||||||
if (isset(self::$tags[$tag])) {
|
if (is_callable($class)) {
|
||||||
foreach (self::$tags[$tag] as $name) {
|
$result = call_user_func_array($class, [ & $params, $extra]);
|
||||||
|
$class = 'Closure';
|
||||||
|
} elseif (is_object($class)) {
|
||||||
|
$result = call_user_func_array([$class, $tag], [ & $params, $extra]);
|
||||||
|
$class = get_class($class);
|
||||||
|
} else {
|
||||||
|
$obj = new $class();
|
||||||
|
$result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params, $extra) : $obj->run($params, $extra);
|
||||||
|
}
|
||||||
|
if (App::$debug) {
|
||||||
|
Debug::remark('behavior_end', 'time');
|
||||||
|
Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
if (App::$debug) {
|
|
||||||
Debug::remark('behavior_start', 'time');
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = self::exec($name, $tag, $params, $extra);
|
|
||||||
|
|
||||||
if (!is_null($result) && $once) {
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App::$debug) {
|
|
||||||
Debug::remark('behavior_end', 'time');
|
|
||||||
if ($name instanceof \Closure) {
|
|
||||||
$name = 'Closure';
|
|
||||||
} elseif (is_object($name)) {
|
|
||||||
$name = get_class($name);
|
|
||||||
}
|
|
||||||
Log::record('[ BEHAVIOR ] Run ' . $name . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
|
|
||||||
}
|
|
||||||
if (false === $result) {
|
|
||||||
// 如果返回false 则中断行为执行
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$results[] = $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $once ? null : $results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行某个行为
|
|
||||||
* @param mixed $class 要执行的行为
|
|
||||||
* @param string $tag 方法名(标签名)
|
|
||||||
* @param Mixed $params 传人的参数
|
|
||||||
* @param mixed $extra 额外参数
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function exec($class, $tag = '', &$params = null,$extra=null)
|
|
||||||
{
|
|
||||||
if ($class instanceof \Closure) {
|
|
||||||
$result = call_user_func_array($class, [ & $params,$extra]);
|
|
||||||
} elseif (is_object($class)) {
|
|
||||||
$result = call_user_func_array([$class, $tag], [ & $params,$extra]);
|
|
||||||
} else {
|
|
||||||
$obj = new $class();
|
|
||||||
$result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params,$extra) : $obj->run($params,$extra);
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -974,6 +974,7 @@ class Request
|
|||||||
$filter[] = $default;
|
$filter[] = $default;
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
array_walk_recursive($data, [$this, 'filterValue'], $filter);
|
array_walk_recursive($data, [$this, 'filterValue'], $filter);
|
||||||
|
reset($data);
|
||||||
} else {
|
} else {
|
||||||
$this->filterValue($data, $name, $filter);
|
$this->filterValue($data, $name, $filter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use think\App;
|
|||||||
use think\Config;
|
use think\Config;
|
||||||
use think\exception\HttpException;
|
use think\exception\HttpException;
|
||||||
use think\Hook;
|
use think\Hook;
|
||||||
|
use think\Loader;
|
||||||
use think\Log;
|
use think\Log;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
use think\Response;
|
use think\Response;
|
||||||
@@ -853,9 +854,10 @@ class Route
|
|||||||
* @param string $url URL地址
|
* @param string $url URL地址
|
||||||
* @param string $depr URL分割符
|
* @param string $depr URL分割符
|
||||||
* @param string $group 路由分组名
|
* @param string $group 路由分组名
|
||||||
|
* @param array $options 路由参数(分组)
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private static function checkRoute($request, $rules, $url, $depr = '/', $group = '')
|
private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = [])
|
||||||
{
|
{
|
||||||
foreach ($rules as $key => $item) {
|
foreach ($rules as $key => $item) {
|
||||||
if (true === $item) {
|
if (true === $item) {
|
||||||
@@ -892,7 +894,7 @@ class Route
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = self::checkRoute($request, $rule, $url, $depr, $key);
|
$result = self::checkRoute($request, $rule, $url, $depr, $key, $option);
|
||||||
if (false !== $result) {
|
if (false !== $result) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -906,6 +908,9 @@ class Route
|
|||||||
if ($group) {
|
if ($group) {
|
||||||
$rule = $group . ($rule ? '/' . ltrim($rule, '/') : '');
|
$rule = $group . ($rule ? '/' . ltrim($rule, '/') : '');
|
||||||
}
|
}
|
||||||
|
if (isset($options['bind_model']) && isset($option['bind_model'])) {
|
||||||
|
$option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']);
|
||||||
|
}
|
||||||
$result = self::checkRule($rule, $route, $url, $pattern, $option);
|
$result = self::checkRule($rule, $route, $url, $pattern, $option);
|
||||||
if (false !== $result) {
|
if (false !== $result) {
|
||||||
return $result;
|
return $result;
|
||||||
@@ -1003,7 +1008,7 @@ class Route
|
|||||||
if (!empty($array[1])) {
|
if (!empty($array[1])) {
|
||||||
self::parseUrlParams($array[1]);
|
self::parseUrlParams($array[1]);
|
||||||
}
|
}
|
||||||
return ['type' => 'method', 'method' => [$class, $action], 'params' => []];
|
return ['type' => 'method', 'method' => [$class, $action]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1022,7 +1027,7 @@ class Route
|
|||||||
if (!empty($array[2])) {
|
if (!empty($array[2])) {
|
||||||
self::parseUrlParams($array[2]);
|
self::parseUrlParams($array[2]);
|
||||||
}
|
}
|
||||||
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method], 'params' => []];
|
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1040,7 +1045,7 @@ class Route
|
|||||||
if (!empty($array[1])) {
|
if (!empty($array[1])) {
|
||||||
self::parseUrlParams($array[1]);
|
self::parseUrlParams($array[1]);
|
||||||
}
|
}
|
||||||
return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'params' => []];
|
return ['type' => 'controller', 'controller' => $controller . '/' . $action];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1327,6 +1332,44 @@ class Route
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绑定模型数据
|
||||||
|
if (isset($option['bind_model'])) {
|
||||||
|
$bind = [];
|
||||||
|
foreach ($option['bind_model'] as $key => $val) {
|
||||||
|
if ($val instanceof \Closure) {
|
||||||
|
$result = call_user_func_array($val, [$matches]);
|
||||||
|
} else {
|
||||||
|
if (is_array($val)) {
|
||||||
|
$fields = explode('&', $val[1]);
|
||||||
|
$model = $val[0];
|
||||||
|
$exception = isset($val[2]) ? $val[2] : true;
|
||||||
|
} else {
|
||||||
|
$fields = ['id'];
|
||||||
|
$model = $val;
|
||||||
|
$exception = true;
|
||||||
|
}
|
||||||
|
$where = [];
|
||||||
|
$match = true;
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
if (!isset($matches[$field])) {
|
||||||
|
$match = false;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$where[$field] = $matches[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($match) {
|
||||||
|
$query = strpos($model, '\\') ? $model::where($where) : Loader::model($model)->where($where);
|
||||||
|
$result = $query->failException($exception)->find();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($result)) {
|
||||||
|
$bind[$key] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$matches = array_merge($matches, $bind);
|
||||||
|
}
|
||||||
|
|
||||||
// 解析额外参数
|
// 解析额外参数
|
||||||
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
|
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
|
||||||
// 记录匹配的路由信息
|
// 记录匹配的路由信息
|
||||||
@@ -1346,7 +1389,7 @@ class Route
|
|||||||
}
|
}
|
||||||
// 路由规则重定向
|
// 路由规则重定向
|
||||||
if ($result instanceof Response) {
|
if ($result instanceof Response) {
|
||||||
return ['type' => 'response', 'response' => $result, 'params' => $matches];
|
return ['type' => 'response', 'response' => $result];
|
||||||
} elseif (is_array($result)) {
|
} elseif (is_array($result)) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -1354,17 +1397,17 @@ class Route
|
|||||||
|
|
||||||
if ($route instanceof \Closure) {
|
if ($route instanceof \Closure) {
|
||||||
// 执行闭包
|
// 执行闭包
|
||||||
$result = ['type' => 'function', 'function' => $route, 'params' => $matches];
|
$result = ['type' => 'function', 'function' => $route];
|
||||||
} elseif (0 === strpos($route, '/') || 0 === strpos($route, 'http')) {
|
} elseif (0 === strpos($route, '/') || 0 === strpos($route, 'http')) {
|
||||||
// 路由到重定向地址
|
// 路由到重定向地址
|
||||||
$result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301];
|
$result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301];
|
||||||
} elseif (0 === strpos($route, '\\')) {
|
} elseif (0 === strpos($route, '\\')) {
|
||||||
// 路由到方法
|
// 路由到方法
|
||||||
$method = strpos($route, '@') ? explode('@', $route) : $route;
|
$method = strpos($route, '@') ? explode('@', $route) : $route;
|
||||||
$result = ['type' => 'method', 'method' => $method, 'params' => $matches];
|
$result = ['type' => 'method', 'method' => $method];
|
||||||
} elseif (0 === strpos($route, '@')) {
|
} elseif (0 === strpos($route, '@')) {
|
||||||
// 路由到控制器
|
// 路由到控制器
|
||||||
$result = ['type' => 'controller', 'controller' => substr($route, 1), 'params' => $matches];
|
$result = ['type' => 'controller', 'controller' => substr($route, 1)];
|
||||||
} else {
|
} else {
|
||||||
// 路由到模块/控制器/操作
|
// 路由到模块/控制器/操作
|
||||||
$result = self::parseModule($route);
|
$result = self::parseModule($route);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
|
use think\File;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
use think\Session;
|
use think\Session;
|
||||||
|
|
||||||
@@ -562,10 +563,10 @@ class Validate
|
|||||||
$result = is_array($value);
|
$result = is_array($value);
|
||||||
break;
|
break;
|
||||||
case 'file':
|
case 'file':
|
||||||
$result = $value instanceof \think\File;
|
$result = $value instanceof File;
|
||||||
break;
|
break;
|
||||||
case 'image':
|
case 'image':
|
||||||
$result = $value instanceof \think\File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);
|
$result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);
|
||||||
break;
|
break;
|
||||||
case 'token':
|
case 'token':
|
||||||
$result = $this->token($value, '__token__', $data);
|
$result = $this->token($value, '__token__', $data);
|
||||||
@@ -629,7 +630,7 @@ class Validate
|
|||||||
*/
|
*/
|
||||||
protected function fileExt($file, $rule)
|
protected function fileExt($file, $rule)
|
||||||
{
|
{
|
||||||
if (!($file instanceof \think\File)) {
|
if (!($file instanceof File)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_string($rule)) {
|
if (is_string($rule)) {
|
||||||
@@ -656,7 +657,7 @@ class Validate
|
|||||||
*/
|
*/
|
||||||
protected function fileMime($file, $rule)
|
protected function fileMime($file, $rule)
|
||||||
{
|
{
|
||||||
if (!($file instanceof \think\File)) {
|
if (!($file instanceof File)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_string($rule)) {
|
if (is_string($rule)) {
|
||||||
@@ -683,7 +684,7 @@ class Validate
|
|||||||
*/
|
*/
|
||||||
protected function fileSize($file, $rule)
|
protected function fileSize($file, $rule)
|
||||||
{
|
{
|
||||||
if (!($file instanceof \think\File)) {
|
if (!($file instanceof File)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_array($file)) {
|
if (is_array($file)) {
|
||||||
@@ -707,7 +708,7 @@ class Validate
|
|||||||
*/
|
*/
|
||||||
protected function image($file, $rule)
|
protected function image($file, $rule)
|
||||||
{
|
{
|
||||||
if (!($file instanceof \think\File)) {
|
if (!($file instanceof File)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$rule = explode(',', $rule);
|
$rule = explode(',', $rule);
|
||||||
@@ -946,7 +947,7 @@ class Validate
|
|||||||
{
|
{
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$length = count($value);
|
$length = count($value);
|
||||||
} elseif ($value instanceof \think\File) {
|
} elseif ($value instanceof File) {
|
||||||
$length = $value->getSize();
|
$length = $value->getSize();
|
||||||
} else {
|
} else {
|
||||||
$length = mb_strlen((string) $value);
|
$length = mb_strlen((string) $value);
|
||||||
@@ -973,7 +974,7 @@ class Validate
|
|||||||
{
|
{
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$length = count($value);
|
$length = count($value);
|
||||||
} elseif ($value instanceof \think\File) {
|
} elseif ($value instanceof File) {
|
||||||
$length = $value->getSize();
|
$length = $value->getSize();
|
||||||
} else {
|
} else {
|
||||||
$length = mb_strlen((string) $value);
|
$length = mb_strlen((string) $value);
|
||||||
@@ -992,7 +993,7 @@ class Validate
|
|||||||
{
|
{
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$length = count($value);
|
$length = count($value);
|
||||||
} elseif ($value instanceof \think\File) {
|
} elseif ($value instanceof File) {
|
||||||
$length = $value->getSize();
|
$length = $value->getSize();
|
||||||
} else {
|
} else {
|
||||||
$length = mb_strlen((string) $value);
|
$length = mb_strlen((string) $value);
|
||||||
|
|||||||
@@ -91,6 +91,19 @@ class View
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置模板引擎
|
||||||
|
* @access private
|
||||||
|
* @param string|array $name 参数名
|
||||||
|
* @param mixed $value 参数值
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function config($name, $value = null)
|
||||||
|
{
|
||||||
|
$this->engine->config($name, $value);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析和获取模板内容 用于输出
|
* 解析和获取模板内容 用于输出
|
||||||
* @param string $template 模板文件名或者内容
|
* @param string $template 模板文件名或者内容
|
||||||
|
|||||||
@@ -89,24 +89,22 @@ abstract class Builder
|
|||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($data as $key => $val) {
|
foreach ($data as $key => $val) {
|
||||||
|
$item = $this->parseKey($key);
|
||||||
if (!in_array($key, $fields, true)) {
|
if (!in_array($key, $fields, true)) {
|
||||||
if ($options['strict']) {
|
if ($options['strict']) {
|
||||||
throw new Exception('fields not exists:[' . $key . ']');
|
throw new Exception('fields not exists:[' . $key . ']');
|
||||||
}
|
}
|
||||||
} else {
|
} elseif (isset($val[0]) && 'exp' == $val[0]) {
|
||||||
$item = $this->parseKey($key);
|
$result[$item] = $val[1];
|
||||||
if (isset($val[0]) && 'exp' == $val[0]) {
|
} elseif (is_null($val)) {
|
||||||
$result[$item] = $val[1];
|
$result[$item] = 'NULL';
|
||||||
} elseif (is_null($val)) {
|
} elseif (is_scalar($val)) {
|
||||||
$result[$item] = 'NULL';
|
// 过滤非标量数据
|
||||||
} elseif (is_scalar($val)) {
|
if ($this->query->isBind(substr($val, 1))) {
|
||||||
// 过滤非标量数据
|
$result[$item] = $val;
|
||||||
if ($this->query->isBind(substr($val, 1))) {
|
} else {
|
||||||
$result[$item] = $val;
|
$this->query->bind($key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||||
} else {
|
$result[$item] = ':' . $key;
|
||||||
$this->query->bind($key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
|
||||||
$result[$item] = ':' . $key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,43 +222,34 @@ abstract class Builder
|
|||||||
}
|
}
|
||||||
|
|
||||||
$whereStr = '';
|
$whereStr = '';
|
||||||
// 获取字段信息
|
|
||||||
$fields = $this->query->getTableFields($options);
|
|
||||||
$binds = $this->query->getFieldsBind($options);
|
|
||||||
foreach ($where as $key => $val) {
|
foreach ($where as $key => $val) {
|
||||||
$str = [];
|
$str = [];
|
||||||
foreach ($val as $field => $value) {
|
foreach ($val as $field => $value) {
|
||||||
if ($fields && in_array($field, $fields, true) && is_scalar($value) && !$this->query->isBind($field)) {
|
|
||||||
$this->query->bind($field, $value, isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR);
|
|
||||||
$value = ':' . $field;
|
|
||||||
}
|
|
||||||
if ($value instanceof \Closure) {
|
if ($value instanceof \Closure) {
|
||||||
// 使用闭包查询
|
// 使用闭包查询
|
||||||
$query = new Query($this->connection);
|
$query = new Query($this->connection);
|
||||||
call_user_func_array($value, [ & $query]);
|
call_user_func_array($value, [ & $query]);
|
||||||
$str[] = ' ' . $key . ' ( ' . $this->buildWhere($query->getOptions('where'), $options) . ' )';
|
$str[] = ' ' . $key . ' ( ' . $this->buildWhere($query->getOptions('where'), $options) . ' )';
|
||||||
} else {
|
} elseif (strpos($field, '|')) {
|
||||||
if (strpos($field, '|')) {
|
// 不同字段使用相同查询条件(OR)
|
||||||
// 不同字段使用相同查询条件(OR)
|
$array = explode('|', $field);
|
||||||
$array = explode('|', $field);
|
$item = [];
|
||||||
$item = [];
|
foreach ($array as $k) {
|
||||||
foreach ($array as $k) {
|
$item[] = $this->parseWhereItem($k, $value, '', $options);
|
||||||
$item[] = $this->parseWhereItem($k, $value, '', $options);
|
|
||||||
}
|
|
||||||
$str[] = ' ' . $key . ' ( ' . implode(' OR ', $item) . ' )';
|
|
||||||
} elseif (strpos($field, '&')) {
|
|
||||||
// 不同字段使用相同查询条件(AND)
|
|
||||||
$array = explode('&', $field);
|
|
||||||
$item = [];
|
|
||||||
foreach ($array as $k) {
|
|
||||||
$item[] = $this->parseWhereItem($k, $value, '', $options);
|
|
||||||
}
|
|
||||||
$str[] = ' ' . $key . ' ( ' . implode(' AND ', $item) . ' )';
|
|
||||||
} else {
|
|
||||||
// 对字段使用表达式查询
|
|
||||||
$field = is_string($field) ? $field : '';
|
|
||||||
$str[] = ' ' . $key . ' ' . $this->parseWhereItem($field, $value, $key, $options);
|
|
||||||
}
|
}
|
||||||
|
$str[] = ' ' . $key . ' ( ' . implode(' OR ', $item) . ' )';
|
||||||
|
} elseif (strpos($field, '&')) {
|
||||||
|
// 不同字段使用相同查询条件(AND)
|
||||||
|
$array = explode('&', $field);
|
||||||
|
$item = [];
|
||||||
|
foreach ($array as $k) {
|
||||||
|
$item[] = $this->parseWhereItem($k, $value, '', $options);
|
||||||
|
}
|
||||||
|
$str[] = ' ' . $key . ' ( ' . implode(' AND ', $item) . ' )';
|
||||||
|
} else {
|
||||||
|
// 对字段使用表达式查询
|
||||||
|
$field = is_string($field) ? $field : '';
|
||||||
|
$str[] = ' ' . $key . ' ' . $this->parseWhereItem($field, $value, $key, $options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -733,11 +733,12 @@ abstract class Connection
|
|||||||
* SQL指令安全过滤
|
* SQL指令安全过滤
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $str SQL字符串
|
* @param string $str SQL字符串
|
||||||
|
* @param bool $master 是否主库查询
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function quote($str)
|
public function quote($str, $master = false)
|
||||||
{
|
{
|
||||||
$this->initConnect();
|
$this->initConnect($master);
|
||||||
return $this->linkID ? $this->linkID->quote($str) : $str;
|
return $this->linkID ? $this->linkID->quote($str) : $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class Pgsql extends Builder
|
|||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
// JSON字段支持
|
// JSON字段支持
|
||||||
list($field, $name) = explode($key, '$.');
|
list($field, $name) = explode('$.', $key);
|
||||||
$key = $field . '->>\'' . $name . '\'';
|
$key = $field . '->>\'' . $name . '\'';
|
||||||
}
|
}
|
||||||
return $key;
|
return $key;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Sqlsrv extends Connection
|
|||||||
{
|
{
|
||||||
// PDO连接参数
|
// PDO连接参数
|
||||||
protected $params = [
|
protected $params = [
|
||||||
PDO::ATTR_CASE => PDO::CASE_LOWER,
|
PDO::ATTR_CASE => PDO::CASE_NATURAL,
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class PDOException extends DbException
|
|||||||
|
|
||||||
$this->setData('PDO Error Info', [
|
$this->setData('PDO Error Info', [
|
||||||
'SQLSTATE' => $error[0],
|
'SQLSTATE' => $error[0],
|
||||||
'Driver Error Code' => $error[1],
|
'Driver Error Code' => isset($error[1]) ? $error[1] : 0,
|
||||||
'Driver Error Message' => isset($error[2]) ? $error[2] : '',
|
'Driver Error Message' => isset($error[2]) ? $error[2] : '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -339,7 +339,10 @@ class Relation
|
|||||||
{
|
{
|
||||||
$foreignKey = $this->foreignKey;
|
$foreignKey = $this->foreignKey;
|
||||||
// 预载入关联查询 支持嵌套预载入
|
// 预载入关联查询 支持嵌套预载入
|
||||||
$list = $model->where($where)->where($closure)->with($subRelation)->select();
|
if ($closure) {
|
||||||
|
call_user_func_array($closure, [ & $model]);
|
||||||
|
}
|
||||||
|
$list = $model->where($where)->with($subRelation)->select();
|
||||||
|
|
||||||
// 组装模型数据
|
// 组装模型数据
|
||||||
$data = [];
|
$data = [];
|
||||||
@@ -602,7 +605,7 @@ class Relation
|
|||||||
// 保存关联表数据
|
// 保存关联表数据
|
||||||
$model = new $this->model;
|
$model = new $this->model;
|
||||||
$id = $model->save($data);
|
$id = $model->save($data);
|
||||||
} elseif (is_numeric($data)) {
|
} elseif (is_numeric($data) || is_string($data)) {
|
||||||
// 根据关联表主键直接写入中间表
|
// 根据关联表主键直接写入中间表
|
||||||
$id = $data;
|
$id = $data;
|
||||||
} elseif ($data instanceof Model) {
|
} elseif ($data instanceof Model) {
|
||||||
@@ -634,7 +637,7 @@ class Relation
|
|||||||
{
|
{
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
$id = $data;
|
$id = $data;
|
||||||
} elseif (is_numeric($data)) {
|
} elseif (is_numeric($data) || is_string($data)) {
|
||||||
// 根据关联表主键直接写入中间表
|
// 根据关联表主键直接写入中间表
|
||||||
$id = $data;
|
$id = $data;
|
||||||
} elseif ($data instanceof Model) {
|
} elseif ($data instanceof Model) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Memcache extends SessionHandler
|
|||||||
protected $handler = null;
|
protected $handler = null;
|
||||||
protected $config = [
|
protected $config = [
|
||||||
'host' => '127.0.0.1', // memcache主机
|
'host' => '127.0.0.1', // memcache主机
|
||||||
'port' => 1121, // memcache端口
|
'port' => 11211, // memcache端口
|
||||||
'expire' => 3600, // session有效期
|
'expire' => 3600, // session有效期
|
||||||
'timeout' => 0, // 连接超时时间(单位:毫秒)
|
'timeout' => 0, // 连接超时时间(单位:毫秒)
|
||||||
'persistent' => true, // 长连接
|
'persistent' => true, // 长连接
|
||||||
@@ -54,7 +54,7 @@ class Memcache extends SessionHandler
|
|||||||
foreach ((array) $hosts as $i => $host) {
|
foreach ((array) $hosts as $i => $host) {
|
||||||
$port = isset($ports[$i]) ? $ports[$i] : $ports[0];
|
$port = isset($ports[$i]) ? $ports[$i] : $ports[0];
|
||||||
$this->config['timeout'] > 0 ?
|
$this->config['timeout'] > 0 ?
|
||||||
$this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) :
|
$this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) :
|
||||||
$this->handler->addServer($host, $port, $this->config['persistent'], 1);
|
$this->handler->addServer($host, $port, $this->config['persistent'], 1);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Memcached extends SessionHandler
|
|||||||
protected $handler = null;
|
protected $handler = null;
|
||||||
protected $config = [
|
protected $config = [
|
||||||
'host' => '127.0.0.1', // memcache主机
|
'host' => '127.0.0.1', // memcache主机
|
||||||
'port' => 1121, // memcache端口
|
'port' => 11211, // memcache端口
|
||||||
'expire' => 3600, // session有效期
|
'expire' => 3600, // session有效期
|
||||||
'timeout' => 0, // 连接超时时间(单位:毫秒)
|
'timeout' => 0, // 连接超时时间(单位:毫秒)
|
||||||
'session_name' => '', // memcache key前缀
|
'session_name' => '', // memcache key前缀
|
||||||
@@ -61,9 +61,9 @@ class Memcached extends SessionHandler
|
|||||||
$servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];
|
$servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];
|
||||||
}
|
}
|
||||||
$this->handler->addServers($servers);
|
$this->handler->addServers($servers);
|
||||||
if('' != $this->config['username']){
|
if ('' != $this->config['username']) {
|
||||||
$this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
|
$this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
|
||||||
$this->handler->setSaslAuthData($this->config['username'], $this->config['password']);
|
$this->handler->setSaslAuthData($this->config['username'], $this->config['password']);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,4 +132,16 @@ class Php
|
|||||||
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置模板引擎
|
||||||
|
* @access private
|
||||||
|
* @param string|array $name 参数名
|
||||||
|
* @param mixed $value 参数值
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function config($name, $value = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,22 @@ class Think
|
|||||||
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置模板引擎
|
||||||
|
* @access private
|
||||||
|
* @param string|array $name 参数名
|
||||||
|
* @param mixed $value 参数值
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function config($name, $value = null)
|
||||||
|
{
|
||||||
|
if (is_array($name)) {
|
||||||
|
$this->template->config($name);
|
||||||
|
} else {
|
||||||
|
$this->template->$name = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function __call($method, $params)
|
public function __call($method, $params)
|
||||||
{
|
{
|
||||||
return call_user_func_array([$this->template, $method], $params);
|
return call_user_func_array([$this->template, $method], $params);
|
||||||
|
|||||||
Reference in New Issue
Block a user