Slim3, как я могу управлять ошибками смешанного типа контента - PullRequest
0 голосов
/ 21 июня 2019

Мне нужно настроить приложение Slim для html и json содержимого.У меня будет только один обработчик ошибок, и он должен отвечать как json для json enpoints и html error page для html views.В старом модном Slim (v.2) я определил вид в начале маршрута, поэтому я мог проверить тип вида (веточка или json), чтобы понять, как ответить.

С новым Slim3Реализация представления будет отправлена ​​в конце маршрута, и, насколько я знаю, нет способа определить его ранее.

Как я могу управлять ошибками смешанного содержимого?

Я подумал использовать заголовок типа контента запроса, но нет реального правила, что тип контента должен быть согласован с ответом, например, я могу отправить некоторый запрос в виде application / json и получить ответ text / html, я также не могуиспользуйте заголовок Accept, потому что он может отсутствовать или быть общим */*.

1 Ответ

0 голосов
/ 30 июня 2019

Полагаю, это зависит от того, как вы решите, между возвращением формата json или html.

Например, вы можете вернуть ошибку в формате json, когда она запрашивается из AJAX, в противном случае вы возвращаете html.

Если у вас есть обработчик ошибок, который возвращает html как следующий код

<?php namespace Your\App\Name\Space\Errors;

class HtmlErrorHandler
{

    public function __invoke($request, $response, $exception)
    {
        $err = '<html><head></head><body>' .
            '<div>code : ' . $exception->getCode() . 
            ' message' . $exception->getMessage() '</div>';
        return $response->withStatus(500)
            ->withHeader('content-Type : text/html')
            ->write($err);
    }
}

и обработчик ошибок, который возвращает json,

<?php namespace Your\App\Name\Space\Errors;

class JsonErrorHandler
{    
    public function __invoke($request, $response, $exception)
    {
        $err = (object) [
            'code' => $exception->getCode(),
            'message' => $exception->getMessage(),
        ];
        return $response->withStatus(500)->withJson($err);
    }
}

Вы можете составить их в другом обработчике ошибоккласс, который выбирает, какой обработчик ошибок будет возвращать ответ об ошибке в зависимости от того, поступил ли запрос от AJAX.

<?php namespace Your\App\Name\Space\Errors;

class Http500Error
{
    private $jsonErrorHandler;
    private $htmlErrorHandler;

    public function __construct($jsonErrHandler, $htmlErrHandler) 
    {
        $this->jsonErrorHandler = $jsonErrHandler;
        $this->htmlErrorHandler = $htmlErrHandler;
    }

    public function __invoke($request, $response, $exception)
    {
        if ($request->isXhr()) {
            $errHandler = $this->jsonErrorHandler;
        } else {
            $errHandler = $this->htmlErrorHandler;        
        }
        return $errHandler($request, $response, $exception);
    }
}

Или вы можете поместить некоторую переменную в строку запроса, чтобы указать, какой формат клиент хочет, тогда вы можете использовать

if ($request->getParam('format', 'html') === 'json') {
    $errHandler = $this->jsonErrorHandler;
} else {
    $errHandler = $this->htmlErrorHandler;        
}

Затем вы вводите обработчик ошибок в контейнер

use Your\App\Name\Space\Errors;
...
$app = new \Slim\App();
$c = $app->getContainer();
$c['errorHandler'] = function ($c) {
    return new Http500Error(new JsonErrorHandler(), new HtmlErrorHandler());
};
...