tobento/service-responser

提供具有简化方法的PSR-7响应包装类。

1.0.0 2022-02-04 12:10 UTC

This package is not auto-updated.

Last update: 2024-09-28 23:35:13 UTC


README

提供具有简化方法的PSR-7响应包装类。

目录

入门指南

使用以下命令添加运行此项目的请求服务项目最新版本。

composer require tobento/service-responser

需求

  • PHP 8.0 或更高版本

亮点

  • 框架无关,可与任何项目一起使用
  • 解耦设计
  • 闪存消息
  • 闪存输入数据

文档

响应器

创建响应器

use Tobento\Service\Responser\Responser;
use Tobento\Service\Responser\ResponserInterface;
use Tobento\Service\Responser\RendererInterface;
use Tobento\Service\Responser\StorageInterface;
use Tobento\Service\Message\MessagesInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

$psr17Factory = new Psr17Factory();

$responser = new Responser(
    responseFactory: $psr17Factory, // Any PSR-17 ResponseFactoryInterface
    streamFactory: $psr17Factory, // Any PSR-17 StreamFactoryInterface
    renderer: null, // null|RendererInterface
    storage: null, // null|StorageInterface
    messages: null, // null|MessagesInterface
);

var_dump($responser instanceof ResponserInterface);
// bool(true)

渲染器

如果您想 渲染视图响应,则可以添加渲染器。

首先,如果您想使用视图渲染器,请确保已安装视图服务,否则您可以自己实现渲染器。

composer require tobento/service-view

查看 视图服务 了解更多信息。

use Tobento\Service\Responser\RendererInterface;
use Tobento\Service\Responser\ViewRenderer;
use Tobento\Service\View\View;
use Tobento\Service\View\PhpRenderer;
use Tobento\Service\Dir\Dirs;
use Tobento\Service\Dir\Dir;

$view = new View(
    new PhpRenderer(
        new Dirs(
            new Dir('/private/views/'),
        )
    )
);

$renderer = new ViewRenderer($view);

var_dump($renderer instanceof RendererInterface);
// bool(true)

存储

如果您想闪存消息和/或输入数据,则可以添加存储。

首先,如果您想使用会话存储,请确保已安装会话服务,否则您可以自己实现存储。

composer require tobento/service-session

查看 会话服务 了解如何启动会话的更多信息。

use Tobento\Service\Responser\StorageInterface;
use Tobento\Service\Responser\SessionStorage;
use Tobento\Service\Session\Session;

$session = new Session('name');

$storage = new SessionStorage($session);

var_dump($storage instanceof StorageInterface);
// bool(true)

HTML响应

将HTML写入响应体并将内容类型头设置为"text/html; charset=utf-8"。

use Psr\Http\Message\ResponseInterface;

$response = $responser->html(
    html: 'html',
    code: 200, // is default
);

var_dump($response instanceof ResponseInterface);
// bool(true)

JSON响应

将JSON数据写入响应体并将内容类型头设置为"application/json"。

use Psr\Http\Message\ResponseInterface;

$response = $responser->json(
    data: ['key' => 'value'],
    code: 200, // is default
);

var_dump($response instanceof ResponseInterface);
// bool(true)

渲染视图响应

渲染指定的视图并将其写入响应体,默认内容类型头为"text/html; charset=utf-8"。

查看 渲染器 了解渲染器实现的更多信息。

use Psr\Http\Message\ResponseInterface;

$response = $responser->render(
    view: 'shop/products',
    data: ['products' => []],
    code: 200, // is default
    contentType: 'text/html; charset=utf-8', // is default
);

var_dump($response instanceof ResponseInterface);
// bool(true)

任何内容响应

将数据写入响应体。

use Psr\Http\Message\ResponseInterface;

$response = $responser->write(
    data: 'data', // mixed
    code: 200, // is default
);

var_dump($response instanceof ResponseInterface);
// bool(true)

重定向响应

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
use Stringable;

$response = $responser->redirect(
    uri: 'uri', // string|Stringable|UriInterface
    code: 302, // is default
);

