如果您要从版本 3 升级到版本 4,以下是您需要了解的重大变化。
Slim 4 要求PHP 7.4 或更高版本。
Slim 的应用程序设置曾经是容器的一部分,现在已从中分离出来。
/**
* 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
构造函数中各自的接口。以下请求拉取提供了对这些新组件的公共接口的很多见解
这也意味着 路由组 已更改其签名
$app->group('/user', function(\Slim\Routing\RouteCollectorProxy $app){
$app->get('', function() { /* ... */ });
//...
});
在 Slim 4 中,我们希望通过分离 Slim 的一些 App 核心功能并将其实现为中间件,从而为开发者提供更大的灵活性。这使您可以替换核心组件的自定义实现。
中间件执行未更改,并且与 Slim 3 中仍为 后进先出 (LIFO)
。
引入 AppFactory
组件是为了减少由将 PSR-7 实现与 App
核心分离而引起的一些摩擦。它检测哪个 PSR-7 实现和 ServerRequest 创建者安装在您的项目根目录中,使您可以通过 AppFactory::create()
实例化一个应用程序,并且使用 App::run()
而无需传入 ServerRequest
对象。支持以下 PSR-7 实现和 ServerRequest 创建者组合
路由已作为中间件实现。我们仍在使用FastRoute满足我们的路由需求。如果您正在使用determineRouteBeforeAppMiddleware
,则需要在调用run()
之前将Middleware\RoutingMiddleware
中间件添加到应用程序中,以维护之前的行为。有关详细信息,请参见请求提取#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();
可以如下迁移版本3中的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 调度程序周围创建了一个包装器,该包装器添加了一个结果包装器,并允许访问路由允许的所有方法的完整列表,而不仅仅是在出现异常时才能访问这些方法。请求属性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
标头。这是为了替换从 Slim 3 中弃用的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();
输出缓冲中间件使您可以在两种输出缓冲模式之间切换: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();