🎻

「Symfonyをインストール」するとき、具体的に何が行われているのか

2023/12/01に公開

Symfony Advent Calendar 2023 の1日目の記事です!🎄✨

Twitter (X) でもちょいちょいSymfonyネタを呟いてます!よろしければ フォロー お願いします!

はじめに

Symfonyアプリケーションの開発を始めるときに必ず行う「Symfonyをインストールする」という作業。

今日はこの「Symfonyをインストールする」という作業が具体的に何をすることなのか、裏で何が行われているのか、を改めておさらいしてみたいと思います。

公式ドキュメント では、Symfonyのインストール方法として、

# 伝統的なWebアプリケーションを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}" --webapp

# マイクロサービス、コンソールアプリケーション、APIなどを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}"

または

# 伝統的なWebアプリケーションを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}
$ cd {ディレクトリ名}
$ composer require webapp

# マイクロサービス、コンソールアプリケーション、APIなどを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}

という 2 x 2 パターンの方法が紹介されています。

これらについて詳しくみていきましょう。

composer create-project コマンドでSymfonyをインストールすることの意味

順番が前後しますが、まずは後者の composer create-project コマンドを使う方法について説明します。

composer create-project コマンド は、公開されているパッケージの composer.json をもとに新しくプロジェクトを作成するためのコマンドです。

「パッケージの composer.json をもとに新しくプロジェクトを作成する」とは、以下の操作を行うこととほぼ同じ意味です。

  1. 新しくディレクトリを作成する
  2. 作成したディレクトリの直下に composer.json を作成し、パッケージの composer.json の内容をコピペする
  3. 作成したディレクトリの直下で composer install を実行する

「ほぼ同じ」と書いたとおり、厳密には、パッケージによっては上記の操作以上のことが行われることがあります。

例えば、パッケージの composer.jsonscripts フィールドに post-create-project イベント に対する処理が書かれている場合、その処理は composer install 時には実行されず、composer create-project 時にのみ実行されます。

例として、koriym/php-skeleton の実装( composer.jsonsrc/Installer.php)などを読んでみると理解に助かると思います。

また、Symfony Flexrequire しているパッケージにおいて、composer.jsonflex-require フィールドに依存パッケージが書かれている場合、それらの依存パッケージは composer create-project 時にのみインストールされるようです

Symfony Flexについての詳細は以下の過去記事をご参照ください。

https://zenn.dev/ttskch/articles/13013224b61531

これらを踏まえて、公式ドキュメントで紹介されているコマンド

$ composer create-project symfony/skeleton:"7.0.*" my_project_directory

を実行すると何が起こるかを整理してみましょう。

