首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Symfony -如何调用链中的下一个服务

Symfony -如何调用链中的下一个服务
EN

Stack Overflow用户
提问于 2022-10-21 13:49:12
回答 1查看 48关注 0票数 0

我想在我的应用程序中实现授权的责任链模式。我已经创建了四种不同的授权链服务,它们取决于用户想要访问的路由。我对连锁服务有问题。我想链接服务而不明确地命名它们。例如:

代码语言:javascript
运行
复制
class Authorization1:
public function auth($request){
    if (isThisRoute){
        $this->authorize($request);
     }
     $this->authorization2->authorize($request);  
 }

我想知道如何用$this->authorization2->authorize($request);替换最后一行:$this->chain->authorize($request);,这样就可以完整地实现责任链模式。

EN

回答 1

Stack Overflow用户

发布于 2022-10-23 16:55:09

您的代码看起来像Laravel中间件代码。

试着学习它:https://refactoring.guru/design-patterns/chain-of-responsibility

如果您真的想对四种不同的服务使用责任链而不是策略,那么它可以类似于下面的代码(PHPV8.0)。

链式的接口

代码语言:javascript
运行
复制
interface AuthorizationRequestHandlerInterface
{
    public function auth(Request $request): bool;

   // Option 2
   public function setNext(AuthorizationRequestHandlerInterface $handler): void;
}

条件或状态的处理程序

代码语言:javascript
运行
复制
class Authorization1 implements AuthorizationRequestHandlerInterface
{
    // Option 1
    public function __construct(private AuthorizationRequestHandlerInterface $handler)
    {
    }

    // Option 2
    public function setNext(AuthorizationRequestHandlerInterface $handler): void
    {
        $this->handler = $handler;
    } 

    public function auth(Request $request): bool
    {
        if (isThisRoute) {
            // Check permissions here or call your private or protected method
            return $this->authorize($request);
        }

        // Option 1: Call the next handler
        return $this->handler->auth($request);  

        // Option 2: Call the next handler if it exists
        return $this->handler ? $this->handler->auth($request) : false;
    }

    private function authorize(Request $request): bool
    {
        $result = false;

        // Your code

        return $result;
    }
}

其他处理程序看起来与前一个类似。

您可以对对象执行任何操作并返回任何类型的值,但本例使用bool

您应该使用services.yml或其他方式来准备服务的配置。

最后,PHP代码可能如下所示:

代码语言:javascript
运行
复制
// Initialization: Option 1
$authNull = new AuthNull();
$auth1 = new Authorization1($authNull);
$auth2 = new Authorization2($auth1);
$auth3 = new Authorization3($auth2);

return $auth3;

// Initialization: Option 2
$auth1 = new Authorization1($authNull);
$auth2 = new Authorization2($auth1);
$auth3 = new Authorization3($auth2);
$auth1->setNext($auth2);
$auth2->setNext($auth3);
// In this way you must add the `setNext` method and use its value as `handler` instead of that constructor value.

return $auth1;

// ...

// A class that has the main handler, like AbstractGuardAuthenticator, Controller, ArgumentResolver, ParamConverter, Middleware, etc.

if ($auth->handle($request)) {
    // when it is authorizable, continues the request
} else {
    // when it isn't authorizable, throws Exception, for example
}

// Different handling order that depends on the options.
// Option 1: Auth3 -> Auth2 -> Auth1 -> AuthNull
// Option 2: Auth1 -> Auth2 -> Auth3

正如@alexcm所提到的,您应该阅读一些Symfony信息:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74154646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档