Thinkphp8 通过中间件 和 属性 简单实现AOP
转载请著名来源,侵权必究
//属性接口
declare(strict_types=1);
namespace app\common\attribute;
interface AttributeHandler
{
public function handler(mixed $handler);
}
//不需要登陆属性
declare(strict_types=1);
namespace app\common\attribute;
/**
* 跳过登陆验证
*/
#[\Attribute(\Attribute::TARGET_METHOD)]
class NoLogin implements AttributeHandler
{
public function __construct(){
}
public function handler(mixed $handler)
{
// TODO: Implement handler() method.
//return Response::create('页面未找到 - NoLogin', 'html', 404);
}
}
//权限验证属性
declare(strict_types=1);
namespace app\shop\attribute;
use app\common\attribute\AttributeHandler;
/**
* 权限验证
*/
#[\Attribute(\Attribute::TARGET_METHOD)]
class CheckPermission implements AttributeHandler
{
public function __construct(private string $permission){
}
public function handler(mixed $handler)
{
// TODO: Implement handler() method.
//return Response::create('页面未找到 - CheckPermission', 'html', 404);
}
}
注意这里是要加到 控制器中间件
//属性中间件 (控制器中间件)
declare(strict_types=1);
namespace app\common\middleware;
use app\common\attribute\AttributeHandler;
use Closure;
use think\App;
use think\Request;
use think\Response;
use think\Session;
/**
* 属性中间件
*/
class AttributeMiddleware
{
/**
* 记录属性
* @throws Throwable
*/
public function handle($request, Closure $next)
{
$context = app(Context::class);
$controller = str_replace('.', '\\', $request->controller());
/** @var Response $response */
$reflect = new \ReflectionClass('app\\' . app('http')->getName() . '\controller\\' . $controller);
$attributes = $reflect->getMethod($request->action())->getAttributes();
$annotations = [
/**
* 这里可以添加全局
* 'CheckLogin' => [
* 'instance' => app(CheckLogin::class)
* ]
**/
];
foreach ($attributes as $attribute) {
/**
* @var AttributeHandler $instance
* **/
$instance = $attribute->newInstance();
if ($instance instanceof AttributeHandler) {
$annotations[$attribute->getName()] = [
'attribute' => $attribute,
'instance' => $instance
];
}
}
$context->annotations = $annotations;
foreach ($annotations as $attribute) {
/**
* @var AttributeHandler $instance
* **/
$instance = $attribute['instance'];
$instance->handler(request: $request);
}
return $next($request);
}
}
//测试类
<?php
namespace app\shop\controller;
use app\common\attribute\NoLogin;
use app\shop\attribute\CheckPermission;
use app\shop\BaseController;
class Index extends BaseController
{
#[CheckPermission(permission:"Foo")]
public function index()
{
return '<style>*{ padding: 0; margin: 0; }</style><iframe src="https://www.thinkphp.cn/welcome?version=' . \think\facade\App::version() . '" width="100%" height="100%" frameborder="0" scrolling="auto"></iframe>';
}
#[NoLogin]
public function hello($name = 'ThinkPHP8')
{
return 'hello,' . $name;
}
}