メインメニュー
XAMPP アレンジ
IED
WSL2
-
道具箱
リポジトリ編
フレームワーク編
公開ソフトウェア
メタ
リンク
- PHP ライブラリ
- PHP 言語
slim:4:middleware目次
Slim4 ミドルウェア
Version 4.5.0
— y2sunlight 2020-09-23
関連記事
- Slim4 ミドルウェア
本章は以下のサイトの Packaged Middleware のセクションを翻訳し若干の補足を加えたのもです。
ルーティング
使用法
ルーティングはミドルウェアとして実装されています。まだデフォルトルーターとしてFastRouteを使用していますが、緊密に結合されているわかではありません。別のルーティングライブラリを実装したい場合は、ルーティングインターフェイスの独自の実装を作成することで可能になります。それは、Slimのコンポーネントとルーティングライブラリの間にブリッジを作成する
DispatcherInterface
、RouteCollectorInterface
、RouteParserInterface
、およびRouteResolverInterface
です。もしdetermineRouteBeforeAppMiddleware
を使用していた場合は、以前の動作を維持するために、run()
を呼び出す直前にMiddleware\RoutingMiddleware
ミドルウェアをアプリケーションに追加する必要があります。<?php use Slim\Factory\AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add Routing Middleware $app->addRoutingMiddleware(); // ... $app->run();
エラー処理
物事はうまくいかない。エラーを予言することはできませんが、予想することはできます。それぞれの Slim Framework アプリケーションには、キャッチされなかったすべてのPHP例外を受け取るエラーハンドラーがあります。このエラーハンドラーは、現在のHTTPリクエスト及びレスポンスオブジェクトも受信します。エラーハンドラは、HTTPクライアントに返される適切なResponseオブジェクトを準備して返す必要があります。
使用法
<?php use Slim\Factory\AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); /** * The routing middleware should be added earlier than the ErrorMiddleware * Otherwise exceptions thrown from it will not be handled by the middleware */ $app->addRoutingMiddleware(); /** * @param bool $displayErrorDetails -> Should be set to false in production * @param bool $logErrors -> Parameter is passed to the default ErrorHandler * @param bool $logErrorDetails -> Display error details in error log * which can be replaced by a callable of your choice. * @param \Psr\Log\LoggerInterface $logger -> Optional PSR-3 logger to receive errors * * Note: This middleware should be added last. It will not handle any exceptions/errors * for middleware added after it. */ $errorMiddleware = $app->addErrorMiddleware(true, true, true, $logger); // ... $app->run();
カスタムエラーハンドラーの追加
あらゆるタイプの Exception または Throwable のカスタムハンドラーをマップできるようになります。
<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Slim\Factory\AppFactory; use Slim\Psr7\Response; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add Routing Middleware $app->addRoutingMiddleware(); // Define Custom Error Handler $customErrorHandler = function ( ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails, ?LoggerInterface $logger = null ) use ($app) { $logger->error($exception->getMessage()); $payload = ['error' => $exception->getMessage()]; $response = $app->getResponseFactory()->createResponse(); $response->getBody()->write( json_encode($payload, JSON_UNESCAPED_UNICODE) ); return $response; }; // Add Error Middleware $errorMiddleware = $app->addErrorMiddleware(true, true, true, $logger); $errorMiddleware->setDefaultErrorHandler($customErrorHandler); // ... $app->run();
エラーロギング
Slimに同梱されているデフォルトの
ErrorHandler
にカスタムエラーロギングをパイプする場合には、2つの方法があります。最初の方法では、
ErrorHandler
を拡張し、logError()
メソッドをスタブ化するだけです。<?php namespace MyApp\Handlers; use Slim\Handlers\ErrorHandler; class MyErrorHandler extends ErrorHandler { protected function logError(string $error): void { // Insert custom error logging function. } }
<?php use MyApp\Handlers\MyErrorHandler; use Slim\Factory\AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add Routing Middleware $app->addRoutingMiddleware(); // Instantiate Your Custom Error Handler $myErrorHandler = new MyErrorHandler($app->getCallableResolver(), $app->getResponseFactory()); // Add Error Middleware $errorMiddleware = $app->addErrorMiddleware(true, true, true); $errorMiddleware->setDefaultErrorHandler($myErrorHandler); // ... $app->run();
2番目の方法では、人気のある Monolog ライブラリからのものなど、PSR-3 規約に準拠するロガーを提供できます。
<?php use MyApp\Handlers\MyErrorHandler; use Slim\Factory\AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add Routing Middleware $app->addRoutingMiddleware(); // Instantiate Logger // $logger = ... // Add Error Middleware with Logger $errorMiddleware = $app->addErrorMiddleware(true, true, true, $logger); // ... $app->run();
エラー処理とレンダリング
レンダリングは最終的にエラー処理から切り離されています。それでもコンテンツタイプを検出し、
ErrorRenderers
の助けを借りて適切にレンダリングします。 コアのErrorHandler
は、完全にリファクタリングされたAbstractErrorHandler
クラスを拡張します。デフォルトでは、サポートされているコンテンツタイプに合わせたErrorRenderer
が呼び出されます。コアのErrorHandler
は、次のコンテンツタイプのレンダラーを定義します。- application/json
- application/xml とtext/xml
- text/html
- text/plain
どのコンテンツタイプでも、独自のエラーレンダラーを登録できます。従って、最初に
\Slim\Interfaces\ErrorRendererInterface
を実装する新しいエラーレンダラーを定義します。<?php use Slim\Interfaces\ErrorRendererInterface; class MyCustomErrorRenderer implements ErrorRendererInterface { public function __invoke(Throwable $exception, bool $displayErrorDetails): string { return 'My awesome format'; } }
次に、そのエラーレンダラーをコアエラーハンドラーに登録します。以下の例では、
text/html
コンテンツタイプに使用されるレンダラーを登録しています。<?php use MyApp\Handlers\MyErrorHandler; use Slim\Factory\AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add Routing Middleware $app->addRoutingMiddleware(); // Add Error Middleware $errorMiddleware = $app->addErrorMiddleware(true, true, true); // Get the default error handler and register my custom error renderer. $errorHandler = $errorMiddleware->getDefaultErrorHandler(); $errorHandler->registerErrorRenderer('text/html', MyCustomErrorRenderer::class); // ... $app->run();
エラーレンダリングに特定のコンテンツタイプを強制する
デフォルトでは、エラーハンドラーは、リクエストの
Accept
ヘッダーを使用してエラーレンダラーの検出を試みます。エラーハンドラーに特定のエラーレンダラーを使用させる必要がある場合は、次のように記述できます。$errorHandler->forceContentType('application/json');
新しいHTTP例外
アプリケーション内に名前付きHTTP例外を追加しています。これらの例外は、ネイティブなレンダラーでうまく機能します。ネイティブHTMLレンダラーが呼び出されたときに、もう少し見識を与えるために、それぞれに
description
とtitle
属性を設定することもできます。基本クラス
HttpSpecializedException
はException
を拡張し、次のサブクラスが付属しています:- HttpBadRequestException
- HttpForbiddenException
- HttpInternalServerErrorException
- HttpNotAllowedException
- HttpNotFoundException
- HttpNotImplementedException
- HttpUnauthorizedException
Example if you wanted a 504 gateway timeout exception that behaves like the native ones you would do the following:
ベースリポジトリで提供しないと判断した他のレスポンスコードが必要な場合は、
HttpSpecializedException
クラスを拡張できます。例えば、ネイティブのように動作する504ゲートウェイタイムアウト例外が必要な場合は、次のようにします:class HttpGatewayTimeoutException extends HttpSpecializedException { protected $code = 504; protected $message = 'Gateway Timeout.'; protected $title = '504 Gateway Timeout'; protected $description = 'Timed out before receiving response from the upstream server.'; }
メソッドオーバライド
メソッドオーバライド ミドルウエアを使用すると、
X-Http-Method-Override
リクエストヘッダーまたはリクエストボディのパラメータ_METHOD
を使用して、着信リクエストのメソッドをオーバーライドできます。このミドルウェアは、ルーティングミドルウェアが追加された後に配置する必要があります。使用法
<?php use Slim\Factory\AppFactory; use Slim\Middleware\MethodOverrideMiddleware; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Add RoutingMiddleware before we add the MethodOverrideMiddleware so the method is overrode before routing is done $app->addRoutingMiddleware(); // Add MethodOverride middleware $methodOverrideMiddleware = new MethodOverrideMiddleware(); $app->add($methodOverrideMiddleware); // ... $app->run();
出力バッファリング
出力バッファリング ミドルウェアを使用すると、出力バッファリングの2つのモード(
APPEND
(デフォルト)とPREPEND
モード)を切り替えることができます。APPEND
モードでは、既存のレスポンスボディを使用してコンテンツを追加します。PREPEND
モードは、新しいレスポンスボディ オブジェクトを作成し、既存のレスポンスボディからの出力の前にコンテンツを追加します。このミドルウェアは、最後に実行されるようにミドルウェアスタックの中央に配置する必要があります。使用法
<?php use Slim\Factory\AppFactory; use Slim\Middleware\OutputBufferingMiddleware; use Slim\Psr7\Factory\StreamFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); $streamFactory = new StreamFactory(); /** * The two modes available are * OutputBufferingMiddleware::APPEND (default mode) - Appends to existing response body * OutputBufferingMiddleware::PREPEND - Creates entirely new response body */ $mode = OutputBufferingMiddleware::APPEND; $outputBufferingMiddleware = new OutputBufferingMiddleware($streamFactory, $mode); $app->add($outputBufferingMiddleware); // ... $app->run();
ボディ解析
Web APIでは、JSONまたはXML形式でデータを送信するのが非常に一般的です。箱から出しも、PSR-7の実装はこれらの形式をサポートしていません。リクエストオブジェクトの
getBody()
を自分でデコードする必要があります。これは一般的な要件であるため、Slim4はこのタスクを処理するためのBodyParsingMiddleware
を提供します。使用法
addErrorMiddlware
を呼び出す前に、ボディ解析ミドルウェアを配置して、スタックが次のようになるようにすることをお勧めします:<?php use Slim\Factory\AppFactory; require_once __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); // Parse json, form data and xml $app->addBodyParsingMiddleware(); $app->addRoutingMiddleware(); $app->addErrorMiddleware(true, true, true); // ... $app->run();
ポストされたJSON、フォーム、XMLデータ
POSTハンドラーを変更する必要はありません。というのは、
BodyParsingMiddleware
はContent-Type
がJSON
メディアタイプに設定されていることを検出し、デコードされたボディをリクエストの parsed bodyプロパティに配置するからです。ブラウザからウェブサイトにポストされたデータの場合、$request の
getParsedBody()
メソッドを使用できます。これにより、投稿されたデータの配列が返されます。
$app->post('/', function (Request $request, Response $response, $args): Response { $data = $request->getParsedBody(); $html = var_export($data, true); $response->getBody()->write($html); return $response; });
メディアタイプの検出
- ミドルウェアは、リクエストヘッダーから
Content-Type
を読み取り、メディアタイプを検出します。 - この特定のメディアタイプにパーサーが登録されているかどうかを確認します。
- そうでない場合は、構造化された構文サフィックス(RFC 6839)が付いたメディアタイプを探します。例えば:
application/*
サポートされているメディアタイプ
- application/json
- application/x-www-form-urlencoded
- application/xml
- text/xml
Content Length
Content Length ミドルウェアは、
Content-Length
ヘッダーをレスポンスに自動的に追加します。これは、Slim3 から削除されたaddContentLengthHeader
の設定を置き換えるためのものです。このミドルウェアは、最後に実行されるように、ミドルウェアスタックの中央に配置する必要があります。使用法
<?php use Slim\Factory\AppFactory; use Slim\Middleware\ContentLengthMiddleware; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); $contentLengthMiddleware = new ContentLengthMiddleware(); $app->add($contentLengthMiddleware); // ... $app->run();
slim/4/middleware.txt · 最終更新: 2020/10/13 16:23 by y2sunlight
コメント