mirror of
https://gitee.com/apiadmin/ApiAdmin.git
synced 2025-04-06 03:58:00 +08:00
updated 升级ThinkPHP核心包到V5.0.3版本
This commit is contained in:
parent
5b5d2b3763
commit
3afec99c92
@ -9,7 +9,7 @@
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
define('THINK_VERSION', '5.0.2');
|
||||
define('THINK_VERSION', '5.0.3');
|
||||
define('THINK_START_TIME', microtime(true));
|
||||
define('THINK_START_MEM', memory_get_usage());
|
||||
define('EXT', '.php');
|
||||
|
@ -103,6 +103,10 @@ return [
|
||||
'var_ajax' => '_ajax',
|
||||
// 表单pjax伪装变量
|
||||
'var_pjax' => '_pjax',
|
||||
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
|
||||
'request_cache' => false,
|
||||
// 请求缓存有效期
|
||||
'request_cache_expire' => null,
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 模板设置
|
||||
|
@ -117,7 +117,7 @@ if (!function_exists('input')) {
|
||||
* @param string $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
function input($key = '', $default = null, $filter = null)
|
||||
function input($key = '', $default = null, $filter = '')
|
||||
{
|
||||
if (0 === strpos($key, '?')) {
|
||||
$key = substr($key, 1);
|
||||
@ -125,10 +125,9 @@ if (!function_exists('input')) {
|
||||
}
|
||||
if ($pos = strpos($key, '.')) {
|
||||
// 指定参数来源
|
||||
$method = substr($key, 0, $pos);
|
||||
if (in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
|
||||
$key = substr($key, $pos + 1);
|
||||
} else {
|
||||
list($method, $key) = explode('.', $key);
|
||||
if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
|
||||
$key = $method . '.' . $key;
|
||||
$method = 'param';
|
||||
}
|
||||
} else {
|
||||
@ -359,12 +358,17 @@ if (!function_exists('cache')) {
|
||||
// 缓存初始化
|
||||
return Cache::connect($name);
|
||||
}
|
||||
if ('' === $value) {
|
||||
if (is_null($name)) {
|
||||
return Cache::clear($value);
|
||||
} elseif ('' === $value) {
|
||||
// 获取缓存
|
||||
return 0 === strpos($name, '?') ? Cache::has(substr($name, 1)) : Cache::get($name);
|
||||
} elseif (is_null($value)) {
|
||||
// 删除缓存
|
||||
return Cache::rm($name);
|
||||
} elseif (0 === strpos($name, '?') && '' !== $value) {
|
||||
$expire = is_numeric($options) ? $options : null;
|
||||
return Cache::remember(substr($name, 1), $value, $expire);
|
||||
} else {
|
||||
// 缓存数据
|
||||
if (is_array($options)) {
|
||||
|
@ -127,6 +127,8 @@ class App
|
||||
|
||||
// 监听app_begin
|
||||
Hook::listen('app_begin', $dispatch);
|
||||
// 请求缓存检查
|
||||
$request->cache($config['request_cache'], $config['request_cache_expire']);
|
||||
|
||||
switch ($dispatch['type']) {
|
||||
case 'redirect':
|
||||
@ -377,12 +379,14 @@ class App
|
||||
// 获取当前操作名
|
||||
$action = $actionName . $config['action_suffix'];
|
||||
|
||||
$vars = [];
|
||||
if (is_callable([$instance, $action])) {
|
||||
// 执行操作方法
|
||||
$call = [$instance, $action];
|
||||
} elseif (is_callable([$instance, '_empty'])) {
|
||||
// 空操作
|
||||
$call = [$instance, '_empty'];
|
||||
$vars = [$action];
|
||||
} else {
|
||||
// 操作不存在
|
||||
throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
|
||||
@ -390,9 +394,7 @@ class App
|
||||
|
||||
Hook::listen('action_begin', $call);
|
||||
|
||||
$data = self::invokeMethod($call);
|
||||
|
||||
return $data;
|
||||
return self::invokeMethod($call, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,6 +59,7 @@ class Config
|
||||
self::$config[$range] = [];
|
||||
}
|
||||
if (is_file($file)) {
|
||||
$name = strtolower($name);
|
||||
$type = pathinfo($file, PATHINFO_EXTENSION);
|
||||
if ('php' == $type) {
|
||||
return self::set(include $file, $name, $range);
|
||||
|
@ -42,6 +42,9 @@ use think\paginator\Collection as PaginatorCollection;
|
||||
* @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行
|
||||
* @method PaginatorCollection paginate(integer $listRows = 15, mixed $simple = false, array $config = []) static 分页查询
|
||||
* @method mixed transaction(callable $callback) static 执行数据库事务
|
||||
* @method void startTrans() static 启动事务
|
||||
* @method void commit() static 用于非自动提交状态下面的查询提交
|
||||
* @method void rollback() static 事务回滚
|
||||
* @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句
|
||||
*/
|
||||
class Db
|
||||
|
@ -39,7 +39,7 @@ class File extends SplFileObject
|
||||
public function __construct($filename, $mode = 'r')
|
||||
{
|
||||
parent::__construct($filename, $mode);
|
||||
$this->filename = $this->getRealPath();
|
||||
$this->filename = $this->getRealPath() ?: $this->getPathname();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,6 +101,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
protected $failException = false;
|
||||
// 全局查询范围
|
||||
protected $useGlobalScope = true;
|
||||
// 是否采用批量验证
|
||||
protected $batchValidate = false;
|
||||
|
||||
/**
|
||||
* 初始化过的模型.
|
||||
@ -741,7 +743,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
// 数据批量验证
|
||||
$validate = $this->validate;
|
||||
foreach ($dataSet as $data) {
|
||||
if (!$this->validate($validate)->validateData($data)) {
|
||||
if (!$this->validateData($data, $validate)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -854,9 +856,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
* @access public
|
||||
* @param array|string|bool $rule 验证规则 true表示自动读取验证器类
|
||||
* @param array $msg 提示信息
|
||||
* @param bool $batch 批量验证
|
||||
* @return $this
|
||||
*/
|
||||
public function validate($rule = true, $msg = [])
|
||||
public function validate($rule = true, $msg = [], $batch = false)
|
||||
{
|
||||
if (is_array($rule)) {
|
||||
$this->validate = [
|
||||
@ -866,6 +869,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
} else {
|
||||
$this->validate = true === $rule ? $this->name : $rule;
|
||||
}
|
||||
$this->batchValidate = $batch;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -885,12 +889,15 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
* 自动验证数据
|
||||
* @access protected
|
||||
* @param array $data 验证数据
|
||||
* @param mixed $rule 验证规则
|
||||
* @param bool $batch 批量验证
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateData($data)
|
||||
protected function validateData($data, $rule = null, $batch = null)
|
||||
{
|
||||
if (!empty($this->validate)) {
|
||||
$info = $this->validate;
|
||||
$info = is_null($rule) ? $this->validate : $rule;
|
||||
|
||||
if (!empty($info)) {
|
||||
if (is_array($info)) {
|
||||
$validate = Loader::validate();
|
||||
$validate->rule($info['rule']);
|
||||
@ -905,7 +912,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
$validate->scene($scene);
|
||||
}
|
||||
}
|
||||
if (!$validate->check($data)) {
|
||||
$batch = is_null($batch) ? $this->batchValidate : $batch;
|
||||
|
||||
if (!$validate->batch($batch)->check($data)) {
|
||||
$this->error = $validate->getError();
|
||||
if ($this->failException) {
|
||||
throw new ValidateException($this->error);
|
||||
@ -1356,19 +1365,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
||||
|
||||
public static function __callStatic($method, $params)
|
||||
{
|
||||
$query = self::getDb();
|
||||
$query = (new static())->db();
|
||||
return call_user_func_array([$query, $method], $params);
|
||||
}
|
||||
|
||||
protected static function getDb()
|
||||
{
|
||||
$model = get_called_class();
|
||||
if (!isset(self::$links[$model])) {
|
||||
self::$links[$model] = (new static())->db();
|
||||
}
|
||||
return self::$links[$model];
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改器 设置数据对象的值
|
||||
* @access public
|
||||
|
@ -121,6 +121,8 @@ class Request
|
||||
protected $input;
|
||||
// 请求缓存
|
||||
protected $cache;
|
||||
// 缓存是否检查
|
||||
protected $isCheckCache;
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
@ -607,7 +609,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function param($name = '', $default = null, $filter = null)
|
||||
public function param($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->param)) {
|
||||
$method = $this->method(true);
|
||||
@ -644,7 +646,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function route($name = '', $default = null, $filter = null)
|
||||
public function route($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (is_array($name)) {
|
||||
$this->param = [];
|
||||
@ -661,7 +663,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($name = '', $default = null, $filter = null)
|
||||
public function get($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->get)) {
|
||||
$this->get = $_GET;
|
||||
@ -681,7 +683,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($name = '', $default = null, $filter = null)
|
||||
public function post($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->post)) {
|
||||
$this->post = $_POST;
|
||||
@ -701,7 +703,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function put($name = '', $default = null, $filter = null)
|
||||
public function put($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (is_null($this->put)) {
|
||||
$content = $this->input;
|
||||
@ -727,7 +729,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($name = '', $default = null, $filter = null)
|
||||
public function delete($name = '', $default = null, $filter = '')
|
||||
{
|
||||
return $this->put($name, $default, $filter);
|
||||
}
|
||||
@ -740,7 +742,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function patch($name = '', $default = null, $filter = null)
|
||||
public function patch($name = '', $default = null, $filter = '')
|
||||
{
|
||||
return $this->put($name, $default, $filter);
|
||||
}
|
||||
@ -752,7 +754,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function request($name = '', $default = null, $filter = null)
|
||||
public function request($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->request)) {
|
||||
$this->request = $_REQUEST;
|
||||
@ -772,7 +774,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function session($name = '', $default = null, $filter = null)
|
||||
public function session($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->session)) {
|
||||
$this->session = Session::get();
|
||||
@ -791,7 +793,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function cookie($name = '', $default = null, $filter = null)
|
||||
public function cookie($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->cookie)) {
|
||||
$this->cookie = $_COOKIE;
|
||||
@ -810,7 +812,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function server($name = '', $default = null, $filter = null)
|
||||
public function server($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->server)) {
|
||||
$this->server = $_SERVER;
|
||||
@ -888,7 +890,7 @@ class Request
|
||||
* @param string|array $filter 过滤方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function env($name = '', $default = null, $filter = null)
|
||||
public function env($name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (empty($this->env)) {
|
||||
$this->env = $_ENV;
|
||||
@ -947,7 +949,7 @@ class Request
|
||||
* @param string|array $filter 过滤函数
|
||||
* @return mixed
|
||||
*/
|
||||
public function input($data = [], $name = '', $default = null, $filter = null)
|
||||
public function input($data = [], $name = '', $default = null, $filter = '')
|
||||
{
|
||||
if (false === $name) {
|
||||
// 获取原始数据
|
||||
@ -976,13 +978,17 @@ class Request
|
||||
}
|
||||
|
||||
// 解析过滤器
|
||||
$filter = $filter ?: $this->filter;
|
||||
|
||||
if (is_string($filter)) {
|
||||
$filter = explode(',', $filter);
|
||||
if (is_null($filter)) {
|
||||
$filter = [];
|
||||
} else {
|
||||
$filter = (array) $filter;
|
||||
$filter = $filter ?: $this->filter;
|
||||
if (is_string($filter)) {
|
||||
$filter = explode(',', $filter);
|
||||
} else {
|
||||
$filter = (array) $filter;
|
||||
}
|
||||
}
|
||||
|
||||
$filter[] = $default;
|
||||
if (is_array($data)) {
|
||||
array_walk_recursive($data, [$this, 'filterValue'], $filter);
|
||||
@ -1471,15 +1477,34 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取或者设置缓存
|
||||
* 设置当前地址的请求缓存
|
||||
* @access public
|
||||
* @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id
|
||||
* @param mixed $expire 缓存有效期
|
||||
* @return mixed
|
||||
* @return void
|
||||
*/
|
||||
public function cache($key, $expire = null)
|
||||
{
|
||||
if ($this->isGet()) {
|
||||
if (false !== $key && $this->isGet() && !$this->isCheckCache) {
|
||||
// 标记请求缓存检查
|
||||
$this->isCheckCache = true;
|
||||
if (false === $expire) {
|
||||
// 关闭当前缓存
|
||||
return;
|
||||
}
|
||||
if ($key instanceof \Closure) {
|
||||
$key = call_user_func_array($key, [$this]);
|
||||
} elseif (true === $key) {
|
||||
// 自动缓存功能
|
||||
$key = '__URL__';
|
||||
} elseif (strpos($key, '|')) {
|
||||
list($key, $fun) = explode('|', $key);
|
||||
}
|
||||
// 特殊规则替换
|
||||
if (false !== strpos($key, '__')) {
|
||||
$key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__'], [$this->module, $this->controller, $this->action, md5($this->url())], $key);
|
||||
}
|
||||
|
||||
if (false !== strpos($key, ':')) {
|
||||
$param = $this->param();
|
||||
foreach ($param as $item => $val) {
|
||||
@ -1487,9 +1512,6 @@ class Request
|
||||
$key = str_replace(':' . $item, $val, $key);
|
||||
}
|
||||
}
|
||||
} elseif ('__URL__' == $key) {
|
||||
// 当前URL地址作为缓存标识
|
||||
$key = md5($this->url());
|
||||
} elseif (strpos($key, ']')) {
|
||||
if ('[' . $this->ext() . ']' == $key) {
|
||||
// 缓存某个后缀的请求
|
||||
@ -1498,6 +1520,9 @@ class Request
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isset($fun)) {
|
||||
$key = $fun($key);
|
||||
}
|
||||
|
||||
if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) {
|
||||
// 读取缓存
|
||||
@ -1514,7 +1539,7 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取缓存设置
|
||||
* 读取请求缓存设置
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
|
@ -69,6 +69,8 @@ class Route
|
||||
private static $domainRule;
|
||||
// 当前域名
|
||||
private static $domain;
|
||||
// 当前路由执行过程中的参数
|
||||
private static $option = [];
|
||||
|
||||
/**
|
||||
* 注册变量规则
|
||||
@ -127,7 +129,7 @@ class Route
|
||||
* 设置路由绑定
|
||||
* @access public
|
||||
* @param mixed $bind 绑定信息
|
||||
* @param string $type 绑定类型 默认为module 支持 namespace class
|
||||
* @param string $type 绑定类型 默认为module 支持 namespace class controller
|
||||
* @return mixed
|
||||
*/
|
||||
public static function bind($bind, $type = 'module')
|
||||
@ -302,12 +304,12 @@ class Route
|
||||
$rule = substr($rule, 0, -1);
|
||||
}
|
||||
|
||||
if ('/' != $rule) {
|
||||
if ('/' != $rule || $group) {
|
||||
$rule = trim($rule, '/');
|
||||
}
|
||||
$vars = self::parseVar($rule);
|
||||
if (isset($name)) {
|
||||
$key = $group ? $group . '/' . $rule : $rule;
|
||||
$key = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
|
||||
self::name(strtolower($name), [$key, $vars, self::$domain]);
|
||||
}
|
||||
if ($group) {
|
||||
@ -341,6 +343,27 @@ class Route
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前执行的参数信息
|
||||
* @access public
|
||||
* @param array $options 参数信息
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function setOption($options = [])
|
||||
{
|
||||
self::$option[] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前执行的所有参数信息
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getOption()
|
||||
{
|
||||
return self::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的分组信息
|
||||
* @access public
|
||||
@ -425,10 +448,11 @@ class Route
|
||||
$options['complete_match'] = true;
|
||||
$key = substr($key, 0, -1);
|
||||
}
|
||||
$key = trim($key, '/');
|
||||
$vars = self::parseVar($key);
|
||||
$item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns];
|
||||
// 设置路由标识
|
||||
self::name($route, [$name . '/' . $key, $vars, self::$domain]);
|
||||
self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain]);
|
||||
}
|
||||
self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
|
||||
}
|
||||
@ -578,7 +602,8 @@ class Route
|
||||
} elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) {
|
||||
$val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]);
|
||||
}
|
||||
$item = ltrim($rule . $val[1], '/');
|
||||
$item = ltrim($rule . $val[1], '/');
|
||||
$option['rest'] = $key;
|
||||
self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern);
|
||||
}
|
||||
}
|
||||
@ -637,7 +662,7 @@ class Route
|
||||
* rest方法定义和修改
|
||||
* @access public
|
||||
* @param string $name 方法名称
|
||||
* @param array $resourece 资源
|
||||
* @param array $resource 资源
|
||||
* @return void
|
||||
*/
|
||||
public static function rest($name, $resource = [])
|
||||
@ -833,6 +858,7 @@ class Route
|
||||
$rule = self::getRouteExpress($item);
|
||||
}
|
||||
if (!empty($rule['route']) && self::checkOption($rule['option'], $request)) {
|
||||
self::setOption($rule['option']);
|
||||
return self::parseRule($item, $rule['route'], $url, $rule['option']);
|
||||
}
|
||||
}
|
||||
@ -896,7 +922,7 @@ class Route
|
||||
if (is_string($str) && $str && 0 !== strpos(str_replace('|', '/', $url), $str)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
self::setOption($option);
|
||||
$result = self::checkRoute($request, $rule, $url, $depr, $key, $option);
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
@ -911,6 +937,8 @@ class Route
|
||||
if ($group) {
|
||||
$rule = $group . ($rule ? '/' . ltrim($rule, '/') : '');
|
||||
}
|
||||
|
||||
self::setOption($option);
|
||||
if (isset($options['bind_model']) && isset($option['bind_model'])) {
|
||||
$option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']);
|
||||
}
|
||||
@ -997,6 +1025,9 @@ class Route
|
||||
case 'class':
|
||||
// 绑定到类
|
||||
return self::bindToClass($url, $bind, $depr);
|
||||
case 'controller':
|
||||
// 绑定到控制器类
|
||||
return self::bindToController($url, $bind, $depr);
|
||||
case 'namespace':
|
||||
// 绑定到命名空间
|
||||
return self::bindToNamespace($url, $bind, $depr);
|
||||
@ -1041,7 +1072,7 @@ class Route
|
||||
if (!empty($array[2])) {
|
||||
self::parseUrlParams($array[2]);
|
||||
}
|
||||
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method]];
|
||||
return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method]];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1091,14 +1122,16 @@ class Route
|
||||
*/
|
||||
private static function checkOption($option, $request)
|
||||
{
|
||||
// 请求类型检测
|
||||
if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method()))
|
||||
|| (!empty($option['ajax']) && !$request->isAjax()) // Ajax检测
|
||||
|| (!empty($option['pjax']) && !$request->isPjax()) // Pjax检测
|
||||
|| (isset($option['ajax']) && $option['ajax'] && !$request->isAjax()) // Ajax检测
|
||||
|| (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测
|
||||
|| (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测
|
||||
|| (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测
|
||||
|| (isset($option['ext']) && false === stripos($option['ext'], $request->ext())) // 伪静态后缀检测
|
||||
|| (isset($option['deny_ext']) && false !== stripos($option['deny_ext'], $request->ext()))
|
||||
|| (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测
|
||||
|| (!empty($option['https']) && !$request->isSsl()) // https检测
|
||||
|| (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测
|
||||
|| (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测
|
||||
|| (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'])) // 行为检测
|
||||
|| (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测
|
||||
) {
|
||||
@ -1184,7 +1217,9 @@ class Route
|
||||
$find = false;
|
||||
foreach ($path as $val) {
|
||||
$item[] = $val;
|
||||
if (is_file($dir . DS . str_replace('.', DS, $val) . $suffix . EXT)) {
|
||||
$file = $dir . DS . str_replace('.', DS, $val) . $suffix . EXT;
|
||||
$file = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT;
|
||||
if (is_file($file)) {
|
||||
$find = true;
|
||||
break;
|
||||
} else {
|
||||
@ -1370,7 +1405,6 @@ class Route
|
||||
foreach ($matches as $key => $val) {
|
||||
if (false !== strpos($route, ':' . $key)) {
|
||||
$route = str_replace(':' . $key, $val, $route);
|
||||
unset($matches[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1457,7 +1491,7 @@ class Route
|
||||
$result = self::parseModule($route);
|
||||
}
|
||||
// 开启请求缓存
|
||||
if ($request->isGet() && !empty($option['cache'])) {
|
||||
if ($request->isGet() && isset($option['cache'])) {
|
||||
$cache = $option['cache'];
|
||||
if (is_array($cache)) {
|
||||
list($key, $expire) = $cache;
|
||||
|
@ -20,6 +20,7 @@ class Url
|
||||
{
|
||||
// 生成URL地址的root
|
||||
protected static $root;
|
||||
protected static $bindCheck;
|
||||
|
||||
/**
|
||||
* URL生成 支持路由反射
|
||||
@ -31,7 +32,7 @@ class Url
|
||||
*/
|
||||
public static function build($url = '', $vars = '', $suffix = true, $domain = false)
|
||||
{
|
||||
if (false === $domain && Config::get('url_domain_deploy')) {
|
||||
if (false === $domain && Route::rules('domain')) {
|
||||
$domain = true;
|
||||
}
|
||||
// 解析URL
|
||||
@ -80,7 +81,7 @@ class Url
|
||||
// 匹配路由命名标识
|
||||
$url = $match[0];
|
||||
// 替换可选分隔符
|
||||
$url = preg_replace(['/\((\W)\?\)$/', '/\((\W)\?\)/'], ['', '\1'], $url);
|
||||
$url = preg_replace(['/(\W)\?$/', '/(\W)\?/'], ['', '\1'], $url);
|
||||
if (!empty($match[1])) {
|
||||
$domain = $match[1];
|
||||
}
|
||||
@ -112,11 +113,13 @@ class Url
|
||||
}
|
||||
|
||||
// 检测URL绑定
|
||||
$type = Route::getBind('type');
|
||||
if ($type) {
|
||||
$bind = Route::getBind($type);
|
||||
if (0 === strpos($url, $bind)) {
|
||||
$url = substr($url, strlen($bind) + 1);
|
||||
if (!self::$bindCheck) {
|
||||
$type = Route::getBind('type');
|
||||
if ($type) {
|
||||
$bind = Route::getBind($type);
|
||||
if (0 === strpos($url, $bind)) {
|
||||
$url = substr($url, strlen($bind) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 还原URL分隔符
|
||||
@ -152,7 +155,8 @@ class Url
|
||||
// 检测域名
|
||||
$domain = self::parseDomain($url, $domain);
|
||||
// URL组装
|
||||
$url = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/');
|
||||
$url = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/');
|
||||
self::$bindCheck = false;
|
||||
return $url;
|
||||
}
|
||||
|
||||
@ -171,16 +175,29 @@ class Url
|
||||
$url = substr($url, 1);
|
||||
} else {
|
||||
// 解析到 模块/控制器/操作
|
||||
$module = $request->module();
|
||||
if (true === $domain) {
|
||||
$domains = Route::rules('domain');
|
||||
$module = $request->module();
|
||||
$domains = Route::rules('domain');
|
||||
if (true === $domain && 2 == substr_count($url, '/')) {
|
||||
$current = $request->host();
|
||||
$match = [];
|
||||
$pos = [];
|
||||
foreach ($domains as $key => $item) {
|
||||
if (isset($item['[bind]']) && 0 === strpos($url, $item['[bind]'][0])) {
|
||||
$url = substr($url, strlen($item['[bind]'][0]) + 1);
|
||||
$domain = $key;
|
||||
$module = '';
|
||||
$pos[$key] = strlen($item['[bind]'][0]) + 1;
|
||||
$match[] = $key;
|
||||
$module = '';
|
||||
}
|
||||
}
|
||||
if ($match) {
|
||||
$domain = current($match);
|
||||
foreach ($match as $item) {
|
||||
if (0 === strpos($current, $item)) {
|
||||
$domain = $item;
|
||||
}
|
||||
}
|
||||
self::$bindCheck = true;
|
||||
$url = substr($url, $pos[$domain]);
|
||||
}
|
||||
} elseif ($domain) {
|
||||
if (isset($domains[$domain]['[bind]'][0])) {
|
||||
$bindModule = $domains[$domain]['[bind]'][0];
|
||||
@ -212,15 +229,15 @@ class Url
|
||||
if (!$domain) {
|
||||
return '';
|
||||
}
|
||||
$request = Request::instance();
|
||||
$request = Request::instance();
|
||||
$rootDomain = Config::get('url_domain_root');
|
||||
if (true === $domain) {
|
||||
// 自动判断域名
|
||||
$domain = $request->host();
|
||||
if (Config::get('url_domain_deploy')) {
|
||||
// 根域名
|
||||
$urlDomainRoot = Config::get('url_domain_root');
|
||||
$domains = Route::rules('domain');
|
||||
$route_domain = array_keys($domains);
|
||||
|
||||
$domains = Route::rules('domain');
|
||||
if ($domains) {
|
||||
$route_domain = array_keys($domains);
|
||||
foreach ($route_domain as $domain_prefix) {
|
||||
if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) {
|
||||
foreach ($domains as $key => $rule) {
|
||||
@ -229,13 +246,13 @@ class Url
|
||||
$url = ltrim($url, $rule);
|
||||
$domain = $key;
|
||||
// 生成对应子域名
|
||||
if (!empty($urlDomainRoot)) {
|
||||
$domain .= $urlDomainRoot;
|
||||
if (!empty($rootDomain)) {
|
||||
$domain .= $rootDomain;
|
||||
}
|
||||
break;
|
||||
} else if (false !== strpos($key, '*')) {
|
||||
if (!empty($urlDomainRoot)) {
|
||||
$domain .= $urlDomainRoot;
|
||||
if (!empty($rootDomain)) {
|
||||
$domain .= $rootDomain;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -243,13 +260,15 @@ class Url
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (!strpos($domain, '.')) {
|
||||
$rootDomain = Config::get('url_domain_root');
|
||||
|
||||
} else {
|
||||
if (empty($rootDomain)) {
|
||||
$host = $request->host();
|
||||
$rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host;
|
||||
}
|
||||
$domain .= '.' . $rootDomain;
|
||||
if (!strpos($domain, $rootDomain)) {
|
||||
$domain .= '.' . $rootDomain;
|
||||
}
|
||||
}
|
||||
return ($request->isSsl() ? 'https://' : 'http://') . $domain;
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ abstract class Connection
|
||||
$sql . ' ');
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
return rtrim($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -507,22 +507,24 @@ class Query
|
||||
* MIN查询
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @return float|int
|
||||
* @return mixed
|
||||
*/
|
||||
public function min($field = '*')
|
||||
{
|
||||
return $this->value('MIN(' . $field . ') AS tp_min', 0) + 0;
|
||||
$value = $this->value('MIN(' . $field . ') AS tp_min', 0);
|
||||
return is_numeric($value) ? $value + 0 : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* MAX查询
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @return float|int
|
||||
* @return mixed
|
||||
*/
|
||||
public function max($field = '*')
|
||||
{
|
||||
return $this->value('MAX(' . $field . ') AS tp_max', 0) + 0;
|
||||
$value = $this->value('MAX(' . $field . ') AS tp_max', 0);
|
||||
return is_numeric($value) ? $value + 0 : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -659,35 +661,53 @@ class Query
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 传入的表名为数组
|
||||
if (is_array($join)) {
|
||||
if (0 !== $key = key($join)) {
|
||||
// 设置了键名则键名为表名,键值作为表的别名
|
||||
$table = [$key => array_shift($join)];
|
||||
$this->alias($table);
|
||||
} else {
|
||||
$table = array_shift($join);
|
||||
}
|
||||
} else {
|
||||
$prefix = $this->prefix;
|
||||
$join = trim($join);
|
||||
if ($prefix && false === strpos($join, ' ') && false === strpos($join, '(') && false === strpos($join, '.') && 0 !== strpos($join, $prefix) && 0 !== strpos($join, '__')) {
|
||||
$table = $this->getTable($join);
|
||||
$table = [$table => $join];
|
||||
$this->alias($table);
|
||||
} elseif (strpos($join, ' ') && !strpos($join, ')')) {
|
||||
list($table, $alias) = explode(' ', $join);
|
||||
$table = [$table => $alias];
|
||||
$this->alias($table);
|
||||
} else {
|
||||
$table = $join;
|
||||
}
|
||||
}
|
||||
$table = $this->getJoinTable($join);
|
||||
|
||||
$this->options['join'][] = [$table, strtoupper($type), $condition];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Join表名及别名 支持
|
||||
* ['prefix_table或者子查询'=>'alias'] 'prefix_table alias' 'table alias'
|
||||
* @access public
|
||||
* @param array|string $join
|
||||
* @return array|string
|
||||
*/
|
||||
protected function getJoinTable($join, &$alias = null)
|
||||
{
|
||||
// 传入的表名为数组
|
||||
if (is_array($join)) {
|
||||
list($table, $alias) = each($join);
|
||||
} else {
|
||||
$join = trim($join);
|
||||
if (false !== strpos($join, '(')) {
|
||||
// 使用子查询
|
||||
$table = $join;
|
||||
} else {
|
||||
$prefix = $this->prefix;
|
||||
if (strpos($join, ' ')) {
|
||||
// 使用别名
|
||||
list($table, $alias) = explode(' ', $join);
|
||||
} else {
|
||||
$table = $join;
|
||||
if (false === strpos($join, '.') && 0 !== strpos($join, '__')) {
|
||||
$alias = $join;
|
||||
}
|
||||
}
|
||||
if ($prefix && false === strpos($table, '.') && 0 !== strpos($table, $prefix) && 0 !== strpos($table, '__')) {
|
||||
$table = $this->getTable($table);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($alias)) {
|
||||
$table = [$table => $alias];
|
||||
$this->alias($table);
|
||||
}
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询SQL组装 union
|
||||
* @access public
|
||||
@ -770,19 +790,8 @@ class Query
|
||||
}
|
||||
} else {
|
||||
$fields = [];
|
||||
$prefix = $this->prefix;
|
||||
if (is_array($join)) {
|
||||
// 支持数据表别名
|
||||
list($table, $alias) = each($join);
|
||||
} elseif ($prefix && false === strpos($join, ' ') && 0 !== strpos($join, $prefix) && 0 !== strpos($join, '__')) {
|
||||
$table = $this->getTable($join);
|
||||
$alias = $join;
|
||||
} elseif (strpos($join, ' ')) {
|
||||
list($table, $alias) = explode(' ', $join);
|
||||
} else {
|
||||
$alias = $join;
|
||||
}
|
||||
$table = isset($table) ? [$table => $alias] : $alias;
|
||||
$table = $this->getJoinTable($join, $alias);
|
||||
|
||||
if (true === $field) {
|
||||
$fields = $alias . '.*';
|
||||
} else {
|
||||
@ -906,13 +915,9 @@ class Query
|
||||
if (is_array($field)) {
|
||||
// 数组批量查询
|
||||
$where = $field;
|
||||
} elseif ($field) {
|
||||
} elseif ($field && is_string($field)) {
|
||||
// 字符串查询
|
||||
if (is_numeric($field)) {
|
||||
$where[] = ['exp', $field];
|
||||
} else {
|
||||
$where[$field] = ['null', ''];
|
||||
}
|
||||
$where[$field] = ['null', ''];
|
||||
}
|
||||
} elseif (is_array($op)) {
|
||||
$where[$field] = $param;
|
||||
@ -933,6 +938,22 @@ class Query
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除某个查询条件
|
||||
* @access public
|
||||
* @param string $field 查询字段
|
||||
* @param string $logic 查询逻辑 and or xor
|
||||
* @return $this
|
||||
*/
|
||||
public function removeWhereField($field, $logic = 'AND')
|
||||
{
|
||||
$logic = strtoupper($logic);
|
||||
if (isset($this->options['where'][$logic][$field])) {
|
||||
unset($this->options['where'][$logic][$field]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定查询数量
|
||||
* @access public
|
||||
@ -1002,6 +1023,9 @@ class Query
|
||||
|
||||
if (!isset($total) && !$simple) {
|
||||
$options = $this->getOptions();
|
||||
if (isset($options['order'])) {
|
||||
unset($this->options['order']);
|
||||
}
|
||||
$bind = $this->bind;
|
||||
$total = $this->count();
|
||||
$results = $this->options($options)->bind($bind)->page($page, $listRows)->select();
|
||||
@ -1183,6 +1207,9 @@ class Query
|
||||
} else {
|
||||
if (isset($this->options['table'])) {
|
||||
$table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table'];
|
||||
if (false !== strpos($table, '__')) {
|
||||
$table = $this->parseSqlTable($table);
|
||||
}
|
||||
} else {
|
||||
$table = $this->getTable();
|
||||
}
|
||||
@ -1604,6 +1631,8 @@ class Query
|
||||
$field = $this->options['with_field'];
|
||||
unset($this->options['with_field']);
|
||||
}
|
||||
} elseif (isset($info['option']['field'])) {
|
||||
$field = $info['option']['field'];
|
||||
}
|
||||
$this->field($field, false, $joinTable, $joinAlias, $relation . '__');
|
||||
$i++;
|
||||
|
@ -61,14 +61,14 @@ class Merge extends Model
|
||||
{
|
||||
$class = new static();
|
||||
$master = $class->name;
|
||||
$fields = self::getModelField($query, $master, '', $class->mapFields);
|
||||
$fields = self::getModelField($query, $master, '', $class->mapFields, $class->field);
|
||||
$query->alias($master)->field($fields);
|
||||
|
||||
foreach ($class->relationModel as $key => $model) {
|
||||
$name = is_int($key) ? $model : $key;
|
||||
$table = is_int($key) ? $query->getTable($name) : $model;
|
||||
$query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk());
|
||||
$fields = self::getModelField($query, $name, $table, $class->mapFields);
|
||||
$fields = self::getModelField($query, $name, $table, $class->mapFields, $class->field);
|
||||
$query->field($fields);
|
||||
}
|
||||
return $query;
|
||||
@ -81,12 +81,13 @@ class Merge extends Model
|
||||
* @param string $name 模型名称
|
||||
* @param string $table 关联表名称
|
||||
* @param array $map 字段映射
|
||||
* @param array $fields 查询字段
|
||||
* @return array
|
||||
*/
|
||||
protected static function getModelField($query, $name, $table = '', $map = [])
|
||||
protected static function getModelField($query, $name, $table = '', $map = [], $fields = [])
|
||||
{
|
||||
// 获取模型的字段信息
|
||||
$fields = $query->getTableInfo($table, 'fields');
|
||||
$fields = $fields ?: $query->getTableInfo($table, 'fields');
|
||||
$array = [];
|
||||
foreach ($fields as $field) {
|
||||
if ($key = array_search($name . '.' . $field, $map)) {
|
||||
|
@ -47,7 +47,8 @@ class Relation
|
||||
protected $query;
|
||||
// 关联查询条件
|
||||
protected $where;
|
||||
|
||||
// 关联查询参数
|
||||
protected $option;
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
@ -74,6 +75,7 @@ class Relation
|
||||
'localKey' => $this->localKey,
|
||||
'alias' => $this->alias,
|
||||
'joinType' => $this->joinType,
|
||||
'option' => $this->option,
|
||||
];
|
||||
return $name ? $info[$name] : $info;
|
||||
}
|
||||
@ -689,8 +691,10 @@ class Relation
|
||||
}
|
||||
$result = call_user_func_array([$this->query, $method], $args);
|
||||
if ($result instanceof \think\db\Query) {
|
||||
$this->option = $result->getOptions();
|
||||
return $this;
|
||||
} else {
|
||||
$this->option = [];
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
|
@ -24,6 +24,8 @@ class Think
|
||||
private $template;
|
||||
// 模板引擎参数
|
||||
protected $config = [
|
||||
// 视图基础目录(集中式)
|
||||
'view_base' => '',
|
||||
// 模板起始路径
|
||||
'view_path' => '',
|
||||
// 模板文件后缀
|
||||
@ -103,18 +105,21 @@ class Think
|
||||
*/
|
||||
private function parseTemplate($template)
|
||||
{
|
||||
// 分析模板文件规则
|
||||
$request = Request::instance();
|
||||
// 获取视图根目录
|
||||
if (strpos($template, '@')) {
|
||||
// 跨模块调用
|
||||
list($module, $template) = explode('@', $template);
|
||||
$path = APP_PATH . $module . DS . 'view' . DS;
|
||||
}
|
||||
if ($this->config['view_base']) {
|
||||
// 基础视图目录
|
||||
$module = isset($module) ? $module : $request->module();
|
||||
$path = $this->config['view_base'] . ($module ? $module . DS : '');
|
||||
} else {
|
||||
// 当前视图目录
|
||||
$path = $this->config['view_path'];
|
||||
$path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];
|
||||
}
|
||||
|
||||
// 分析模板文件规则
|
||||
$request = Request::instance();
|
||||
$controller = Loader::parseName($request->controller());
|
||||
if ($controller && 0 !== strpos($template, '/')) {
|
||||
$depr = $this->config['view_depr'];
|
||||
|
@ -27,7 +27,8 @@ trait SoftDelete
|
||||
public static function withTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
return $model->db();
|
||||
$field = $model->getDeleteTimeField(true);
|
||||
return $model->db(false)->removeWhereField($field);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,8 +39,8 @@ trait SoftDelete
|
||||
public static function onlyTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
$field = $model->getDeleteTimeField();
|
||||
return $model->db()->where($field, 'exp', 'is not null');
|
||||
$field = $model->getDeleteTimeField(true);
|
||||
return $model->db(false)->where($field, 'exp', 'is not null');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,7 +139,8 @@ trait SoftDelete
|
||||
$field = $this->db(false)->getTable() . '.' . $field;
|
||||
}
|
||||
if (!$read && strpos($field, '.')) {
|
||||
list($alias, $field) = explode('.', $field);
|
||||
$array = explode('.', $field);
|
||||
$field = array_pop($array);
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user