如果您要从版本 3 升级到版本 4,这些是您需要注意的重大变化。
Slim 4 需要PHP 7.4 或更新版本。
Slim 的 App settings 曾经是容器的一部分,现在已经和它解耦了。
/**
* Slim 3 App::__construct($container = [])
* As seen here the settings used to be nested
*/
$app = new App([
'settings' => [...],
]);
/**
* Slim 4 App::__constructor() method takes 1 mandatory parameter and 4 optional parameters
*
* @param ResponseFactoryInterface Any implementation of a ResponseFactory
* @param ContainerInterface|null Any implementation of a Container
* @param CallableResolverInterface|null Any implementation of a CallableResolver
* @param RouteCollectorInterface|null Any implementation of a RouteCollector
* @param RouteResolverInterface|null Any implementation of a RouteResolver
*/
$app = new App(...);
addContentLengthHeader
有关此设置的新实现,请参阅内容长度中间件。determineRouteBeforeAppMiddleware
将路由中间件放置在中间件堆栈中的正确位置以复制现有行为。outputBuffering
有关此设置的新实现,请参阅输出缓冲中间件。displayErrorDetails
有关此设置的新实现,请参阅错误处理中间件。Slim 不再有容器,因此您需要提供自己的容器。如果您依赖容器中的请求或响应,那么您需要自己将它们设置到容器中,或者进行重构。此外,App::__call()
方法已被删除,因此通过$app->key_name()
不再有效访问容器属性。
/**
* Slim 3.x shipped with the Pimple container implementation and enabled the following syntax
*/
$container = $app->getContainer();
//Assign dependencies as array
$container['view'] = function (\Psr\Container\ContainerInterface $container){
return new \Slim\Views\Twig('');
};
/**
* Slim 4.x does not ship with a container library. It supports all PSR-11 implementations such as PHP-DI
* To install PHP-DI `composer require php-di/php-di`
*/
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('');
});
在 v3 之前,Slim 从实例化应用程序的文件夹中提取基本路径。现在不再是这种情况,并且必须显式声明基本路径,以防您的应用程序不是从域的根目录执行的:
use Slim\Factory\AppFactory;
// ...
$app = AppFactory::create();
$app->setBasePath('/my-app-subpath');
// ...
$app->run();
Slim 3 中的组件Router
已拆分为多个不同的组件,以便将 FastRoute 与核心分离App
,并为最终用户提供更大的灵活性。它已被拆分为
RouteCollector
,RouteParser
和RouteResolver
。这 3 个组件都可以有各自的接口,您可以自己实现这些接口并将其注入到App
构造函数中。以下拉取请求提供了很多关于这些新组件的公共接口的见解:
这也意味着Route Groups改变了他们的签名:
$app->group('/user', function(\Slim\Routing\RouteCollectorProxy $app){
$app->get('', function() { /* ... */ });
//...
});
在 Slim 4 中,我们希望通过解耦 Slim 的一些 App 核心功能并将其作为中间件实现,从而为开发人员提供更大的灵活性。这使您能够交换核心组件的自定义实现。
中间件执行没有改变,仍然Last In First Out (LIFO)
和 Slim 3 一样。
引入该AppFactory
组件是为了减少因将 PSR-7 实现与核心解耦而引起的一些摩擦App
。它检测在您的项目根目录中安装了哪个 PSR-7 实现和 ServerRequest 创建者,并使您能够通过实例化应用程序AppFactory::create()
并使用App::run()
而无需传入ServerRequest
对象。支持以下 PSR-7 实现和 ServerRequest 创建者组合:
路由已作为中间件实现。我们仍在使用FastRoute来满足我们的路由需求。如果您使用的是determineRouteBeforeAppMiddleware
,则需要Middleware\RoutingMiddleware
在调用之前将中间件添加到您的应用程序run()
以保持先前的行为。有关更多信息,请参阅拉取请求 #2288 。
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware
$app->addRoutingMiddleware();
// ...
$app->run();
错误处理也被实现为中间件。有关更多信息,请参阅拉取请求 #2398 。
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
/**
* The routing middleware should be added before the ErrorMiddleware
* Otherwise exceptions thrown from it will not be handled
*/
$app->addRoutingMiddleware();
/**
* Add Error Handling 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
* which can be replaced by a callable of your choice.
* Note: This middleware should be added last. It will not handle any exceptions/errors
* for middleware added after it.
*/
$app->addErrorMiddleware(true, true, true);
// ...
$app->run();
v3 中的404 Not Found 处理程序和405 Not Allowed 处理程序可以按如下方式迁移:
<?php
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Slim\Exception\HttpNotFoundException;
use Slim\Exception\HttpMethodNotAllowedException;
use Slim\Psr7\Response;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
// Set the Not Found Handler
$errorMiddleware->setErrorHandler(
HttpNotFoundException::class,
function (ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails) {
$response = new Response();
$response->getBody()->write('404 NOT FOUND');
return $response->withStatus(404);
});
// Set the Not Allowed Handler
$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 调度程序创建了一个包装器,它添加了一个结果包装器并可以访问路由的完整允许方法列表,而不是仅在出现异常时才可以访问这些方法。Request 属性routeInfo
现已弃用并替换为routingResults
. 有关更多信息,请参阅拉取请求 #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();
// Get all of the route's parsed arguments e.g. ['name' => 'John']
$routeArguments = $routingResults->getRouteArguments();
// A route's allowed methods are available at all times now and not only when an error arises like in Slim 3
$allowedMethods = $routingResults->getAllowedMethods();
return $response;
});
// ...
$app->run();
如果您使用自定义标头或正文参数覆盖 HTTP 方法,则需要添加中间件Middleware\MethodOverrideMiddleware
才能像以前一样覆盖该方法。有关更多信息,请参阅拉取请求 #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();
内容长度中间件会自动将Content-Length
标头附加到响应中。这是为了替换addContentLengthHeader
从 Slim 3 中删除的设置。这个中间件应该放在中间件堆栈的中心,以便最后执行。
<?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();
输出缓冲中间件使您能够在两种输出缓冲模式之间切换:(APPEND
默认)和PREPEND
模式。该APPEND
模式将使用现有的响应主体来附加内容,而PREPEND
模式将创建一个新的响应主体并将其附加到现有的响应中。这个中间件应该放在中间件堆栈的中心,这样它才能最后执行。
<?php
use Slim\Factory\AppFactory;
use Slim\Middleware\OutputBufferingMiddleware;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
/**
* 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($mode);
// ...
$app->run();