Ground Sunlight

Windowsで作る - Webプログラミングの開発環境(PHP)

ユーザ用ツール

サイト用ツール


サイドバー

メインメニュー

XAMPP アレンジ

道具箱

リポジトリ編

フレームワーク編

公開ソフトウェア

メタ
リンク


このページへのアクセス
今日: 1 / 昨日: 0
総計: 54

slim:4:middleware

Slim4 ミドルウェア

Version 4.5.0

y2sunlight 2020-09-23

Slim に戻る

関連記事

本章は以下のサイトの Packaged Middleware のセクションを翻訳し若干の補足を加えたのもです。


ルーティング

使用法

ルーティングはミドルウェアとして実装されています。まだデフォルトルーターとしてFastRouteを使用していますが、緊密に結合されているわかではありません。別のルーティングライブラリを実装したい場合は、ルーティングインターフェイスの独自の実装を作成することで可能になります。それは、Slimのコンポーネントとルーティングライブラリの間にブリッジを作成する DispatcherInterfaceRouteCollectorInterfaceRouteParserInterface、および 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レンダラーが呼び出されたときに、もう少し見識を与えるために、それぞれに descriptiontitle 属性を設定することもできます。

基本クラス HttpSpecializedExceptionException を拡張し、次のサブクラスが付属しています:

  • 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ハンドラーを変更する必要はありません。というのは、BodyParsingMiddlewareContent-TypeJSON メディアタイプに設定されていることを検出し、デコードされたボディをリクエストの 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();


コメント

コメントを入力. Wiki文法が有効です:
 
slim/4/middleware.txt · 最終更新: 2020/10/13 16:23 by y2sunlight