同步更新

This commit is contained in:
2026-01-13 17:27:32 +08:00
parent 45785dd33f
commit 5d6e2fc5e0
38 changed files with 1211 additions and 305 deletions

View File

@@ -8,7 +8,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
declare (strict_types = 1);
namespace think\route;
@@ -28,9 +28,20 @@ use think\Validate;
*/
abstract class Dispatch
{
/**
* 控制器名
* @var string
*/
protected $controller;
/**
* 操作名
* @var string
*/
protected $actionName;
/**
* 应用对象
*
* @var App
*/
protected $app;
@@ -41,7 +52,6 @@ abstract class Dispatch
/**
* 执行路由调度
*
* @access public
* @return Response
*/
@@ -53,23 +63,23 @@ abstract class Dispatch
protected function autoResponse($data): Response
{
if($data instanceof Response) {
if ($data instanceof Response) {
$response = $data;
} elseif($data instanceof ResponseInterface) {
$response = Response::create((string)$data->getBody(), 'html', $data->getStatusCode());
} elseif ($data instanceof ResponseInterface) {
$response = Response::create((string) $data->getBody(), 'html', $data->getStatusCode());
foreach ($data->getHeaders() as $header => $values) {
$response->header([$header => implode(", ", $values)]);
}
} elseif(!is_null($data)) {
} elseif (!is_null($data)) {
// 默认自动识别响应输出类型
$type = $this->request->isJson() ? 'json' : 'html';
$type = $this->request->isJson() ? 'json' : 'html';
$response = Response::create($data, $type);
} else {
$data = ob_get_clean();
$content = false === $data ? '' : $data;
$status = '' === $content && $this->request->isJson() ? 204 : 200;
$content = false === $data ? '' : $data;
$status = '' === $content && $this->request->isJson() ? 204 : 200;
$response = Response::create($content, 'html', $status);
}
@@ -78,7 +88,6 @@ abstract class Dispatch
/**
* 检查路由后置操作
*
* @access protected
* @return void
*/
@@ -87,8 +96,8 @@ abstract class Dispatch
$option = $this->option;
// 添加中间件
if(!empty($option['middleware'])) {
if(isset($option['without_middleware'])) {
if (!empty($option['middleware'])) {
if (isset($option['without_middleware'])) {
$middleware = !empty($option['without_middleware']) ? array_diff($option['middleware'], $option['without_middleware']) : [];
} else {
$middleware = $option['middleware'];
@@ -96,12 +105,12 @@ abstract class Dispatch
$this->app->middleware->import($middleware, 'route');
}
if(!empty($option['append'])) {
if (!empty($option['append'])) {
$this->param = array_merge($this->param, $option['append']);
}
// 绑定模型数据
if(!empty($option['model'])) {
if (!empty($option['model'])) {
$this->createBindModel($option['model'], $this->param);
}
@@ -112,14 +121,13 @@ abstract class Dispatch
$this->request->setRoute($this->param);
// 数据自动验证
if(isset($option['validate'])) {
if (isset($option['validate'])) {
$this->autoValidate($option['validate']);
}
}
/**
* 获取操作的绑定参数
*
* @access protected
* @return array
*/
@@ -135,11 +143,9 @@ abstract class Dispatch
/**
* 执行中间件调度
*
* @access public
*
* @param object $controller 控制器实例
*
* @param object $instance 控制器实例
* @param string $action
* @return void
*/
protected function responseWithMiddlewarePipeline($instance, $action)
@@ -153,20 +159,20 @@ abstract class Dispatch
$suffix = $this->rule->config('action_suffix');
$action = $action . $suffix;
if(is_callable([$instance, $action])) {
if (is_callable([$instance, $action])) {
$vars = $this->getActionBindVars();
try {
$reflect = new ReflectionMethod($instance, $action);
// 严格获取当前操作方法名
$actionName = $reflect->getName();
if($suffix) {
if ($suffix) {
$actionName = substr($actionName, 0, -strlen($suffix));
}
$this->request->setAction($actionName);
} catch (ReflectionException $e) {
$reflect = new ReflectionMethod($instance, '__call');
$vars = [$action, $vars];
$vars = [$action, $vars];
$this->request->setAction($action);
}
} else {
@@ -182,47 +188,45 @@ abstract class Dispatch
/**
* 使用反射机制注册控制器中间件
*
* @access public
*
* @param object $controller 控制器实例
*
* @return void
*/
protected function registerControllerMiddleware($controller): void
{
$class = new ReflectionClass($controller);
if($class->hasProperty('middleware')) {
if ($class->hasProperty('middleware')) {
$reflectionProperty = $class->getProperty('middleware');
if(PHP_VERSION_ID < 80100) {
if (PHP_VERSION_ID < 80100) {
$reflectionProperty->setAccessible(true);
}
$middlewares = $reflectionProperty->getValue($controller);
$action = $this->request->action(true);
$action = $this->request->action(true);
foreach ($middlewares as $key => $val) {
if(!is_int($key)) {
if (!is_int($key)) {
$middleware = $key;
$options = $val;
} elseif(isset($val['middleware'])) {
$options = $val;
} elseif (isset($val['middleware'])) {
$middleware = $val['middleware'];
$options = $val['options'] ?? [];
$options = $val['options'] ?? [];
} else {
$middleware = $val;
$options = [];
$options = [];
}
if(isset($options['only']) && !in_array($action, $this->parseActions($options['only']))) {
if (isset($options['only']) && !in_array($action, $this->parseActions($options['only']))) {
continue;
} elseif(isset($options['except']) && in_array($action, $this->parseActions($options['except']))) {
} elseif (isset($options['except']) && in_array($action, $this->parseActions($options['except']))) {
continue;
}
if(is_string($middleware) && str_contains($middleware, ':')) {
if (is_string($middleware) && str_contains($middleware, ':')) {
$middleware = explode(':', $middleware);
if(count($middleware) > 1) {
if (count($middleware) > 1) {
$middleware = [$middleware[0], array_slice($middleware, 1)];
}
}
@@ -241,26 +245,23 @@ abstract class Dispatch
/**
* 路由绑定模型实例
*
* @access protected
*
* @param array $bindModel 绑定模型
* @param array $matches 路由变量
*
* @return void
*/
protected function createBindModel(array $bindModel, array $matches): void
{
foreach ($bindModel as $key => $val) {
if($val instanceof \Closure) {
if ($val instanceof \Closure) {
$result = $this->app->invokeFunction($val, $matches);
} else {
$fields = explode('&', $key);
if(is_array($val)) {
if (is_array($val)) {
[$model, $exception] = $val;
} else {
$model = $val;
$model = $val;
$exception = true;
}
@@ -268,7 +269,7 @@ abstract class Dispatch
$match = true;
foreach ($fields as $field) {
if(!isset($matches[$field])) {
if (!isset($matches[$field])) {
$match = false;
break;
} else {
@@ -276,12 +277,12 @@ abstract class Dispatch
}
}
if($match) {
if ($match) {
$result = $model::where($where)->failException($exception)->find();
}
}
if(!empty($result)) {
if (!empty($result)) {
// 注入容器
$this->app->instance($result::class, $result);
}
@@ -290,11 +291,8 @@ abstract class Dispatch
/**
* 验证数据
*
* @access protected
*
* @param array $option
*
* @return void
* @throws \think\exception\ValidateException
*/
@@ -302,7 +300,7 @@ abstract class Dispatch
{
[$validate, $scene, $message, $batch] = $option;
if(is_array($validate)) {
if (is_array($validate)) {
// 指定验证规则
$v = new Validate();
$v->rule($validate);
@@ -312,7 +310,7 @@ abstract class Dispatch
$v = new $class();
if(!empty($scene)) {
if (!empty($scene)) {
$v->scene($scene);
}
}
@@ -336,14 +334,26 @@ abstract class Dispatch
abstract public function exec();
public function __sleep()
public function __serialize(): array
{
return ['rule', 'dispatch', 'param', 'controller', 'actionName'];
return [
'rule' => $this->rule,
'dispatch' => $this->dispatch,
'param' => $this->param,
'controller' => $this->controller,
'actionName' => $this->actionName,
];
}
public function __wakeup()
public function __unserialize(array $data): void
{
$this->app = Container::pull('app');
$this->rule = $data['rule'];
$this->dispatch = $data['dispatch'];
$this->param = $data['param'];
$this->controller = $data['controller'];
$this->actionName = $data['actionName'];
$this->app = Container::pull('app');
$this->request = $this->app->request;
}