var_dump($response instanceof ResponseInterface);
// bool(true)

消息

您可以添加当前和/或下一个请求的消息。

查看 消息服务 了解更多信息。

use Tobento\Service\Message\MessagesInterface;

var_dump($responser->messages() instanceof MessagesInterface);
// bool(true)

$responser->messages()->add('success', 'Success message');

$response = $responser->render(
    view: 'shop/products',
    data: [
        'products' => [],
        'messages' => $responser->messages(),
    ],
);

在 views/shop/products.php 中

<?php foreach($messages as $message) { ?>
    <?= $message ?>
<?php } ?>

闪存消息

您需要提供一个存储来闪存消息。
查看 存储 了解存储实现的更多信息。

$responser->messages()->add('error', 'Error message');

$response = $responser->redirect('uri');

在重定向的URI上

$response = $responser->render(
    view: 'shop/products',
    data: [
        'products' => [],
        'messages' => $responser->messages(),
    ],
);

闪存输入数据

您需要提供一个存储来闪存输入数据。
查看 存储 了解存储实现的更多信息。

$response = $responser
    ->withInput(['key' => 'value'])
    ->redirect('uri');

在重定向的URI上

$input = $responser->getInput();

使用中间件

您可以使用 合并输入中间件 来合并输入数据与请求数据。

其他响应器方法

创建

您可以从响应工厂创建响应

use Psr\Http\Message\ResponseInterface;

$response = $responser->create(200);

var_dump($response instanceof ResponseInterface);
// bool(true)

streamFactory

您可以得到流工厂

use Psr\Http\Message\StreamFactoryInterface;

$streamFactory = $responser->streamFactory();

var_dump($streamFactory instanceof StreamFactoryInterface);
// bool(true)

文件

您可以得到文件响应器

查看 文件响应器 了解文件响应器的更多信息。

use Tobento\Service\Responser\FileResponserInterface;

$file = $responser->file();

var_dump($file instanceof FileResponserInterface);
// bool(true)

信息

您可以得到响应信息

查看 响应信息 了解响应信息的更多信息。

use Tobento\Service\Responser\ResponseInfo;

$info = $responser->info($responser->create(403));

var_dump($info instanceof ResponseInfo);
// bool(true)

文件响应器

创建文件响应器

use Tobento\Service\Responser\FileResponser;
use Tobento\Service\Responser\FileResponserInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

$psr17Factory = new Psr17Factory();

$fileResponser = new FileResponser(
    responseFactory: $psr17Factory, // Any PSR-17 ResponseFactoryInterface
    streamFactory: $psr17Factory, // Any PSR-17 StreamFactoryInterface
);

var_dump($fileResponser instanceof FileResponserInterface);
// bool(true)

渲染文件响应

创建响应以在浏览器上渲染(显示)文件。

use Tobento\Service\Filesystem\File;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\ResponseInterface;

$response = $fileResponser->render(
    file: 'file.jpg', // string|File|StreamInterface|resource
    name: 'File', // string
    contentType: 'image/jpeg', // null|string
);

var_dump($response instanceof ResponseInterface);
// bool(true)

参数说明

下载文件响应

创建响应以下载文件。

use Tobento\Service\Filesystem\File;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\ResponseInterface;

$response = $fileResponser->download(
    file: 'file.jpg' // string|File|StreamInterface|resource
    name: 'File', // string
    contentType: 'image/jpeg', // null|string    
);

var_dump($response instanceof ResponseInterface);
// bool(true)

参数说明

其他文件响应器方法

创建

您可以从响应工厂创建响应

use Psr\Http\Message\ResponseInterface;

$response = $fileResponser->create(200);

var_dump($response instanceof ResponseInterface);
// bool(true)

streamFactory

您可以得到流工厂

use Psr\Http\Message\StreamFactoryInterface;

$streamFactory = $fileResponser->streamFactory();

var_dump($streamFactory instanceof StreamFactoryInterface);
// bool(true)

信息

您可以得到响应信息

查看 响应信息 了解响应信息的更多信息。

