先週SymfonyWorld 2021 Summer Editionのトークで @TobiasNyholm
さんが紹介していたRuntimeコンポーネントを早速使ってみたのでご紹介します!
Runtimeコンポーネントとは
Symfony5.3から導入された新しいコンポーネントです。
実行環境(php-fpm, AWS Lambda, PaaS, swoole, …)ごとのフロントコントローラの違いをクラスとして提供してくれます。
https://symfony.com/doc/current/components/runtime.html
Runtimeコンポーネントで何が嬉しいか?
Runtimeコンポーネント導入前まで、 symfony new
して作ったSymfonyプロジェクトは、スタンダードなApache・nginxで動かすことを前提にした public/index.php
だけが配布されていました。
それ以外の特殊な実行環境(たとえば「SymfonyをAWS Lambdaで」とか)でSymfonyを動かそうと思ったら、 $_SERVER
を自前でセットする等のやり方をググって、自力で public/index.php
や bin/console
をカスタマイズする必要がありました。
Runtimeコンポーネントは各実行環境ごとのカスタマイズ内容を、再利用可能な形でSymfonyコンポーネントとして提供してくれるため、自力でカスタマイズを適用する必要はなくなりました
既存のSymfonyプロジェクトにRuntimeコンポーネントを導入する方法
前提として、Symfony5.3まで更新してあるプロジェクトが対象です。
symfony/runtime導入
composer require symfony/runtime
vendor/autoload_runtime.php作成, public/index.phpの更新
composer recipes:install symfony/framework-bundle -v --force
config/framework.yamlに自分の設定を書き込んでいる場合は、設定が初期状態まで巻き戻ってしまうため、git diffを見て自分の設定した部分は復元しましょう。
bin/consoleの更新
composer recipes:install symfony/console -v --force
必要な変更をコミット後、 symfony server:start
してみると、今まで通りにアプリケーションが動くことを確認できると思います(私はできました)。
vendor/autoload_runtime.php
を見てみると、デフォルトのRuntimeとして Symfony\Component\Runtime\SymfonyRuntime
が指定されていること、Runtimeを変更したい場合は $_SERVER['APP_RUNTIME']
を変更すれば良いことがわかります。
<?php
// autoload_runtime.php @generated by Symfony Runtime
if (true === (require_once __DIR__.'/autoload.php') || empty($_SERVER['SCRIPT_FILENAME'])) {
return;
}
if (PHP_VERSION_ID < 80000 && in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
ob_start();
$app = require $_SERVER['SCRIPT_FILENAME'];
ob_end_clean();
} else {
$app = require $_SERVER['SCRIPT_FILENAME'];
}
if (!is_object($app)) {
throw new TypeError(sprintf('Invalid return value: callable object expected, "%s" returned from "%s".', get_debug_type($app), $_SERVER['SCRIPT_FILENAME']));
}
$runtime = $_SERVER['APP_RUNTIME'] ?? 'Symfony\\Component\\Runtime\\SymfonyRuntime';
$runtime = new $runtime(($_SERVER['APP_RUNTIME_OPTIONS'] ?? []) + [
'project_dir' => dirname(__DIR__, 1),
]);
[$app, $args] = $runtime
->getResolver($app)
->resolve();
$app = $app(...$args);
exit(
$runtime
->getRunner($app)
->run()
);
感想
ますますコアなアプリケーション部分の開発に集中できる方向に進化してくれるSymfonyがやっぱり大好きだな〜と思いました。