まず、symfony/skeleton パッケージの、7.0.* というバージョン指定に適合する最新のバージョン(本稿執筆時点では 7.0.99 が採択され、その composer.json をもとにプロジェクトが作成されます。

その際、Symfony Flexの働きによって、composer.jsonflex-require フィールドの中身require に展開され、それらのパッケージもインストールされます。

各種パッケージがインストールされる際に、Symfony Flexの働きによって、symfony/framework-bundle を始めとする Symfony Recipesリポジトリ にレシピを持つパッケージのレシピがインストールされます。

これにより、いわゆるSymfonyの標準的なディレクトリ構造やデフォルトの設定ファイル群を備えたプロジェクトが作成され、「Symfonyがインストールされた」状態になるというわけです💡

symfony new コマンドでSymfonyをインストールすることの意味

次に、symfony new コマンドを使う方法について説明します。

symfony new コマンドは、Symfony CLI で利用できるサブコマンドです。

Symfony CLIは、

  • Symfonyをインストールする機能(つまり symfony new コマンド)
  • TSL証明書のサポートもある、強力なローカルWebサーバー機能
  • セキュリティの脆弱性をチェックする機能
  • Platform.sh とのシームレスな統合

などの機能を持つ、Symfonyアプリケーションの開発環境になくてはならないツールです。

公式ドキュメントで紹介されている symfony new によるSymfonyのインストールコマンドは

$ symfony new my_project_directory --version="7.0.*"

です。これを実行すると何が起こるかというと、実は

$ composer create-project symfony/skeleton:"7.0.*" my_project_directory

を実行するのとまったく同じです。

symfony new コマンドの実装を覗いてみると分かりますが、内部的には composer create-project symfony/skeleton を実行しているだけ なのです。

なので、composer create-project symfony/skeleton コマンドを使う方法も、symfony new コマンドを使う方法も、得られる結果は完全に同一です。どっちを使っても構いません👌

composer require webapp--webapp の意味

最後に、2 x 2 パターンの残りの半分、

# 伝統的なWebアプリケーションを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}" --webapp
# 伝統的なWebアプリケーションを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}
$ cd {ディレクトリ名}
$ composer require webapp

これらについて説明します。

まずは symfony new コマンドの実装を再度覗いてみましょう。--webapp オプションを付けた場合には追加で composer require webapp を実行するようになっている ことが分かります。

つまり、やはりここでも symfony new コマンドのパターンと composer create-project コマンドのパターンで、実は起こることは同じというわけです。

では、composer require webapp を実行すると何が起こるのでしょうか。

そもそも、webapp というパッケージ名指定が少し不思議ですよね。packagist.org に公開されているパッケージはどれも ベンダー名/パッケージ名 という形式の名前になっていて、webapp などという名前のパッケージは見つけられません

それもそのはず、これはSymfony Flexの働きを前提としたパッケージ名指定なのです。Symfony Recipeseリポジトリに登録されている symfony/webapp-pack のレシピ を見てみると、

{
    "aliases": ["webapp"],
}

という記述が見られます。つまり、Symfony FlexがインストールされたComposer環境においては、webapp というエイリアスを使って symfony/webapp-pack パッケージ をインストールできるというわけです💡

symfony/webapp-pack パッケージの composer.json の内容 は以下のとおりです。

{
    "name": "symfony/webapp-pack",
    "type": "symfony-pack",
    "license": "MIT",
    "description": "A webapp pack on top of the default skeleton",
    "require": {
        "symfony/asset": "*",
        "symfony/debug-pack": "*",
        "symfony/doctrine-messenger": "*",
        "symfony/expression-language": "*",
        "symfony/form": "*",
        "symfony/http-client": "*",
        "symfony/intl": "*",
        "symfony/mailer": "*",
        "symfony/maker-bundle": "^1.0",
        "symfony/mime": "*",
        "symfony/monolog-bundle": "^3.1",
        "symfony/notifier": "*",
        "symfony/orm-pack": "*",
        "symfony/process": "*",
        "symfony/profiler-pack": "*",
        "symfony/security-bundle": "*",
        "symfony/serializer-pack": "*",
        "symfony/string": "*",
        "symfony/test-pack": "*",
        "symfony/translation": "*",
        "symfony/twig-pack": "*",
        "symfony/validator": "*",
        "symfony/web-link": "*"
    },
    "require-dev": {
        "symfony/debug-pack": "*",
        "symfony/profiler-pack": "*",
        "symfony/maker-bundle": "^1.0",
        "symfony/test-pack": "*"
    },
    "conflict": {
        "symfony/framework-bundle": "<5.0"
    }
}

要するに、各種Symfonyコンポーネントやバンドルをまとめてインストールするためのメタパッケージになっているわけです。

公式ドキュメントで # 伝統的なWebアプリケーションを作る場合 と注釈されていたのは、「伝統的なWebアプリケーションを作る場合なら、まあこれらのパッケージはほぼ使うでしょうから、一通りまとめて入れておくといいですよ」という意味だったわけですね。

とはいえここに列挙されているパッケージはすべてが常に必要なものとも言えないと思うので、webapp ありでインストールした場合も、不要なものは手動で composer remove する(か、そもそも webapp なしでインストールしておいて必要なものを追加していくようにする)ことを個人的にはおすすめします。

おわりに

というわけで、「Symfonyをインストール」するとき、具体的に何が行われているのかを改めておさらいしてみました。

Symfonyに対する理解が少し深まりましたね!

Symfony Advent Calendar 2023、明日がさっそく空きになってしまっているので、ぜひどなたかご参加ください!!!ライトな記事でも全然いいと思います!!!

GitHubで編集を提案

Discussion