
라우팅 미들웨어 (Routing Middleware)
라우팅은 미들웨어로 구현되었습니다. 기본 라우터로 FastRoute를 사용하고 있지만 이 라우터에 단단히 결합되어 있지는 않습니다. 다른 라우팅 라이브러리를 구현하려면 라우팅 인터페이스 구현을 직접 생성하면 됩니다. DispatcherInterface
, RouteCollectorInterface
, RouteParserInterface
, RouteResolverInterface
Slim의 구성 요소와 라우팅 라이브러리 사이에 브리지를 만듭니다. determineRouteBeforeAppMiddleware
를 사용하는 경우 호출 실행 직전 프로그램에 Middleware\RoutingMiddleware
미들웨어를 추가하여 이전 동작을 유지해야 합니다.
사용법
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware
$app->addRoutingMiddleware();
// ...
$app->run();
에러 미들웨어 (Error Middleware)
오류를 예측할 수는 없지만 예상할 수는 있습니다. 각 Slim Framework 응용 프로그램에는 검색되지 않은 모든 PHP 예외를 수신하는 오류 처리기가 있습니다. 이 오류 처리기는 현재 HTTP 요청 및 응답 개체도 수신합니다. 오류 처리기는 HTTP 클라이언트에 반환될 적절한 응답 오브젝트를 준비하고 반환해야 합니다.
사용법
<?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();
/**
* Add Error Middleware
*
* @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
* @param LoggerInterface|null $logger -> Optional PSR-3 Logger
*
* 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);
// ...
$app->run();
사용자 지정 오류 처리기 추가 (Adding Custom Error Handlers)
이제 예외 또는 버릴 수 있는 유형에 대해 사용자 지정 핸들러를 매핑할 수 있습니다.
<?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);
$errorMiddleware->setDefaultErrorHandler($customErrorHandler);
// ...
$app->run();
에러 로깅 (Error Logging)
Slim과 함께 제공되는 기본값인 ErrorHandler
에 사용자 지정 오류 로깅을 파이프로 연결하려는 경우 두 가지 방법이 있습니다.
첫 번째 방법을 사용하면 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();
두 번째 방법을 사용하면 인기 있는 Monolog 라이브러리와 같이 PSR-3 표준,을 준수하는 로거를 제공할 수 있습니다.
<?php
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use MyApp\Handlers\MyErrorHandler;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware
$app->addRoutingMiddleware();
// Monolog Example
$logger = new Logger('app');
$streamHandler = new StreamHandler(__DIR__ . '/var/log', 100);
$logger->pushHandler($streamHandler);
// Add Error Middleware with Logger
$errorMiddleware = $app->addErrorMiddleware(true, true, true, $logger);
// ...
$app->run();
오류 처리/렌더링 (Error Handling/Rendering)
렌더링이 드디어 핸들링에서 분리되었습니다. ErrorRenderers
의 도움을 받아 여전히 콘텐츠 유형을 탐지하고 적절히 렌더링합니다. 핵심 ErrorHandler
는 완전히 리팩터링된 ‘AbstractErrorHandler’ 클래스를 확장합니다. 기본적으로 지원되는 콘텐츠 유형에 적합한 ‘ErrorRenderer’를 호출합니다. 핵심 ‘ErrorHandler’는 다음과 같은 콘텐츠 유형에 대한 렌더러를 정의합니다.
application/json
application/xml
andtext/xml
text/html
text/plain
모든 콘텐츠 유형에 대해 자신의 오류 렌더러를 등록할 수 있습니다. 그러므로 먼저 \Slim\Interfaces\ErrorRendererInterface
를 구현하는 새로운 오류 렌더러를 정의합니다.
<?php
use Slim\Interfaces\ErrorRendererInterface;
use Throwable;
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();
오류 렌더링에 대해 특정 콘텐츠 유형 강제 적용 (Force a specific content type for error rendering)
기본적으로 오류 처리기는 요청의 Accept
헤더를 사용하여 오류 렌더러를 탐지하려고 합니다. 오류 핸들러가 특정 오류 렌더러를 사용하도록 강제해야 할 경우 다음을 작성할 수 있습니다.
$errorHandler->forceContentType('application/json');
새 HTTP 예외 (New HTTP Exceptions)
The base class HttpSpecializedException
extends Exception
and comes with the following sub classes:
애플리케이션 내에 명명된 HTTP 예외를 추가했습니다. 이러한 예외는 네이티브 렌더러에서 잘 작동합니다. 이들은 각각 ‘description’과 ‘title’ 속성을 가질 수 있으며 네이티브 HTML 렌더러가 호출될 때 조금 더 많은 통찰력을 제공할 수 있다.
기본 클래스 HttpSpecializedException
은 Exception
을 확장하며 다음과 같은 하위 클래스가 제공됩니다.
- HttpBadRequestException
- HttpForbiddenException
- HttpInternalServerErrorException
- HttpMethodNotAllowedException
- HttpNotFoundException
- HttpNotImplementedException
- HttpUnauthorizedException
기본 리포지토리에서 제공하지 않기로 결정한 다른 응답 코드가 필요한 경우 ‘HttpSpecializedException’ 클래스를 확장할 수 있습니다. 예를 들어 기본 게이트웨이와 동일하게 동작하는 504 게이트웨이 시간 초과 예외를 원할 경우 다음을 수행합니다.
class HttpForbiddenException 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.';
}