如果你從 3 版升級到 4 版,以下是你需要注意的重要變更。
Slim 4 需要 PHP 7.4 或更新版本。
Slim 的 App 設定過去是容器的一部分,而現在已從中解耦。
/**
* 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 已不再有 Container,所以你需要提供自己的 Container。如果你依賴 Container 內的 request 或 response,那麼你需要手動將它們設置到容器中,或是進行重構。另外,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
。這三個組件都可以有各自的介面,你可以自行實作並注入 App
建構函式。下列 Pull Request 提供了這些新組件的公用介面的許多見解
這也表示路由群組已變更其簽章
$app->group('/user', function(\Slim\Routing\RouteCollectorProxy $app){
$app->get('', function() { /* ... */ });
//...
});
在 Slim 4 中,我們希望透過讓 Slim 的部分應用程式核心功能脫鉤並實作為中間件,來提供開發人員更大的彈性。這樣一來,你就可以替換核心組件的自訂實作。
中間件執行並未改變,仍然是「後進先出 (LIFO)」原則,就跟 Slim 3 一樣。
引入 AppFactory
組件,是為了減少因為將 PSR-7 實作與 App
核心脫鉤而造成的摩擦。它會偵測專案根目錄中安裝哪一個 PSR-7 實作和 ServerRequest 建立器,並讓你透過 AppFactory::create()
來實例化應用程式,並使用 App::run()
,而不需要傳入 ServerRequest
物件。下列 PSR-7 實作和 ServerRequest 建立器組合獲得支援
路由已實作為中介軟體。我們仍使用 FastRoute 來因應我們的路由需求。如果您使用 determineRouteBeforeAppMiddleware
,您需要在呼叫 run()
之前將 Middleware\RoutingMiddleware
中介軟體新增到您的應用程式中,以維持之前的行為。請參閱 Pull Request #2288 以取得更多資訊。
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware
$app->addRoutingMiddleware();
// ...
$app->run();
錯誤處理也已實作為中介軟體。請參閱 Pull Request #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 未找到處理常式 和 405 不允許處理常式 可改用下列方式進行移轉
<?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
取代。請參閱 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();
// 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
中介軟體,以能夠像以往一樣覆寫方法。請參閱 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();
內容長度中介軟體會自動將 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();