use Tobento\Service\Responser\ResponseInfo;

$info = $fileResponser->info($fileResponser->create(403));

var_dump($info instanceof ResponseInfo);
// bool(true)

响应信息

use Tobento\Service\Responser\ResponseInfo;
use Psr\Http\Message\ResponseInterface;

$responseInfo = new ResponseInfo(
    response: $response // ResponseInterface
);

isInformational

如果响应为信息性,状态码为1xx

var_dump($responseInfo->isInformational());
// bool(true)

isSuccessful

如果响应成功,状态码为2xx

var_dump($responseInfo->isSuccessful());
// bool(true)

isRedirection

如果响应为重定向,状态码为3xx

var_dump($responseInfo->isRedirection());
// bool(true)

isClientError

如果响应为客户端错误,状态码为4xx

var_dump($responseInfo->isClientError());
// bool(true)

isServerError

如果响应为服务器错误,状态码为5xx

var_dump($responseInfo->isServerError());
// bool(true)

isOk

如果响应正常,状态码为200

var_dump($responseInfo->isOk());
// bool(true)

isForbidden

如果响应为禁止错误,状态码为403

var_dump($responseInfo->isForbidden());
// bool(true)

isNotFound

如果响应为未找到错误,状态码为404

var_dump($responseInfo->isNotFound());
// bool(true)

isCode

如果响应为指定的状态码。

var_dump($responseInfo->isCode(403, 404));
// bool(true)

中间件

响应器中间件

将响应器添加到请求属性中。

use Tobento\Service\Responser\Responser;
use Tobento\Service\Responser\ResponserInterface;
use Tobento\Service\Responser\Middleware;
use Tobento\Service\Middleware\MiddlewareDispatcher;
use Tobento\Service\Middleware\AutowiringMiddlewareFactory;
use Tobento\Service\Middleware\FallbackHandler;
use Tobento\Service\Container\Container;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

$psr17Factory = new Psr17Factory();

// create middleware dispatcher.
$dispatcher = new MiddlewareDispatcher(
    new FallbackHandler($psr17Factory->createResponse(404)),
    new AutowiringMiddlewareFactory(new Container()) // any PSR-11 container
);

$dispatcher->add(new Middleware\Responser(
    new Responser($psr17Factory, $psr17Factory)
));

$dispatcher->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
    
    $responser = $request->getAttribute(ResponserInterface::class);
    
    var_dump($responser instanceof ResponserInterface);
    // bool(true)
    
    return $handler->handle($request);
});

$request = $psr17Factory->createServerRequest('GET', 'https://example.com');

$response = $dispatcher->handle($request);

合并输入中间件

将响应器输入与请求输入合并。

use Tobento\Service\Responser\Responser;
use Tobento\Service\Responser\ResponserInterface;
use Tobento\Service\Responser\Middleware;
use Tobento\Service\Middleware\MiddlewareDispatcher;
use Tobento\Service\Middleware\AutowiringMiddlewareFactory;
use Tobento\Service\Middleware\FallbackHandler;
use Tobento\Service\Container\Container;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

$psr17Factory = new Psr17Factory();

$container = new Container();
$container->set(ResponserInterface::class, Responser::class)->construct($psr17Factory, $psr17Factory);

// create middleware dispatcher.
$dispatcher = new MiddlewareDispatcher(
    new FallbackHandler($psr17Factory->createResponse(404)),
    new AutowiringMiddlewareFactory($container) // any PSR-11 container
);

// Simulating Previous request
$dispatcher->add(Middleware\Responser::class);

$dispatcher->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
    
    $responser = $request->getAttribute(ResponserInterface::class);
    
    $responser->withInput(['key' => 'value']);
    
    return $handler->handle($request);
});

// Current request
$dispatcher->add(Middleware\ResponserMergeInput::class);

$dispatcher->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
    
    var_dump($request->getQueryParams()['key']);
    // string(5) "value"
    
    return $handler->handle($request);
});

$request = $psr17Factory->createServerRequest('GET', 'https://example.com');

$response = $dispatcher->handle($request);

致谢