アップグレードガイド

バージョン3からバージョン4にアップグレードする場合は、認識しておく必要がある重要な変更点がいくつかあります。

PHP バージョン要件

Slim 4 は **PHP 7.4 以降** を必要とします。

Slim\App コンストラクタの破壊的変更

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(...);

削除された App 設定

コンテナの変更

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 コアから分離し、エンドユーザーにより多くの柔軟性を提供するために、複数の異なるコンポーネントに分割されました。 RouteCollectorRouteParserRouteResolver に分割されました。これら3つのコンポーネントはそれぞれ独自のインターフェースを持つことができ、それらを独自に実装して App コンストラクタに注入できます。次のプルリクエストは、これらの新しいコンポーネントのパブリックインターフェースに関する多くの洞察を提供しています。

これはまた、ルートグループ のシグネチャが変更されたことを意味します。

$app->group('/user', function(\Slim\Routing\RouteCollectorProxy $app){
    $app->get('', function() { /* ... */ });
    //...
});

新しいミドルウェアアプローチ

Slim 4 では、Slim の App コアの機能の一部を分離し、ミドルウェアとして実装することにより、開発者に柔軟性を提供することを目指しました。これにより、コアコンポーネントのカスタム実装を交換できます。

ミドルウェアの実行

ミドルウェアの実行は変更されておらず、Slim 3 と同様に Last In First Out (LIFO) です。

新しい App ファクトリ

AppFactory コンポーネントは、PSR-7 実装を App コアから分離することによって発生する摩擦を軽減するために導入されました。プロジェクトルートにインストールされている PSR-7 実装と ServerRequest クリエイターを検出し、AppFactory::create() を介してアプリをインスタンス化し、ServerRequest オブジェクトを渡すことなく App::run() を使用できるようにします。次の 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();

新しい 404 Not Found および 405 Not Allowed ハンドラー

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 ディスパッチャをラップするラッパーを作成しました。これにより、結果ラッパーと、例外が発生した場合にのみアクセスできるのではなく、ルートの許可されたメソッドの完全なリストへのアクセスが追加されます。リクエスト属性 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();

新しい出力バッファリングミドルウェア

出力バッファリングミドルウェアを使用すると、出力バッファリングの2つのモードを切り替えることができます。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();