tobento / service-responser
Providing PSR-7 response wrapper classes with simplified methods.
Requires
- php: >=8.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- tobento/service-filesystem: ^1.0
- tobento/service-message: ^1.0
- tobento/service-support: ^1.0
Requires (Dev)
- nyholm/psr7: ^1.4
- phpunit/phpunit: ^9.5
- tobento/service-container: ^1.0
- tobento/service-middleware: ^1.0
- tobento/service-session: ^1.0
- tobento/service-view: ^1.0
- vimeo/psalm: ^4.0
Suggests
- tobento/service-session: Storage implementation for flashing input and messages.
- tobento/service-view: Renderer implementation for render response.
This package is not auto-updated.
Last update: 2024-12-22 00:51:25 UTC
README
Providing PSR-7 response wrapper classes with simplified methods.
Table of Contents
Getting started
Add the latest version of the requester service project running this command.
composer require tobento/service-responser
Requirements
- PHP 8.0 or greater
Highlights
- Framework-agnostic, will work with any project
- Decoupled design
- Flash messages
- Flash input data
Documentation
Responser
Create Responser
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)
Renderer
You may add a renderer if you want to Render View Responses.
Firstly, make sure you have the view service installed if you want to use the view renderer, otherwise you may implement your own renderer:
composer require tobento/service-view
Check out the View Service to learn more about it in general.
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)
Storage
You may add a storage if you want to flash messages and/or input data.
Firstly, make sure you have the session service installed if you want to use the session storage, otherwise you may implement your own storage:
composer require tobento/service-session
Check out the Session Service to learn more about how to start 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 Response
Writes HTML into the body response and sets "text/html; charset=utf-8" content-type header.
use Psr\Http\Message\ResponseInterface; $response = $responser->html( html: 'html', code: 200, // is default ); var_dump($response instanceof ResponseInterface); // bool(true)
Json Response
Writes JSON data into the body response and sets "application/json" content-type header.
use Psr\Http\Message\ResponseInterface; $response = $responser->json( data: ['key' => 'value'], code: 200, // is default ); var_dump($response instanceof ResponseInterface); // bool(true)
Render View Response
Renders the specified view writing into the body response and sets "text/html; charset=utf-8" content-type header as default.
Check out Renderer to learn more about the renderer implementation.
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)
Any Content Response
Writes data into the body response.
use Psr\Http\Message\ResponseInterface; $response = $responser->write( data: 'data', // mixed code: 200, // is default ); var_dump($response instanceof ResponseInterface); // bool(true)
Redirect Response
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)
Messages
You may add messages for the current and/or next request.
Check out the Message Service to learn more about it in general.
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(), ], );
in views/shop/products.php
<?php foreach($messages as $message) { ?> <?= $message ?> <?php } ?>
Flash Messages
You will need to provide a storage in order to flash messages.
Check out Storage to learn more about the storage implementation.
$responser->messages()->add('error', 'Error message'); $response = $responser->redirect('uri');
On the redirected uri:
$response = $responser->render( view: 'shop/products', data: [ 'products' => [], 'messages' => $responser->messages(), ], );
Flash Input Data
You will need to provide a storage in order to flash input data.
Check out Storage to learn more about the storage implementation.
$response = $responser ->withInput(['key' => 'value']) ->redirect('uri');
On the redirected uri:
$input = $responser->getInput();
Using middleware
You may check out the Merge Input Middleware to merge the input data with the request data.
Additional Responser Methods
create
You may create a response from the response factory:
use Psr\Http\Message\ResponseInterface; $response = $responser->create(200); var_dump($response instanceof ResponseInterface); // bool(true)
streamFactory
You may get the stream factory:
use Psr\Http\Message\StreamFactoryInterface; $streamFactory = $responser->streamFactory(); var_dump($streamFactory instanceof StreamFactoryInterface); // bool(true)
file
You may get the file responser:
Check out File Responser to learn more about the file repsonser in general.
use Tobento\Service\Responser\FileResponserInterface; $file = $responser->file(); var_dump($file instanceof FileResponserInterface); // bool(true)
info
You may get the response info:
Check out Response Info to learn more about the response info in general.
use Tobento\Service\Responser\ResponseInfo; $info = $responser->info($responser->create(403)); var_dump($info instanceof ResponseInfo); // bool(true)
File Responser
Create File Responser
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)
Render File Response
Create response to render (display) the file on browser.
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)
Parameters explanation
Download File Response
Create response to download the file.
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)
Parameters explanation
Additional File Responser Methods
create
You may create a response from the response factory:
use Psr\Http\Message\ResponseInterface; $response = $fileResponser->create(200); var_dump($response instanceof ResponseInterface); // bool(true)
streamFactory
You may get the stream factory:
use Psr\Http\Message\StreamFactoryInterface; $streamFactory = $fileResponser->streamFactory(); var_dump($streamFactory instanceof StreamFactoryInterface); // bool(true)
info
You may get the response info:
Check out Response Info to learn more about the response info in general.
use Tobento\Service\Responser\ResponseInfo; $info = $fileResponser->info($fileResponser->create(403)); var_dump($info instanceof ResponseInfo); // bool(true)
Response Info
use Tobento\Service\Responser\ResponseInfo; use Psr\Http\Message\ResponseInterface; $responseInfo = new ResponseInfo( response: $response // ResponseInterface );
isInformational
If the response is informational, status codes 1xx.
var_dump($responseInfo->isInformational()); // bool(true)
isSuccessful
If the response is successfull, status codes 2xx.
var_dump($responseInfo->isSuccessful()); // bool(true)
isRedirection
If the response is a redirection, status codes 3xx.
var_dump($responseInfo->isRedirection()); // bool(true)
isClientError
If the response is a client error, status codes 4xx.
var_dump($responseInfo->isClientError()); // bool(true)
isServerError
If the response is a server error, status codes 5xx.
var_dump($responseInfo->isServerError()); // bool(true)
isOk
If the response is ok, status code 200.
var_dump($responseInfo->isOk()); // bool(true)
isForbidden
If the response is a forbidden error, status code 403.
var_dump($responseInfo->isForbidden()); // bool(true)
isNotFound
If the response is a not found error, status code 404.
var_dump($responseInfo->isNotFound()); // bool(true)
isCode
If the response is of the specified status code(s).
var_dump($responseInfo->isCode(403, 404)); // bool(true)
Middleware
Responser Middleware
Adds the responser to the request attributes.
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);
Merge Input Middleware
Merges the responser input with the request input.
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);