code-202/processor

处理请求工作的机制

1.0 2022-12-06 19:38 UTC

This package is auto-updated.

Last update: 2024-09-06 23:31:23 UTC


README

处理请求工作的机制

安装

您可以使用 Composer 安装 Processor

$ composer require code-202/processor

如何使用它?

这个库的主要优点是 ChainProcessor。它包含多个处理器,可以从请求中处理特定的工作并生成响应。

ChainProcessor 会询问它包含的每个处理器是否可以处理特定请求的工作。第一个回答可以做的处理器将被使用。响应包含多个内容,如请求本身、状态码、执行工作的处理器的名称,以及显然的工作输出。

构建 请求

在使用处理器之前,您必须构建您的请求。您的请求可以是任何您想要的内容:一个简单的字符串、一个数组、一个对象... 这个对象将用于确定处理器是否可以处理工作以及如何处理。

示例

<?php

$object; // The object is the reason of your request.

$request = ['action' => 'validate', 'item' => $object];

执行工作

您只需使用一个 Processor 来尝试执行工作。最好的方式是使用包含多个处理器的 ChainProcessor

<?php

$chainProcessor; // We considere that this processors is already init with several processors

$request; // We considere that you already build the request

if ($chainProcessor->supports($request) { // Test if the processor can do the job
    $response = $chainProcessor->proccess($request); //Do the job
}

实际上,您可以直接尝试使用 ChainProcessor 来执行工作。如果无法完成工作,处理器将返回一个包含特殊状态码 Code202\Processor\Component\ResponseStatusCode::NOT_IMPLEMENTED 的响应。

使用 响应

使用 Response 时,您首先要做的是检查状态码,以了解工作是如何完成的。

<?php

use Code202\Processor\Component\ResponseStatusCode;

if ($response->getStatusCode() == ResponseStatusCode::OK) {
    // the job had been correctly done.
} else {
    $reasonPhrase = $response->getReasonPhrase();
    // The message who explain the cause of the status code
}

您还可以使用以下方法了解哪个 Processor 执行了工作(当您使用 ChainProcessor 时):

<?php

$response->getExtra('name');

显然,您可以使用方法 $response->getRequest() 获取初始请求(即获取输入)。

更重要的是,获取工作结果。

<?php

$response->getOutput();

构建您自己的 处理器

由于库中没有定义任何 Processor,因此它还没有准备好使用。您必须创建它们来执行您想要的工作。

为此,您只需创建一个实现了 Code202\Processor\Component\Processor 接口的新类。

<?php

use Code202\Processor\Component\Processor;
use Code202\Processor\Component\Response;
use Code202\Processor\Component\ResponseStatusCode;

class CustomProcessor implements Processor
{
    public function supports($request)
    {
        // With the $request you have to decide if this processor can do the job

        // i.e.
        return $request instanceof MyClass;
    }

    public function process($request)
    {
        // Advice : check the method 'supports'
        if (!$this->supports($request)) {
            return new Response($request, null, ResponseStatusCode::NOT_SUPPORTED);
        }

        // do the job

        // and return the Response

        return Response($request, $output); // $output had been create during the job was doing
    }
}

现在,您只需将其添加到 ChainProcessor 中。

<?php

$chainProcessor->add(new CustomProcessor());

更简单的方法

  • 使用 Code202\Processor\Component\ProcessorTrait 并实现 Code202\Processor\Component\Processor
  • 扩展 Code202\Processor\Component\AbstractProcessor (它使用 Code202\Processor\Component\ProcessTrait

为什么?因为进程方法

  • 在处理请求之前已经测试了请求是否由处理器支持
  • 如果您的处理器返回 null,则创建并返回一个状态码为 ResponseStatusCode::INTERNAL_ERRORResponse
  • 如果您的处理器抛出异常,则创建并返回一个状态码为 ResponseStatusCode::INTERNAL_ERRORResponse
  • 如果您的处理器返回一个非 null 值且不是 Response 的实例,则创建并返回一个状态码为 ResponseStatusCode::OKResponse

与先前方法的不同之处在于,'process' 方法必须调用 'doProcess' 并为 protected

使用 AbstractProcessor 的示例

<?php

use Code202\Processor\Component\AbstractProcessor;

class CustomProcessor extends AbstractProcessor
{
    public function supports($request)
    {
        // With the $request you have to decide if this processor can do the job

        // i.e.
        return $request instanceof MyClass;
    }

    protected function doPocess($request)
    {
        // No need to check if $request is supported

        // do the job

        // and return the Response
        // or nothing for bad response
        // or throw exception for bad response
        // or directly the ouput for bood response
    }
}

使用 ProcessorTrait 的示例

<?php

use Code202\Processor\Component\Processor;
use Code202\Processor\Component\ProcessorTrait;

class CustomProcessor implements Processor
{
    use ProcessorTrait;

    public function supports($request)
    {
        // With the $request you have to decide if this processor can do the job

        // i.e.
        return $request instanceof MyClass;
    }

    protected function doPocess($request)
    {
        return $this->otherMethod($request);
    }
}

与其他库的集成

Symfony

code-202/processor 包含一个 CompilerPass,可以自动将 Processor 连接到 ChainProcessor

配置

您可以使用类 Code202\Processor\Bridge\Symfony\DependencyInjection\Compiler\ProcessorPass 使用此 CompilerPass,或者像这样将捆绑包添加到您的 Symfony 内核中:

// app/AppKernel.php

public function registerBundles()
{
    $bundles = [
        // ...
        new Code202\Processor\Bridge\Symfony\Bundle\Code202ProcessorBundle(),
    ];

    // ...

    return $bundles;
}

要使用它,您需要引入 symfony/dependency-injectionsymfony/options-resolver 包(如果您不使用Symfony全栈)。

使用方法

现在您可以在服务(是 ChainProcessor 的实例)上使用标签 code202.processor.chain。所有带有此服务名称的标签服务都将添加到其中。

您可以在标签上添加 priority 参数来设置处理器的优先级(默认优先级为10)。

services:
    my_chain:
        class: Code202\Processor\Component\ChainProcessor
        tags:
            - { name: 'code202.processor.chain' }

    p1:
        class: Foo\Processor
        tags:
            - { name: 'my_chain', priority: 5 }
    p2:
        class: Bar\Processor
        tags:
            - { name: 'my_chain' }

在这个例子中,ChainProcessor my_chain 将接收两个 Processor p1p2

接下来呢?

Processor 的输入如果没有类型提示的限制,因此您可以真正地使用您想要的来创建请求。如果 ChainProcessor 中包含可以完成这项工作的 Processor,则它可以做您想做的事情...