1、更新内核

2、修复模型bug
3、修复后台部分操作的bug
4、清除多余文件
This commit is contained in:
2016-07-07 08:58:01 +08:00
parent f3fff63632
commit 2d3e41037d
43 changed files with 499 additions and 752 deletions

View File

@@ -187,7 +187,7 @@ class App
$reflect = new \ReflectionFunction($function);
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->getFileName() . '[ ' . var_export($vars, true) . ' ]', 'info');
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs($args);
}
@@ -213,7 +213,7 @@ class App
}
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->getFileName() . '[ ' . var_export($args, true) . ' ]', 'info');
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
}
@@ -335,7 +335,7 @@ class App
if (method_exists($instance, '_empty')) {
$method = new \ReflectionMethod($instance, '_empty');
$data = $method->invokeArgs($instance, [$action, '']);
self::$debug && Log::record('[ RUN ] ' . $method->getFileName(), 'info');
self::$debug && Log::record('[ RUN ] ' . $method->__toString(), 'info');
} else {
throw new HttpException(404, 'method not exists:' . (new \ReflectionClass($instance))->getName() . '->' . $action);
}

View File

@@ -132,8 +132,21 @@ class Log
// 检测日志写入权限
return false;
}
$result = self::$driver->save(self::$log);
if (empty(self::$config['level'])) {
// 获取全部日志
$log = self::$log;
} else {
// 记录允许级别
$log = [];
foreach (self::$config['level'] as $level) {
if (isset(self::$log[$level])) {
$log[$level] = self::$log[$level];
}
}
}
$result = self::$driver->save($log);
if ($result) {
self::$log = [];
}
@@ -147,12 +160,19 @@ class Log
* 实时写入日志信息 并支持行为
* @param mixed $msg 调试信息
* @param string $type 信息类型
* @param bool $force 是否强制写入
* @return bool
*/
public static function write($msg, $type = 'log')
public static function write($msg, $type = 'log', $force = false)
{
// 封装日志信息
$log[$type][] = $msg;
if (true === $force || empty(self::$config['level'])) {
$log[$type][] = $msg;
} elseif (in_array($type, self::$config['level'])) {
$log[$type][] = $msg;
} else {
return false;
}
// 监听log_write
Hook::listen('log_write', $log);

View File

@@ -11,6 +11,7 @@
namespace think;
use InvalidArgumentException;
use think\Cache;
use think\Db;
use think\db\Query;
@@ -33,6 +34,7 @@ use think\paginator\Collection as PaginatorCollection;
* @method static integer avg($field = '*') AVG查询
* @method static setField($field, $value = '')
* @method static Query where($field, $op = null, $condition = null) 指定AND查询条件
* @method static static findOrFail($data = null) 查找单条记录 如果不存在则抛出异常
*
*/
abstract class Model implements \JsonSerializable, \ArrayAccess
@@ -171,7 +173,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
{
if (!is_null($relation)) {
// 执行关联查询
return $this->db->relation($relation);
return $this->db()->relation($relation);
}
// 获取关联对象实例
@@ -204,7 +206,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
{}
/**
* 设置数据对象值(不进行修改器处理)
* 设置数据对象值
* @access public
* @param mixed $data 数据或者属性名
* @param mixed $value 值
@@ -212,12 +214,20 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/
public function data($data, $value = null)
{
if (is_object($data)) {
$this->data = get_object_vars($data);
} elseif (is_array($data)) {
$this->data = $data;
} else {
if (is_string($data)) {
$this->data[$data] = $value;
} else {
if (is_object($data)) {
$data = get_object_vars($data);
}
if (true === $value) {
// 数据对象赋值
foreach ($data as $key => $value) {
$this->setAttr($key, $value, $data);
}
} else {
$this->data = $data;
}
}
return $this;
}
@@ -227,6 +237,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @access public
* @param string $name 字段名 留空获取全部
* @return mixed
* @throws InvalidArgumentException
*/
public function getData($name = null)
{
@@ -235,7 +246,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
} elseif (array_key_exists($name, $this->data)) {
return $this->data[$name];
} else {
return false;
throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name);
}
}
@@ -350,10 +361,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @access public
* @param string $name 名称
* @return mixed
* @throws InvalidArgumentException
*/
public function getAttr($name)
{
$value = $this->getData($name);
try {
$notFound = false;
$value = $this->getData($name);
} catch (InvalidArgumentException $e) {
$notFound = true;
$value = null;
}
// 检测属性获取器
$method = 'get' . Loader::parseName($name, 1) . 'Attr';
@@ -362,11 +380,15 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->readTransform($value, $this->type[$name]);
} elseif (false === $value && method_exists($this, $name)) {
// 不存在该字段 获取关联数据
$value = $this->relation()->getRelation($name);
// 保存关联对象值
$this->data[$name] = $value;
} elseif ($notFound) {
if (method_exists($this, $name) && !method_exists('\think\Model', $name)) {
// 不存在该字段 获取关联数据
$value = $this->relation()->getRelation($name);
// 保存关联对象值
$this->data[$name] = $value;
} else {
throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name);
}
}
return $value;
}
@@ -557,7 +579,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 检测字段
if (!empty($this->field)) {
if (true === $this->field) {
$this->field = $this->db->getTableInfo('', 'fields');
$this->field = $this->db()->getTableInfo('', 'fields');
}
foreach ($this->data as $key => $val) {
if (!in_array($key, $this->field)) {
@@ -989,8 +1011,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if ($name instanceof Query) {
return $name;
}
$model = new static();
$params = func_get_args();
$model = new static();
$params = func_get_args();
$params[0] = $model->db();
if ($name instanceof \Closure) {
call_user_func_array($name, $params);
@@ -1277,13 +1299,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/
public function __isset($name)
{
if (array_key_exists($name, $this->data)) {
return true;
} elseif ($this->getAttr($name)) {
return true;
} else {
try {
if (array_key_exists($name, $this->data)) {
return true;
} else {
$this->getAttr($name);
return true;
}
} catch (InvalidArgumentException $e) {
return false;
}
}
/**

View File

@@ -62,7 +62,7 @@ class Request
/**
* @var array 当前路由信息
*/
protected $route = [];
protected $routeInfo = [];
/**
* @var array 当前调度信息
@@ -81,6 +81,7 @@ class Request
protected $get = [];
protected $post = [];
protected $request = [];
protected $route = [];
protected $put;
protected $delete;
protected $session = [];
@@ -608,21 +609,37 @@ class Request
// 自动获取请求变量
switch ($method) {
case 'POST':
$vars = $this->post();
$vars = $this->post(false);
break;
case 'PUT':
$vars = $this->put();
$vars = $this->put(false);
break;
case 'DELETE':
$vars = $this->delete();
$vars = $this->delete(false);
break;
default:
$vars = [];
}
// 当前请求参数和URL地址中的参数合并
$this->param = array_merge($this->get(), $vars);
$this->param = array_merge($this->route(false), $this->get(false), $vars);
}
return $this->input($this->param, $name, $default, $filter);
return false === $name ? $this->param : $this->input($this->param, $name, $default, $filter);
}
/**
* 设置获取获取路由参数
* @access public
* @param string|array $name 变量名
* @param mixed $default 默认值
* @param string|array $filter 过滤方法
* @return mixed
*/
public function route($name = '', $default = null, $filter = null)
{
if (is_array($name)) {
return $this->route = array_merge($this->route, $name);
}
return false === $name ? $this->route : $this->input($this->route, $name, $default, $filter);
}
/**
@@ -640,7 +657,7 @@ class Request
} elseif (empty($this->get)) {
$this->get = $_GET;
}
return $this->input($this->get, $name, $default, $filter);
return false === $name ? $this->get : $this->input($this->get, $name, $default, $filter);
}
/**
@@ -658,7 +675,7 @@ class Request
} elseif (empty($this->post)) {
$this->post = $_POST;
}
return $this->input($this->post, $name, $default, $filter);
return false === $name ? $this->post : $this->input($this->post, $name, $default, $filter);
}
/**
@@ -677,7 +694,7 @@ class Request
if (is_null($this->put)) {
parse_str(file_get_contents('php://input'), $this->put);
}
return $this->input($this->put, $name, $default, $filter);
return false === $name ? $this->put : $this->input($this->put, $name, $default, $filter);
}
/**
@@ -696,7 +713,7 @@ class Request
if (is_null($this->delete)) {
parse_str(file_get_contents('php://input'), $this->delete);
}
return $this->input($this->delete, $name, $default, $filter);
return false === $name ? $this->delete : $this->input($this->delete, $name, $default, $filter);
}
/**
@@ -713,7 +730,7 @@ class Request
} elseif (empty($this->request)) {
$this->request = $_REQUEST;
}
return $this->input($this->request ?: $_REQUEST, $name, $default, $filter);
return false === $name ? $this->request : $this->input($this->request ?: $_REQUEST, $name, $default, $filter);
}
/**
@@ -731,7 +748,7 @@ class Request
} elseif (empty($this->session)) {
$this->session = Session::get();
}
return $this->input($this->session, $name, $default, $filter);
return false === $name ? $this->session : $this->input($this->session, $name, $default, $filter);
}
/**
@@ -749,7 +766,7 @@ class Request
} elseif (empty($this->cookie)) {
$this->cookie = $_COOKIE;
}
return $this->input($this->cookie, $name, $default, $filter);
return false === $name ? $this->cookie : $this->input($this->cookie, $name, $default, $filter);
}
/**
@@ -767,7 +784,7 @@ class Request
} elseif (empty($this->server)) {
$this->server = $_SERVER;
}
return $this->input($this->server, $name, $default, $filter);
return false === $name ? $this->server : $this->input($this->server, $name, $default, $filter);
}
/**
@@ -844,7 +861,7 @@ class Request
} elseif (empty($this->env)) {
$this->env = $_ENV;
}
return $this->input($this->env, strtoupper($name), $default, $filter);
return false === $name ? $this->env : $this->input($this->env, strtoupper($name), $default, $filter);
}
/**
@@ -882,25 +899,6 @@ class Request
return isset($this->header[$name]) ? $this->header[$name] : $default;
}
/**
* 获取PATH_INFO
* @param string $name 数据名称
* @param string $default 默认值
* @param string|array $filter 过滤方法
* @return mixed
*/
public function pathParam($name = '', $default = null, $filter = null)
{
$pathinfo = $this->pathinfo();
if (!empty($pathinfo)) {
$depr = Config::get('pathinfo_depr');
$input = explode($depr, trim($pathinfo, $depr));
return $this->input($input, $name, $default, $filter);
} else {
return $default;
}
}
/**
* 获取变量 支持过滤和默认值
* @param array $data 数据源
@@ -1279,17 +1277,17 @@ class Request
}
/**
* 获取当前请求的路由
* 获取当前请求的路由信息
* @access public
* @param array $route 路由名称
* @return array
*/
public function route($route = [])
public function routeInfo($route = [])
{
if (!empty($route)) {
$this->route = $route;
$this->routeInfo = $route;
} else {
return $this->route;
return $this->routeInfo;
}
}

View File

@@ -193,14 +193,14 @@ class Route
continue;
}
if (0 === strpos($key, '[')) {
$key = substr($key, 1, -1);
$result = ['routes' => $val, 'option' => [], 'pattern' => []];
$key = substr($key, 1, -1);
self::group($key, $val);
} elseif (is_array($val)) {
$result = ['route' => $val[0], 'option' => $val[1], 'pattern' => isset($val[2]) ? $val[2] : []];
self::setRule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []);
} else {
$result = ['route' => $val, 'option' => [], 'pattern' => []];
self::setRule($key, $val, $type);
}
self::$rules[$type][$key] = $result;
}
}
@@ -212,41 +212,64 @@ class Route
* @param string $type 请求类型
* @param array $option 路由参数
* @param array $pattern 变量规则
* @return void
*/
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [])
{
$group = self::$group;
$option = array_merge(self::$option, $option);
$type = strtoupper($type);
if (strpos($type, '|')) {
$option['method'] = $type;
$type = '*';
}
if (is_array($rule)) {
foreach ($rule as $key => $val) {
if (is_numeric($key)) {
$key = array_shift($val);
}
if (is_array($val)) {
$route = $val[0];
$option1 = array_merge($option, $val[1]);
$pattern1 = array_merege($pattern, isset($val[2]) ? $val[2] : []);
} else {
$route = $val;
}
self::setRule($key, $route, $type, isset($option1) ? $option1 : $option, isset($pattern1) ? $pattern1 : $pattern, $group);
}
} else {
self::setRule($rule, $route, $type, $option, $pattern, $group);
}
}
/**
* 设置路由规则
* @access public
* @param string $rule 路由规则
* @param string $route 路由地址
* @param string $type 请求类型
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [], $group = '')
protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '')
{
$group = $group ?: self::$group;
$type = strtoupper($type);
if (strpos($type, '|')) {
foreach (explode('|', $type) as $val) {
self::rule($rule, $route, $val, $option, $pattern, $group);
}
if ('$' == substr($rule, -1, 1)) {
// 是否完整匹配
$option['complete_match'] = true;
$rule = substr($rule, 0, -1);
}
if ('/' != $rule) {
$rule = trim($rule, '/');
}
$vars = self::parseVar($rule);
if ($group) {
self::$rules[$type][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];
} else {
if (is_array($rule)) {
foreach ($rule as $key => $val) {
if (is_numeric($key)) {
$key = array_shift($val);
}
if (is_array($val)) {
$result = ['route' => $val[0], 'option' => array_merge($option, $val[1]), 'pattern' => isset($val[2]) ? $val[2] : []];
} else {
$result = ['route' => $val, 'option' => $option, 'pattern' => $pattern];
}
if ($group) {
self::$rules[$type][$group]['routes'][$key] = [$result['route'], $result['option'], $result['pattern']];
} else {
self::$rules[$type][$key] = $result;
}
}
} else {
if ($group) {
self::$rules[$type][$group]['routes'][$rule] = [$route, $option, $pattern];
} else {
self::$rules[$type][$rule] = ['route' => $route, 'option' => $option, 'pattern' => $pattern];
}
}
self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];
}
}
@@ -290,14 +313,31 @@ class Route
}
$type = strtoupper($type);
if (!empty($name)) {
// 分组
if ($routes instanceof \Closure) {
self::setGroup($name);
call_user_func_array($routes, []);
self::setGroup(null);
self::$rules[$type][$name]['route'] = '';
self::$rules[$type][$name]['var'] = self::parseVar($name);
self::$rules[$type][$name]['option'] = $option;
self::$rules[$type][$name]['pattern'] = $pattern;
} else {
self::$rules[$type][$name] = ['routes' => $routes, 'option' => $option, 'pattern' => $pattern];
foreach ($routes as $key => $val) {
if (is_numeric($key)) {
$key = array_shift($val);
}
if (is_array($val)) {
$route = $val[0];
$option1 = array_merge($option, $val[1]);
$pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []);
} else {
$route = $val;
}
$vars = self::parseVar($key);
$item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => isset($option1) ? $option1 : $option, 'pattern' => isset($pattern1) ? $pattern1 : $pattern];
}
self::$rules[$type][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
}
} else {
if ($routes instanceof \Closure) {
@@ -319,12 +359,11 @@ class Route
* @param string $route 路由地址
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function any($rule, $route = '', $option = [], $pattern = [], $group = '')
public static function any($rule, $route = '', $option = [], $pattern = [])
{
self::rule($rule, $route, '*', $option, $pattern, $group);
self::rule($rule, $route, '*', $option, $pattern);
}
/**
@@ -334,12 +373,11 @@ class Route
* @param string $route 路由地址
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function get($rule, $route = '', $option = [], $pattern = [], $group = '')
public static function get($rule, $route = '', $option = [], $pattern = [])
{
self::rule($rule, $route, 'GET', $option, $pattern, $group);
self::rule($rule, $route, 'GET', $option, $pattern);
}
/**
@@ -349,12 +387,11 @@ class Route
* @param string $route 路由地址
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function post($rule, $route = '', $option = [], $pattern = [], $group = '')
public static function post($rule, $route = '', $option = [], $pattern = [])
{
self::rule($rule, $route, 'POST', $option, $pattern, $group);
self::rule($rule, $route, 'POST', $option, $pattern);
}
/**
@@ -364,12 +401,11 @@ class Route
* @param string $route 路由地址
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function put($rule, $route = '', $option = [], $pattern = [], $group = '')
public static function put($rule, $route = '', $option = [], $pattern = [])
{
self::rule($rule, $route, 'PUT', $option, $pattern, $group);
self::rule($rule, $route, 'PUT', $option, $pattern);
}
/**
@@ -379,12 +415,11 @@ class Route
* @param string $route 路由地址
* @param array $option 路由参数
* @param array $pattern 变量规则
* @param string $group 所属分组
* @return void
*/
public static function delete($rule, $route = '', $option = [], $pattern = [], $group = '')
public static function delete($rule, $route = '', $option = [], $pattern = [])
{
self::rule($rule, $route, 'DELETE', $option, $pattern, $group);
self::rule($rule, $route, 'DELETE', $option, $pattern);
}
/**
@@ -504,12 +539,11 @@ class Route
* @param string $route 路由地址
* @param string $method 请求类型
* @param array $option 路由参数
* @param string $group 路由分组
* @return void
*/
public static function miss($route, $method = '*', $option = [], $group = '')
public static function miss($route, $method = '*', $option = [])
{
self::rule('__miss__', $route, $method, $option, [], $group);
self::rule('__miss__', $route, $method, $option, []);
}
/**
@@ -668,7 +702,6 @@ class Route
// 获取当前请求类型的路由规则
$rules = self::$rules[$request->method()];
if (!empty(self::$rules['*'])) {
// 合并任意请求的路由规则
$rules = array_merge_recursive(self::$rules['*'], $rules);
@@ -686,9 +719,12 @@ class Route
// 路由规则检测
if (!empty($rules)) {
foreach ($rules as $rule => $val) {
$option = isset($val['option']) ? $val['option'] : [];
$pattern = isset($val['pattern']) ? $val['pattern'] : [];
foreach ($rules as $group => $val) {
$rule = $val['rule'];
$route = $val['route'];
$vars = $val['var'];
$option = $val['option'];
$pattern = $val['pattern'];
// 参数有效性检查
if (!self::checkOption($option, $url, $request)) {
@@ -696,79 +732,61 @@ class Route
}
if ('__miss__' == $rule) {
// 指定分组MISS路由
$miss = $val['route'];
$miss = $route;
continue;
}
if (!empty($val['routes'])) {
if (is_array($rule)) {
// 分组路由
if (($pos = strpos($rule, ':')) || ($pos = strpos($rule, '<'))) {
$str = substr($rule, 0, $pos);
if (($pos = strpos($group, ':')) || ($pos = strpos($group, '<'))) {
$str = substr($group, 0, $pos);
} else {
$str = $rule;
$str = $group;
}
if (0 !== strpos($url, $str)) {
continue;
}
$missGroup = false;
// 匹配到路由分组
foreach ($val['routes'] as $key => $route) {
if (is_numeric($key)) {
$key = array_shift($route);
}
// 检查规则路由
if (is_array($route)) {
$option1 = $route[1];
// 检查参数有效性
if (!self::checkOption($option1, $url, $request)) {
continue;
}
$pattern = array_merge($pattern, isset($route[2]) ? $route[2] : []);
$route = $route[0];
$option = array_merge($option, $option1);
}
if ('__miss__' == $key) {
// 指定分组MISS路由
$missGroup = $route;
foreach ($rule as $key => $item) {
$key = $item['rule'];
$route = $item['route'];
$vars = $item['var'];
$option = $item['option'];
$pattern = $item['pattern'];
// 检查参数有效性
if (!self::checkOption($option, $url, $request)) {
continue;
}
$key = $rule . ($key ? '/' . ltrim($key, '/') : '');
if ('__miss__' == $key) {
// 指定分组MISS路由
$missGroup = $item;
continue;
}
$key = $group . '/' . ltrim($key, '/');
$result = self::checkRule($key, $route, $url, $pattern, $option);
if (false !== $result) {
$request->route(['rule' => $key, 'route' => $route, 'pattern' => $pattern, 'option' => $option]);
$request->routeInfo(['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, []);
}
return self::parseRule('', $missGroup, $url, []);
}
} else {
if (is_numeric($rule)) {
$rule = array_shift($val);
}
// 单项路由
$route = !empty($val['route']) ? $val['route'] : '';
// 规则路由
$result = self::checkRule($rule, $route, $url, $pattern, $option);
if (false !== $result) {
$request->route(['rule' => $rule, 'route' => $route, 'pattern' => $pattern, 'option' => $option]);
$request->routeInfo(['rule' => $rule, 'route' => $route, 'pattern' => $pattern, 'option' => $option]);
return $result;
}
}
}
if (isset($miss)) {
// 未匹配所有路由的路由规则处理
if ($miss instanceof \Closure) {
// 执行闭包
return ['type' => 'function', 'function' => $miss, 'params' => []];
} else {
return self::parseRule('', $miss, $url, []);
}
return self::parseRule('', $miss, $url, []);
}
}
return false;
@@ -949,19 +967,16 @@ class Route
$rule = str_replace($depr, '/', $rule);
}
$rule = ltrim($rule, '/');
$len1 = substr_count($url, '/');
$len2 = substr_count($rule, '/');
// 多余参数是否合并
$merge = !empty($option['merge_extra_vars']) ? true : false;
if ($len1 >= $len2 || strpos($rule, '[')) {
if ('$' == substr($rule, -1, 1)) {
if (!empty($option['complete_match'])) {
// 完整匹配
if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) {
return false;
} else {
$rule = substr($rule, 0, -1);
}
}
$pattern = array_merge(self::$pattern, $pattern);
@@ -986,10 +1001,6 @@ class Route
return $result;
}
}
if ($route instanceof \Closure) {
// 执行闭包
return ['type' => 'function', 'function' => $route, 'params' => $match];
}
return self::parseRule($rule, $route, $url, $match, $merge);
}
}
@@ -1148,33 +1159,41 @@ class Route
private static function parseRule($rule, $route, $pathinfo, $matches, $merge = false)
{
// 解析路由规则
$rule = explode('/', $rule);
// 获取URL地址中的参数
$paths = $merge ? explode('/', $pathinfo, count($rule)) : explode('/', $pathinfo);
if ($rule) {
$rule = explode('/', $rule);
// 获取URL地址中的参数
$paths = $merge ? explode('/', $pathinfo, count($rule)) : explode('/', $pathinfo);
foreach ($rule as $item) {
$fun = '';
if (0 === strpos($item, '[:')) {
$item = substr($item, 1, -1);
}
if (0 === strpos($item, ':')) {
$var = substr($item, 1);
$matches[$var] = array_shift($paths);
} else {
// 过滤URL中的静态变量
array_shift($paths);
}
}
} else {
$paths = explode('/', $pathinfo);
}
// 获取路由地址规则
$url = is_array($route) ? $route[0] : $route;
foreach ($rule as $item) {
$fun = '';
if (0 === strpos($item, '[:')) {
$item = substr($item, 1, -1);
}
if (0 === strpos($item, ':')) {
$var = substr($item, 1);
$matches[$var] = array_shift($paths);
} else {
// 过滤URL中的静态变量
array_shift($paths);
}
}
// 替换路由地址中的变量
foreach ($matches as $key => $val) {
if (false !== strpos($url, ':' . $key)) {
$url = str_replace(':' . $key, $val, $url);
unset($matches[$key]);
if (is_string($url)) {
foreach ($matches as $key => $val) {
if (false !== strpos($url, ':' . $key)) {
$url = str_replace(':' . $key, $val, $url);
unset($matches[$key]);
}
}
}
if (0 === strpos($url, '/') || 0 === strpos($url, 'http')) {
if ($url instanceof \Closure) {
// 执行闭包
$result = ['type' => 'function', 'function' => $url, 'params' => $matches];
} elseif (0 === strpos($url, '/') || 0 === strpos($url, 'http')) {
// 路由到重定向地址
$result = ['type' => 'redirect', 'url' => $url, 'status' => (is_array($route) && isset($route[1])) ? $route[1] : 301];
} elseif (0 === strpos($url, '\\')) {
@@ -1235,7 +1254,39 @@ class Route
}
}
// 设置当前请求的参数
Request::instance()->param(array_merge($var, $_GET));
Request::instance()->route($var);
}
// 分析路由规则中的变量
private static function parseVar($rule)
{
// 提取路由规则中的变量
$var = [];
foreach (explode('/', $rule) as $val) {
$optional = false;
if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) {
foreach ($matches[1] as $name) {
if (strpos($name, '?')) {
$name = substr($name, 0, -1);
$optional = true;
} else {
$optional = false;
}
$var[$name] = $optional ? 2 : 1;
}
}
if (0 === strpos($val, '[:')) {
// 可选参数
$optional = true;
$val = substr($val, 1, -1);
}
if (0 === strpos($val, ':')) {
// URL变量
$name = substr($val, 1);
$var[$name] = $optional ? 2 : 1;
}
}
return $var;
}
}

View File

@@ -19,6 +19,9 @@ use think\Route;
class Url
{
// 生成URL地址的root
protected static $root;
/**
* URL生成 支持路由反射
* @param string $url URL表达式
@@ -113,7 +116,7 @@ class Url
// 检测域名
$domain = self::parseDomain($url, $domain);
// URL组装
$url = $domain . Request::instance()->root() . '/' . ltrim($url, '/');
$url = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/');
return $url;
}
@@ -140,7 +143,7 @@ class Url
$url = $module . $controller . '/' . $request->action();
} else {
$path = explode('/', $url);
$action = array_pop($path);
$action = Config::get('url_convert') ? strtolower(array_pop($path)) : array_pop($path);
$controller = empty($path) ? $controller : (Config::get('url_convert') ? Loader::parseName(array_pop($path)) : array_pop($path));
$module = empty($path) ? $module : array_pop($path) . '/';
$url = $module . $controller . '/' . $action;
@@ -258,25 +261,25 @@ class Url
// 生成路由映射并缓存
private static function getRouteAlias()
{
static $item = [];
if (!empty($item)) {
return $item;
}
if ($item = Cache::get('think_route_map')) {
return $item;
}
// 获取路由定义
$rules = Route::getRules();
foreach ($rules as $rule => $val) {
if (!empty($val['routes'])) {
foreach ($val['routes'] as $key => $route) {
if (is_numeric($key)) {
$key = array_shift($route);
}
if (is_array($route)) {
$route = $route[0];
}
$param = [];
foreach ($rules as $group => $val) {
$rule = $val['rule'];
$route = $val['route'];
$vars = $val['var'];
$option = $val['option'];
$pattern = $val['pattern'];
if (is_array($rule)) {
foreach ($rule as $key => $val) {
$key = $val['rule'];
$route = $val['route'];
$var = $val['var'];
$option = $val['option'];
$pattern = $val['pattern'];
$param = [];
if (is_array($route)) {
$route = implode('\\', $route);
} elseif ($route instanceof \Closure) {
@@ -285,11 +288,10 @@ class Url
list($route, $str) = explode('?', $route, 2);
parse_str($str, $param);
}
$var = self::parseVar($rule . '/' . $key);
$item[$route][] = [$rule . '/' . $key, $var, $param];
$var = array_merge($vars, $var);
$item[$route][] = [$group . '/' . $key, $var, $param];
}
} else {
$route = $val['route'];
$param = [];
if (is_array($route)) {
$route = implode('\\', $route);
@@ -299,8 +301,7 @@ class Url
list($route, $str) = explode('?', $route, 2);
parse_str($str, $param);
}
$var = self::parseVar($rule);
$item[$route][] = [$rule, $var, $param];
$item[$route][] = [$rule, $vars, $param];
}
}
@@ -325,45 +326,16 @@ class Url
return $item;
}
// 分析路由规则中的变量
private static function parseVar($rule)
{
// 提取路由规则中的变量
$var = [];
foreach (explode('/', $rule) as $val) {
$optional = false;
if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) {
foreach ($matches[1] as $name) {
if (strpos($name, '?')) {
$name = substr($name, 0, -1);
$optional = true;
} else {
$optional = false;
}
$var[$name] = $optional ? 2 : 1;
}
}
if ('$' == substr($val, -1, 1)) {
$val = substr($val, 0, -1);
}
if (0 === strpos($val, '[:')) {
// 可选参数
$optional = true;
$val = substr($val, 1, -1);
}
if (0 === strpos($val, ':')) {
// URL变量
$name = substr($val, 1);
$var[$name] = $optional ? 2 : 1;
}
}
return $var;
}
// 清空路由别名缓存
public static function clearAliasCache()
{
Cache::rm('think_route_map');
}
// 指定当前生成URL地址的root
public static function root($root)
{
self::$root = $root;
Request::instance()->root($root);
}
}

View File

@@ -38,8 +38,8 @@ class File
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
if (substr($this->options['path'], -1) != '/') {
$this->options['path'] .= '/';
if (substr($this->options['path'], -1) != DS) {
$this->options['path'] .= DS;
}
$this->init();
}
@@ -74,7 +74,7 @@ class File
$dir = '';
$len = $this->options['path_level'];
for ($i = 0; $i < $len; $i++) {
$dir .= $name{$i} . '/';
$dir .= $name{$i} . DS;
}
if (!is_dir($this->options['path'] . $dir)) {
mkdir($this->options['path'] . $dir, 0755, true);

View File

@@ -36,8 +36,8 @@ class Lite
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
if (substr($this->options['path'], -1) != '/') {
$this->options['path'] .= '/';
if (substr($this->options['path'], -1) != DS) {
$this->options['path'] .= DS;
}
}

View File

@@ -964,8 +964,7 @@ class Query
* fragment:url锚点,
* var_page:分页变量,
* list_rows:每页数量
* type:分页类名,
* namespace:分页类命名空间
* type:分页类名
* @return \think\paginator\Collection
* @throws DbException
*/
@@ -1717,8 +1716,8 @@ class Query
* @param array|string|Query|\Closure $data
* @return Collection|false|\PDOStatement|string
* @throws DbException
* @throws Exception
* @throws PDOException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
public function select($data = null)
{
@@ -1789,11 +1788,7 @@ class Query
}
}
} elseif (!empty($options['fail'])) {
if (!empty($this->model)) {
throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options);
} else {
throw new DataNotFoundException('table data not Found:' . $options['table'], $options['table'], $options);
}
$this->throwNotFound($options);
}
return $resultSet;
}
@@ -1804,8 +1799,8 @@ class Query
* @param array|string|Query|\Closure $data
* @return array|false|\PDOStatement|string|Model
* @throws DbException
* @throws Exception
* @throws PDOException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
public function find($data = null)
{
@@ -1874,25 +1869,37 @@ class Query
}
}
} elseif (!empty($options['fail'])) {
if (!empty($this->model)) {
throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options);
} else {
throw new DataNotFoundException('table data not Found:' . $options['table'], $options['table'], $options);
}
$this->throwNotFound($options);
} else {
$data = null;
}
return $data;
}
/**
* 查询失败 抛出异常
* @access public
* @param array $options 查询参数
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
protected function throwNotFound($options = [])
{
if (!empty($this->model)) {
throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options);
} else {
throw new DataNotFoundException('table data not Found:' . $options['table'], $options['table'], $options);
}
}
/**
* 查找多条记录 如果不存在则抛出异常
* @access public
* @param array|string|Query|\Closure $data
* @return array|\PDOStatement|string|Model
* @throws DbException
* @throws Exception
* @throws PDOException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
public function selectOrFail($data = null)
{
@@ -1905,8 +1912,8 @@ class Query
* @param array|string|Query|\Closure $data
* @return array|\PDOStatement|string|Model
* @throws DbException
* @throws Exception
* @throws PDOException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
public function findOrFail($data = null)
{

View File

@@ -31,7 +31,7 @@ class Mysql extends Builder
$key = trim($key);
if (strpos($key, '$.') && false === strpos($key, '(')) {
// JSON字段支持
list($field, $name) = explode($key, '$.');
list($field, $name) = explode('$.', $key);
$key = 'jsn_extract(' . $field . ', \'$.\'.' . $name . ')';
}
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {

View File

@@ -9,9 +9,7 @@
// | Author: luofei614 <weibo.com/luofei614>
// +----------------------------------------------------------------------
namespace think\debug;
use think\Response;
namespace think\log\driver;
/**
* github: https://github.com/luofei614/SocketLog
@@ -57,11 +55,10 @@ class Socket
/**
* 调试输出接口
* @access public
* @param Response $response Response对象
* @param array $log 日志信息
* @return bool
*/
public function output(Response $response, array $log = [])
public function save(array $log = [])
{
if (!$this->check()) {
return false;

View File

@@ -66,23 +66,23 @@ class Bootstrap extends Paginator
'last' => null
];
$length = 3;
$side = 3;
$window = $side * 2;
if ($this->lastPage < $length * 4) {
if ($this->lastPage < $window + 6) {
$block['first'] = $this->getUrlRange(1, $this->lastPage);
} elseif ($this->currentPage <= $length * 2) {
$block['first'] = $this->getUrlRange(1, $length * 2 + 2);
} elseif ($this->currentPage <= $window) {
$block['first'] = $this->getUrlRange(1, $window + 2);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
} elseif ($this->currentPage > ($this->lastPage - $length * 2)) {
} elseif ($this->currentPage > ($this->lastPage - $window)) {
$block['first'] = $this->getUrlRange(1, 2);
$block['last'] = $this->getUrlRange($this->lastPage - $length * 2 + 2, $this->lastPage);
$block['last'] = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage);
} else {
$block['first'] = $this->getUrlRange(1, 2);
$block['slider'] = $this->getUrlRange($this->currentPage - $length, $this->currentPage + $length);
$block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side);
$block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
}
$html = '';
if (is_array($block['first'])) {
@@ -132,7 +132,7 @@ class Bootstrap extends Paginator
* 生成一个可点击的按钮
*
* @param string $url
* @param int $page
* @param int $page
* @return string
*/
protected function getAvailablePageWrapper($url, $page)
@@ -193,7 +193,7 @@ class Bootstrap extends Paginator
* 生成普通页码按钮
*
* @param string $url
* @param int $page
* @param int $page
* @return string
*/
protected function getPageLinkWrapper($url, $page)

View File

@@ -19,6 +19,7 @@ use think\exception\HttpResponseException;
use think\Request;
use think\Response;
use think\response\Redirect;
use think\Url;
use think\View as ViewTemplate;
trait Jump
@@ -39,11 +40,16 @@ trait Jump
$code = $msg;
$msg = '';
}
if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
$url = $_SERVER["HTTP_REFERER"];
} else {
$url = preg_match('/^(https?:|\/)/', $url) ? $url : Url::build($url);
}
$result = [
'code' => $code,
'msg' => $msg,
'data' => $data,
'url' => is_null($url) && isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $url,
'url' => $url,
'wait' => $wait,
];
@@ -71,11 +77,16 @@ trait Jump
$code = $msg;
$msg = '';
}
if (is_null($url)) {
$url = 'javascript:history.back(-1);';
} else {
$url = preg_match('/^(https?:|\/)/', $url) ? $url : Url::build($url);
}
$result = [
'code' => $code,
'msg' => $msg,
'data' => $data,
'url' => is_null($url) ? 'javascript:history.back(-1);' : $url,
'url' => $url,
'wait' => $wait,
];
@@ -104,7 +115,7 @@ trait Jump
'msg' => $msg,
'time' => $_SERVER['REQUEST_TIME'],
'data' => $data,
];
];
$type = $type ?: $this->getResponseType();
return Response::create($result, $type);
}