updated 升级ThinkPHP核心包到V5.0.3版本

This commit is contained in:
zhaoxiang 2016-11-22 16:00:44 +08:00
parent 5b5d2b3763
commit 3afec99c92
17 changed files with 289 additions and 156 deletions

View File

@ -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');

View File

@ -103,6 +103,10 @@ return [
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// +----------------------------------------------------------------------
// | 模板设置

View File

@ -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)) {

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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

View File

@ -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();
}
/**

View File

@ -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

View File

@ -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
*/

View File

@ -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;

View File

@ -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;
}

View File

@ -433,7 +433,7 @@ abstract class Connection
$sql . ' ');
}
}
return $sql;
return rtrim($sql);
}
/**

View File

@ -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++;

View File

@ -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)) {

View File

@ -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 {

View File

@ -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'];

View File

@ -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;
}