Если Вы обновляете свое приложение с 3 версии на 4, вы должны быть в курсе следующих значительных изменений.
Slim 4 требует PHP 7.2 и выше.
Настройки приложения хранились в контейнере. Теперь они вынесены отдельно.
/**
* Slim 3 App::__construct($container = [])
* Раньше настройки передавались в конструкторе
*/
$app = new App([
'settings' => [...],
]);
/**
* Slim 4 App::__constructor() метод принимает 1 обязательный и 4 опциональных параметра
*
* @param ResponseFactoryInterface Любая реализация ResponseFactory
* @param ContainerInterface|null Любая реализация Container
* @param CallableResolverInterface|null Любая реализация CallableResolver
* @param RouteCollectorInterface|null Любая реализация RouteCollector
* @param RouteResolverInterface|null Любая реализация RouteResolver
*/
$app = new App(...);addContentLengthHeader См Middleware размера ответа для новой реализации данной настройки.determineRouteBeforeAppMiddleware Добавьте Middleware маршрутизации в правильную позицию вашего стека middleware, чтобы воспроизвести нужное поведение.outputBuffering См Middleware буферизации вывода для новой реализации данной настройки.displayErrorDetails См Middleware обработки ошибок для новой реализации данной настройки.Slim больше не включает в комплект пакет контейнера, вам нужно самостоятельно выбрать и установить любимый контейнер. Также был удален магический метод App::__call(), поэтому доступ к свойству контейнера через $app->key_name() больше не работает.
/**
* Slim 3.x поставляется с контейнером Pimple и включает следующий синтаксис
*/
$container = $app->getContainer();
// сервисы назначаются как в массиве
$container['view'] = function (\Psr\Container\ContainerInterface $container){
return new \Slim\Views\Twig('');
};
/**
* Slim 4.x не включает библиотеку контейнера. Он поддерживает любую реализацию PSR-11, например PHP-DI
* Для установки PHP-DI выполните команду <code class="language-plaintext highlighter-rouge">composer require php-di/php-di</code>
*/
use Slim\Factory\AppFactory;
$container = new \DI\Container();
AppFactory::setContainer($container);
$app = AppFactory::create();
$container = $app->getContainer();
$container->set('view', function(\Psr\Container\ContainerInterface $container){
return new \Slim\Views\Twig('');
});До версии 3, Slim извлекал базовый путь из директории, в которой был создан объект приложения. Теперь базовый путь должен быть вручную объявлен, если приложение выполняется не из корня домена:
use Slim\Factory\AppFactory;
// ...
$app = AppFactory::create();
$app->setBasePath('/my-app-subpath');
// ...
$app->run();Компонент Router из Slim 3 разделен на несколько компонентов (RouteCollector, RouteParser и RouteResolver),
чтобы отделить библиотеку FastRoute от ядра App и предоставить разработчикам большую гибкость.
Эти компоненты имеют свои интерфейсы, которые вы можете самостоятельно реализовать и добавить в конструктор App.
Следующие пул-реквесты предоставят достаточно информации об интерфейсах новых компонентов:
Это значит, что группы маршрутов тоже изменили свои сигнатуры:
$app->group('/user', function(\Slim\Routing\RouteCollectorProxy $app){
$app->get('', function() { /* ... */ });
//...
});В Slim 4 мы хотели предоставить разработчикам больше гибкости и вынесли некоторые функциональные возможности в middleware. Это дает вам возможность использовать собственные реализации основных компонентов.
Очередность выполнения middleware не изменилась с версии 3 (Последний вошёл, первый вышел (LIFO)).
Компонент AppFactory был введен для упрощения некоторых изменений, связанных с отделением реализации PSR-7 от ядра.
Он определяет имеющуюся в проекте реализацию PSR-7 и PSR-17, что позволяет создать экземпляр приложения с помощью AppFactory::create() и использовать App::run() для его запуска без создания объекта ServerRequest.
Поддерживаются следующие реализации PSR-7 и создатели ServerRequest:
Маршрутизация теперь реализована как middleware. Мы всё ещё используем FastRoute для маршрутизации приложения.
Если вы использовали настройку defineRouteBeforeAppMiddleware, вам нужно добавить middleware Middleware\RoutingMiddleware в ваше приложение непосредственно перед вызовомrun () для обеспечения предыдущего поведения.
Подробнее см. в Pull Request #2288.
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware
$app->addRoutingMiddleware();
// ...
$app->run();Обработка ошибок так же реализована в качестве middleware. Подробнее см. в Pull Request #2398.
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
/**
* Middleware маршрутизации должно быть добавлено до ErrorMiddleware
* Иначе, исключения, брошенные из маршрутизатора не будут обработаны
*/
$app->addRoutingMiddleware();
/**
* Add Error Handling Middleware
*
* @param bool $displayErrorDetails -> В продакшене должно быть установлено значение false
* @param bool $logErrors -> Параметер передается в дефолтный ErrorHandler
* @param bool $logErrorDetails -> Показывать подробности ошибок в логе ошибок,
* который может быть заменен по вашему выбору.
* Примечание: это middleware должно быть добавлено последним. Все ошибки и исключения из добавленных позже middlware не будут обработаны.
*/
$app->addErrorMiddleware(true, true, true);
// ...
$app->run();Обработчик ошибки 404 Not Found и Обработчик ошибки 405 Not Allowed из версии 3 могут быть перенесены как показано ниже:
<?php
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Slim\Exception\HttpNotFoundException;
use Slim\Psr7\Response;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
// Установка обработчика ошибки Not Found
$errorMiddleware->setErrorHandler(
HttpNotFoundException::class,
function (ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails) {
$response = new Response();
$response->getBody()->write('404 NOT FOUND');
return $response->withStatus(404);
});
// Установка обработчика ошибки Not Allowed
$errorMiddleware->setErrorHandler(
HttpMethodNotAllowedException::class,
function (ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails) {
$response = new Response();
$response->getBody()->write('405 NOT ALLOWED');
return $response->withStatus(405);
});Мы создали обертку над FastRoute, которая добавляет обертку результатов и доступ к полному списку разрешенных методов маршрута вместо того, чтобы иметь доступ к ним только в случае возникновения исключения.
Атрибут запроса routeInfo помечен как устаревший и заменен на routingResults.
См подробнее в Pull Request #2405.
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Routing\RouteContext;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/hello/{name}', function (Request $request, Response $response) {
$routeContext = RouteContext::fromRequest($request);
$routingResults = $routeContext->getRoutingResults();
// Получаем все аргументы маршрута, например ['name' => 'John']
$routeArguments = $routingResults->getRouteArguments();
// В отличие Slim 3, разрешенные методы маршрута теперь доступны всегда, не только в случаях ошибки.
$allowedMethods = $routingResults->getAllowedMethods();
return $response;
});
// ...
$app->run();Если вы переопределяли HTTP-метод, используя собственный заголовок или параметр тела запроса, вам нужно добавить middleware Middleware\MethodOverrideMiddleware, чтобы иметь эту возможность, как и раньше.
Подробности в Pull Request #2329.
<?php
use Slim\Factory\AppFactory;
use Slim\Middleware\MethodOverridingMiddleware;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$methodOverridingMiddleware = new MethodOverrideMiddleware();
$app->add($methodOverridingMiddleware);
// ...
$app->run();Этот middleware автоматически добавляет к ответу заголовок Content-Length. Он используется взамен удаленной из 3 версии настройки addContentLengthHeader. Этот middleware должен располагаться в стеке middleware, чтобы он выполнялся после всех изменений тела ответа.
<?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();Middleware буферизации вывода позволяет переключаться между двумя режимами буферизации вывода: APPEND (по умолчанию) и PREPEND. Режим APPEND будет использовать существующее тело ответа для добавления содержимого, а режим PREPEND создаст новое тело ответа и добавит его к существующему ответу. Этот middleware должен располагаться в стеке middleware, чтобы он выполнялся после всех изменений тела ответа.
<?php
use Slim\Factory\AppFactory;
use Slim\Middleware\OutputBufferingMiddleware;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
/**
* Доступно 2 режима
* OutputBufferingMiddleware::APPEND (по умолчанию) - Добавляет к текущему телу ответа
* OutputBufferingMiddleware::PREPEND - Создает новое тело ответа
*/
$mode = OutputBufferingMiddleware::APPEND;
$outputBufferingMiddleware = new OutputBufferingMiddleware($mode);
// ...
$app->run();