Skip to content

Commit

Permalink
支持使用注解设置控制器中间件
Browse files Browse the repository at this point in the history
  • Loading branch information
big-dream committed Feb 26, 2025
1 parent 68d123d commit 471e4e0
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 26 deletions.
41 changes: 41 additions & 0 deletions src/think/attribute/Middleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace think\attribute;

/**
* 设置中间件
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
class Middleware
{
/**
* 中间件
* @var string|array
*/
public string|array $middleware;

/**
* 仅生效的操作
* @var string[]
*/
public array $only;

/**
* 排除的操作
* @var string[]
*/
public array $except;

/**
* 设置中间件
* @param string|array $middleware 中间件
* @param string[] $only 仅生效的操作
* @param string[] $except 排除的操作
*/
public function __construct(string|array $middleware, array $only = [], array $except = [])
{
$this->middleware = $middleware;
$this->only = $only;
$this->except = $except;
}
}
66 changes: 40 additions & 26 deletions src/think/route/Dispatch.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
Expand All @@ -8,7 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <[email protected]>
// +----------------------------------------------------------------------
declare (strict_types = 1);
declare (strict_types=1);

namespace think\route;

Expand All @@ -17,6 +18,7 @@
use ReflectionException;
use ReflectionMethod;
use think\App;
use think\attribute\Middleware;
use think\Container;
use think\exception\HttpException;
use think\Request;
Expand All @@ -34,9 +36,7 @@ abstract class Dispatch
*/
protected $app;

public function __construct(protected Request $request, protected Rule $rule, protected $dispatch, protected array $param = [], protected array $option = [])
{
}
public function __construct(protected Request $request, protected Rule $rule, protected $dispatch, protected array $param = [], protected array $option = []) {}

public function init(App $app)
{
Expand Down Expand Up @@ -191,40 +191,54 @@ protected function registerControllerMiddleware($controller): void
{
$class = new ReflectionClass($controller);

$action = $this->request->action(true);

$middlewares = [];

// 读取控制器 middleware 属性
if ($class->hasProperty('middleware')) {
$reflectionProperty = $class->getProperty('middleware');
$reflectionProperty->setAccessible(true);

$middlewares = $reflectionProperty->getValue($controller);
$action = $this->request->action(true);

foreach ($middlewares as $key => $val) {
foreach ($reflectionProperty->getValue($controller) as $key => $val) {
if (!is_int($key)) {
$middleware = $key;
$options = $val;
$middlewares[] = ['middleware' => $key, 'options' => $val];
} elseif (isset($val['middleware'])) {
$middleware = $val['middleware'];
$options = $val['options'] ?? [];
$middlewares[] = ['middleware' => $val['middleware'], 'options' => $val['options'] ?? []];
} else {
$middleware = $val;
$options = [];
$middlewares[] = ['middleware' => $val, 'options' => []];
}
}
}

if (isset($options['only']) && !in_array($action, $this->parseActions($options['only']))) {
continue;
} elseif (isset($options['except']) && in_array($action, $this->parseActions($options['except']))) {
continue;
}
// 读取注解
foreach ($class->getAttributes(Middleware::class) as $val) {
/** @var Middleware $middleware */
$middleware = $val->newInstance();
$middlewares[] = [
'middleware' => $middleware->middleware,
'options' => ['only' => $middleware->only, 'except' => $middleware->except],
];
}

if (is_string($middleware) && str_contains($middleware, ':')) {
$middleware = explode(':', $middleware);
if (count($middleware) > 1) {
$middleware = [$middleware[0], array_slice($middleware, 1)];
}
}
foreach ($middlewares as $val) {
$middleware = $val['middleware'];
$options = $val['options'];

$this->app->middleware->controller($middleware);
if (!empty($options['only']) && !in_array($action, $this->parseActions($options['only']))) {
continue;
} elseif (in_array($action, $this->parseActions($options['except'] ?? []))) {
continue;
}

if (is_string($middleware) && str_contains($middleware, ':')) {
$middleware = explode(':', $middleware);
if (count($middleware) > 1) {
$middleware = [$middleware[0], array_slice($middleware, 1)];
}
}

$this->app->middleware->controller($middleware);
}
}

Expand Down

0 comments on commit 471e4e0

Please sign in to comment.