mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 20:52:48 +08:00
2
base.php
2
base.php
@@ -9,7 +9,7 @@
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
define('THINK_VERSION', '5.0.2dev');
|
||||
define('THINK_VERSION', '5.0.3beta');
|
||||
define('THINK_START_TIME', microtime(true));
|
||||
define('THINK_START_MEM', memory_get_usage());
|
||||
define('EXT', '.php');
|
||||
|
||||
@@ -85,6 +85,8 @@ return [
|
||||
'url_route_on' => true,
|
||||
// 路由配置文件(支持配置多个)
|
||||
'route_config_file' => ['route'],
|
||||
// 路由使用完整匹配
|
||||
'route_complete_match' => false,
|
||||
// 是否强制使用路由
|
||||
'url_route_must' => false,
|
||||
// 域名部署
|
||||
|
||||
@@ -298,7 +298,7 @@ if (!function_exists('session')) {
|
||||
Session::init($name);
|
||||
} elseif (is_null($name)) {
|
||||
// 清除
|
||||
Session::clear($value);
|
||||
Session::clear('' === $value ? null : $value);
|
||||
} elseif ('' === $value) {
|
||||
// 判断或获取
|
||||
return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix);
|
||||
@@ -359,12 +359,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)) {
|
||||
|
||||
@@ -16,6 +16,7 @@ use think\Env;
|
||||
use think\Exception;
|
||||
use think\exception\HttpException;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\exception\RouteNotFoundException;
|
||||
use think\Hook;
|
||||
use think\Lang;
|
||||
use think\Loader;
|
||||
@@ -369,34 +370,29 @@ class App
|
||||
// 监听module_init
|
||||
Hook::listen('module_init', $request);
|
||||
|
||||
try {
|
||||
$instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
|
||||
if (is_null($instance)) {
|
||||
throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1));
|
||||
}
|
||||
// 获取当前操作名
|
||||
$action = $actionName . $config['action_suffix'];
|
||||
if (!preg_match('/^[A-Za-z](\w)*$/', $action)) {
|
||||
// 非法操作
|
||||
throw new \ReflectionException('illegal action name:' . $actionName);
|
||||
}
|
||||
$instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
|
||||
if (is_null($instance)) {
|
||||
throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1));
|
||||
}
|
||||
// 获取当前操作名
|
||||
$action = $actionName . $config['action_suffix'];
|
||||
|
||||
$vars = [];
|
||||
if (is_callable([$instance, $action])) {
|
||||
// 执行操作方法
|
||||
$call = [$instance, $action];
|
||||
Hook::listen('action_begin', $call);
|
||||
|
||||
$data = self::invokeMethod($call);
|
||||
} catch (\ReflectionException $e) {
|
||||
} elseif (is_callable([$instance, '_empty'])) {
|
||||
// 空操作
|
||||
$call = [$instance, '_empty'];
|
||||
$vars = [$action];
|
||||
} else {
|
||||
// 操作不存在
|
||||
if (method_exists($instance, '_empty')) {
|
||||
$reflect = new \ReflectionMethod($instance, '_empty');
|
||||
$data = $reflect->invokeArgs($instance, [$action]);
|
||||
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
|
||||
} else {
|
||||
throw new HttpException(404, 'method not exists:' . (new \ReflectionClass($instance))->getName() . '->' . $action);
|
||||
}
|
||||
throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
|
||||
}
|
||||
return $data;
|
||||
|
||||
Hook::listen('action_begin', $call);
|
||||
|
||||
return self::invokeMethod($call, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,7 +548,7 @@ class App
|
||||
$must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];
|
||||
if ($must && false === $result) {
|
||||
// 路由无效
|
||||
throw new HttpException(404, 'Route Not Found');
|
||||
throw new RouteNotFoundException();
|
||||
}
|
||||
}
|
||||
if (false === $result) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1241,8 +1241,7 @@ class Request
|
||||
if (false !== $pos) {
|
||||
unset($arr[$pos]);
|
||||
}
|
||||
|
||||
$ip = trim($arr[0]);
|
||||
$ip = trim(current($arr));
|
||||
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
|
||||
@@ -24,13 +24,13 @@ class Route
|
||||
{
|
||||
// 路由规则
|
||||
private static $rules = [
|
||||
'GET' => [],
|
||||
'POST' => [],
|
||||
'PUT' => [],
|
||||
'DELETE' => [],
|
||||
'PATCH' => [],
|
||||
'HEAD' => [],
|
||||
'OPTIONS' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'delete' => [],
|
||||
'patch' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
'*' => [],
|
||||
'alias' => [],
|
||||
'domain' => [],
|
||||
@@ -40,21 +40,22 @@ class Route
|
||||
|
||||
// REST路由操作方法定义
|
||||
private static $rest = [
|
||||
'index' => ['GET', '', 'index'],
|
||||
'create' => ['GET', '/create', 'create'],
|
||||
'edit' => ['GET', '/:id/edit', 'edit'],
|
||||
'read' => ['GET', '/:id', 'read'],
|
||||
'save' => ['POST', '', 'save'],
|
||||
'update' => ['PUT', '/:id', 'update'],
|
||||
'delete' => ['DELETE', '/:id', 'delete'],
|
||||
'index' => ['get', '', 'index'],
|
||||
'create' => ['get', '/create', 'create'],
|
||||
'edit' => ['get', '/:id/edit', 'edit'],
|
||||
'read' => ['get', '/:id', 'read'],
|
||||
'save' => ['post', '', 'save'],
|
||||
'update' => ['put', '/:id', 'update'],
|
||||
'delete' => ['delete', '/:id', 'delete'],
|
||||
];
|
||||
|
||||
// 不同请求类型的方法前缀
|
||||
private static $methodPrefix = [
|
||||
'GET' => 'get',
|
||||
'POST' => 'post',
|
||||
'PUT' => 'put',
|
||||
'DELETE' => 'delete',
|
||||
'get' => 'get',
|
||||
'post' => 'post',
|
||||
'put' => 'put',
|
||||
'delete' => 'delete',
|
||||
'patch' => 'patch',
|
||||
];
|
||||
|
||||
// 子域名
|
||||
@@ -68,6 +69,8 @@ class Route
|
||||
private static $domainRule;
|
||||
// 当前域名
|
||||
private static $domain;
|
||||
// 当前路由执行过程中的参数
|
||||
private static $option = [];
|
||||
|
||||
/**
|
||||
* 注册变量规则
|
||||
@@ -150,6 +153,7 @@ class Route
|
||||
} elseif (!is_null($value)) {
|
||||
self::$rules['name'][$name][] = $value;
|
||||
} else {
|
||||
$name = strtolower($name);
|
||||
return isset(self::$rules['name'][$name]) ? self::$rules['name'][$name] : null;
|
||||
}
|
||||
}
|
||||
@@ -198,7 +202,7 @@ class Route
|
||||
unset($rule['__rest__']);
|
||||
}
|
||||
|
||||
self::registerRules($rule, strtoupper($type));
|
||||
self::registerRules($rule, strtolower($type));
|
||||
}
|
||||
|
||||
// 批量注册路由
|
||||
@@ -241,7 +245,7 @@ class Route
|
||||
$pattern = array_merge(self::getGroup('pattern'), $pattern);
|
||||
}
|
||||
|
||||
$type = strtoupper($type);
|
||||
$type = strtolower($type);
|
||||
|
||||
if (strpos($type, '|')) {
|
||||
$option['method'] = $type;
|
||||
@@ -300,13 +304,13 @@ 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;
|
||||
self::name($name, [$key, $vars, self::$domain]);
|
||||
$key = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
|
||||
self::name(strtolower($name), [$key, $vars, self::$domain]);
|
||||
}
|
||||
if ($group) {
|
||||
if ('*' != $type) {
|
||||
@@ -328,7 +332,7 @@ class Route
|
||||
}
|
||||
if ('*' == $type) {
|
||||
// 注册路由快捷方式
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {
|
||||
if (self::$domain) {
|
||||
self::$rules['domain'][self::$domain][$method][$rule] = true;
|
||||
} else {
|
||||
@@ -339,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
|
||||
@@ -423,15 +448,16 @@ 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];
|
||||
}
|
||||
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {
|
||||
if (!isset(self::$rules[$method][$name])) {
|
||||
self::$rules[$method][$name] = true;
|
||||
} elseif (is_array(self::$rules[$method][$name])) {
|
||||
@@ -576,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);
|
||||
}
|
||||
}
|
||||
@@ -625,9 +652,9 @@ class Route
|
||||
public static function setMethodPrefix($method, $prefix = '')
|
||||
{
|
||||
if (is_array($method)) {
|
||||
self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method, CASE_UPPER));
|
||||
self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method));
|
||||
} else {
|
||||
self::$methodPrefix[strtoupper($method)] = $prefix;
|
||||
self::$methodPrefix[strtolower($method)] = $prefix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,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 = [])
|
||||
@@ -682,7 +709,7 @@ class Route
|
||||
if (is_array($rules)) {
|
||||
self::$rules = $rules;
|
||||
} elseif ($rules) {
|
||||
return true === $rules ? self::$rules : self::$rules[$rules];
|
||||
return true === $rules ? self::$rules : self::$rules[strtolower($rules)];
|
||||
} else {
|
||||
$rules = self::$rules;
|
||||
unset($rules['pattern'], $rules['alias'], $rules['domain'], $rules['name']);
|
||||
@@ -698,7 +725,7 @@ class Route
|
||||
* @param string $method 请求类型
|
||||
* @return void
|
||||
*/
|
||||
public static function checkDomain($request, &$currentRules, $method = 'GET')
|
||||
public static function checkDomain($request, &$currentRules, $method = 'get')
|
||||
{
|
||||
// 域名规则
|
||||
$rules = self::$rules['domain'];
|
||||
@@ -808,7 +835,7 @@ class Route
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
$method = $request->method();
|
||||
$method = strtolower($request->method());
|
||||
// 获取当前请求类型的路由规则
|
||||
$rules = self::$rules[$method];
|
||||
// 检测域名部署
|
||||
@@ -831,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']);
|
||||
}
|
||||
}
|
||||
@@ -894,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;
|
||||
@@ -909,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']);
|
||||
}
|
||||
@@ -1091,7 +1121,9 @@ class Route
|
||||
{
|
||||
// 请求类型检测
|
||||
if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method()))
|
||||
|| (isset($option['ext']) && false === stripos($option['ext'], $request->ext())) // 伪静态后缀检测
|
||||
|| (!empty($option['ajax']) && !$request->isAjax()) // Ajax检测
|
||||
|| (!empty($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检测
|
||||
@@ -1162,8 +1194,9 @@ class Route
|
||||
{
|
||||
|
||||
if (isset(self::$bind['module'])) {
|
||||
$bind = str_replace('/', $depr, self::$bind['module']);
|
||||
// 如果有模块/控制器绑定
|
||||
$url = self::$bind['module'] . '/' . ltrim($url, '/');
|
||||
$url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr);
|
||||
}
|
||||
$url = str_replace($depr, '|', $url);
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
@@ -1176,15 +1209,22 @@ class Route
|
||||
$dir = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer');
|
||||
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||
$item = [];
|
||||
$find = false;
|
||||
foreach ($path as $val) {
|
||||
$item[] = array_shift($path);
|
||||
if (is_file($dir . DS . $val . $suffix . EXT)) {
|
||||
$item[] = $val;
|
||||
if (is_file($dir . DS . str_replace('.', DS, $val) . $suffix . EXT)) {
|
||||
$find = true;
|
||||
break;
|
||||
} else {
|
||||
$dir .= DS . $val;
|
||||
}
|
||||
}
|
||||
$controller = implode('.', $item);
|
||||
if ($find) {
|
||||
$controller = implode('.', $item);
|
||||
$path = array_slice($path, count($item));
|
||||
} else {
|
||||
$controller = array_shift($path);
|
||||
}
|
||||
} else {
|
||||
// 解析控制器
|
||||
$controller = !empty($path) ? array_shift($path) : null;
|
||||
@@ -1195,8 +1235,15 @@ class Route
|
||||
self::parseUrlParams(empty($path) ? '' : implode('|', $path));
|
||||
// 封装路由
|
||||
$route = [$module, $controller, $action];
|
||||
if (isset(self::$rules['name'][implode($depr, $route)])) {
|
||||
throw new HttpException(404, 'invalid request:' . $url);
|
||||
// 检查地址是否被定义过路由
|
||||
$name = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action);
|
||||
$name2 = '';
|
||||
if (empty($module) || isset($bind) && $module == $bind) {
|
||||
$name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);
|
||||
}
|
||||
|
||||
if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) {
|
||||
throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));
|
||||
}
|
||||
}
|
||||
return ['type' => 'module', 'module' => $route];
|
||||
|
||||
@@ -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
|
||||
@@ -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,12 +155,13 @@ 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;
|
||||
}
|
||||
|
||||
// 直接解析URL地址
|
||||
protected static function parseUrl($url, $domain)
|
||||
protected static function parseUrl($url, &$domain)
|
||||
{
|
||||
$request = Request::instance();
|
||||
if (0 === strpos($url, '/')) {
|
||||
@@ -173,14 +177,36 @@ class Url
|
||||
// 解析到 模块/控制器/操作
|
||||
$module = $request->module();
|
||||
$domains = Route::rules('domain');
|
||||
if (isset($domains[$domain]['[bind]'][0])) {
|
||||
$bindModule = $domains[$domain]['[bind]'][0];
|
||||
if ($bindModule && !in_array($bindModule[0], ['\\', '@'])) {
|
||||
$module = '';
|
||||
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])) {
|
||||
$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];
|
||||
if ($bindModule && !in_array($bindModule[0], ['\\', '@'])) {
|
||||
$module = '';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$module = $module ? $module . '/' : '';
|
||||
}
|
||||
$module = $module ? $module . '/' : '';
|
||||
|
||||
$controller = Loader::parseName($request->controller());
|
||||
if ('' == $url) {
|
||||
@@ -203,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) {
|
||||
@@ -220,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;
|
||||
}
|
||||
@@ -234,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;
|
||||
}
|
||||
|
||||
@@ -348,16 +348,22 @@ class Validate
|
||||
$result = call_user_func_array($rule, [$value, $data]);
|
||||
} else {
|
||||
// 判断验证类型
|
||||
if (is_numeric($key) && strpos($rule, ':')) {
|
||||
list($type, $rule) = explode(':', $rule, 2);
|
||||
if (isset($this->alias[$type])) {
|
||||
// 判断别名
|
||||
$type = $this->alias[$type];
|
||||
if (is_numeric($key)) {
|
||||
if (strpos($rule, ':')) {
|
||||
list($type, $rule) = explode(':', $rule, 2);
|
||||
if (isset($this->alias[$type])) {
|
||||
// 判断别名
|
||||
$type = $this->alias[$type];
|
||||
}
|
||||
$info = $type;
|
||||
} elseif (method_exists($this, $rule)) {
|
||||
$type = $rule;
|
||||
$info = $rule;
|
||||
$rule = '';
|
||||
} else {
|
||||
$type = 'is';
|
||||
$info = $rule;
|
||||
}
|
||||
$info = $type;
|
||||
} elseif (is_numeric($key)) {
|
||||
$type = 'is';
|
||||
$info = $rule;
|
||||
} else {
|
||||
$info = $type = $key;
|
||||
}
|
||||
@@ -607,6 +613,9 @@ class Validate
|
||||
*/
|
||||
protected function activeUrl($value, $rule)
|
||||
{
|
||||
if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) {
|
||||
$rule = 'MX';
|
||||
}
|
||||
return checkdnsrr($value, $rule);
|
||||
}
|
||||
|
||||
@@ -715,19 +724,24 @@ class Validate
|
||||
if (!($file instanceof File)) {
|
||||
return false;
|
||||
}
|
||||
$rule = explode(',', $rule);
|
||||
list($width, $height, $type) = getimagesize($file->getRealPath());
|
||||
if (isset($rule[2])) {
|
||||
$imageType = strtolower($rule[2]);
|
||||
if ('jpeg' == $imageType) {
|
||||
$imageType = 'jpg';
|
||||
}
|
||||
if (image_type_to_extension($type, false) != $imageType) {
|
||||
return false;
|
||||
if ($rule) {
|
||||
$rule = explode(',', $rule);
|
||||
list($width, $height, $type) = getimagesize($file->getRealPath());
|
||||
if (isset($rule[2])) {
|
||||
$imageType = strtolower($rule[2]);
|
||||
if ('jpeg' == $imageType) {
|
||||
$imageType = 'jpg';
|
||||
}
|
||||
if (image_type_to_extension($type, false) != $imageType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
list($w, $h) = $rule;
|
||||
return $w == $width && $h == $height;
|
||||
} else {
|
||||
return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]);
|
||||
}
|
||||
list($w, $h) = $rule;
|
||||
return $w == $width && $h == $height;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -433,7 +433,7 @@ abstract class Connection
|
||||
$sql . ' ');
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
return rtrim($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -669,11 +669,18 @@ class Query
|
||||
$table = array_shift($join);
|
||||
}
|
||||
} else {
|
||||
$table = trim($join);
|
||||
if (strpos($table, ' ') && !strpos($table, ')')) {
|
||||
list($table, $alias) = explode(' ', $table);
|
||||
$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;
|
||||
}
|
||||
}
|
||||
$this->options['join'][] = [$table, strtoupper($type), $condition];
|
||||
@@ -763,13 +770,19 @@ class Query
|
||||
}
|
||||
} else {
|
||||
$fields = [];
|
||||
$prefix = $this->prefix;
|
||||
if (is_array($join)) {
|
||||
// 支持数据表别名
|
||||
list($join, $alias, $table) = array_pad($join, 3, '');
|
||||
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 = !empty($table) ? $table : $this->getTable($join);
|
||||
$table = isset($table) ? [$table => $alias] : $alias;
|
||||
if (true === $field) {
|
||||
$fields = $alias . '.*';
|
||||
} else {
|
||||
@@ -793,9 +806,9 @@ class Query
|
||||
}
|
||||
$this->field($fields);
|
||||
if ($on) {
|
||||
$this->join($table . ' ' . $alias, $on, $type);
|
||||
$this->join($table, $on, $type);
|
||||
} else {
|
||||
$this->table($table . ' ' . $alias);
|
||||
$this->table($table);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
@@ -893,13 +906,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;
|
||||
@@ -989,8 +998,11 @@ class Query
|
||||
|
||||
if (!isset($total) && !$simple) {
|
||||
$options = $this->getOptions();
|
||||
$total = $this->count();
|
||||
if (isset($options['order'])) {
|
||||
unset($this->options['order']);
|
||||
}
|
||||
$bind = $this->bind;
|
||||
$total = $this->count();
|
||||
$results = $this->options($options)->bind($bind)->page($page, $listRows)->select();
|
||||
} elseif ($simple) {
|
||||
$results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select();
|
||||
|
||||
24
library/think/exception/RouteNotFoundException.php
Normal file
24
library/think/exception/RouteNotFoundException.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\exception;
|
||||
|
||||
use think\exception\HttpException;
|
||||
|
||||
class RouteNotFoundException extends HttpException
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(404);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,7 @@ trait SoftDelete
|
||||
public static function withTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
return $model->db();
|
||||
return $model->db(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ trait SoftDelete
|
||||
{
|
||||
$model = new static();
|
||||
$field = $model->getDeleteTimeField();
|
||||
return $model->db()->where($field, 'exp', 'is not null');
|
||||
return $model->db(false)->where($field, 'exp', 'is not null');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,13 +25,13 @@ class urlTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
Route::rules(['GET' => [],
|
||||
'POST' => [],
|
||||
'PUT' => [],
|
||||
'DELETE' => [],
|
||||
'PATCH' => [],
|
||||
'HEAD' => [],
|
||||
'OPTIONS' => [],
|
||||
Route::rules(['get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'delete' => [],
|
||||
'patch' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
'*' => [],
|
||||
'alias' => [],
|
||||
'domain' => [],
|
||||
|
||||
Reference in New Issue
Block a user