2026年8月16日
2026年8月16日
Symfonyフレームワークの基本設定とディレクトリ構成|インストールから.env・ルーティング・本番設定まで
Symfonyでアプリを始めるときに押さえるべきなのは、「どのディレクトリに何を置くか」「設定は config/ と .env のどちらに書くか」「本番では何を切り替えるか」の3点です。この記事では、新規プロジェクトの作成から、ディレクトリ構成の読み方、環境変数と秘密情報の扱い、最初のコントローラーとルーティング、本番へ出すときの設定までを順に説明します。読み終えるころには、生成されたプロジェクトのどこを触ればよいかが分かり、手元でページを1枚表示できる状態になります。
なお、このブログはWordPressが中心ですが、SymfonyはWordPressとは別のPHPフレームワークです。最後にWordPressとの関わり方も触れます。
始める前に確認すること
Symfonyはバージョンごとに必要なPHPのバージョンが決まっています。Symfony 7系はPHP 8.2以上、Symfony 8系はさらに新しいPHPを要求します(2026年10月現在)。正確な要件は公式ドキュメントの各バージョンのページで確認してください。長く運用する業務アプリなら、サポート期間の長いLTS版を選ぶのが無難です。どれがLTSかは公式のリリース情報に載っています。
準備するものは次の3つです。
- 要件を満たすPHP(CLI版)と、
ctype・iconv・intlなどの拡張 - Composer 2系
- Symfony CLI(任意ですが、プロジェクト作成とローカルサーバー起動が楽になります)
Symfony CLIを入れたら、まず要件チェックを実行します。足りない拡張やphp.iniの設定があれば一覧で表示されるので、エラーが出る前に気づけます。
symfony check:requirements
プロジェクトを作成する
作り方は「Webアプリ一式を入れる」か「最小構成から必要なものだけ足す」かの2通りです。初めてならWebアプリ一式のほうが、テンプレート(Twig)やフォーム、DB(Doctrine)がそろっていて学びやすくなります。
# Symfony CLI を使う場合(Webアプリ一式)
symfony new my_project --webapp
# Composer だけで作る場合(最小構成 → 後から webapp を追加)
composer create-project symfony/skeleton my_project
cd my_project
composer require webapp
バージョンを固定したいときは、symfony new my_project --version="7.4.*" --webapp や composer create-project symfony/skeleton:"7.4.*" my_project のように指定します。数字は例なので、採用するバージョンに読み替えてください。
composer require でパッケージを入れると、Symfony Flexという仕組みが「レシピ」を適用し、設定ファイルの雛形を config/ に自動で追加します。手で設定ファイルを書き始める前に、まずレシピが何を作ったかを git diff で確認する習慣をつけると、どこに何が書かれているかを把握しやすくなります。
ディレクトリ構成の読み方
生成直後のプロジェクトは、おおむね次の構成です。
my_project/
├── bin/console # コマンドラインツール
├── config/ # 設定(YAML/PHP)
│ ├── packages/ # バンドルごとの設定
│ ├── routes/ # ルーティングの読み込み設定
│ ├── bundles.php # 有効なバンドルの一覧
│ └── services.yaml # サービス(DI コンテナ)の設定
├── public/index.php # Web からの唯一の入口
├── src/ # 自分で書く PHP コード(Controller など)
├── templates/ # Twig テンプレート
├── var/ # キャッシュ・ログ(自動生成)
├── vendor/ # Composer が入れたライブラリ
└── .env # 環境変数の既定値
特に間違えやすいのは次の2点です。
**Webサーバーのドキュメントルートは public/ にします。** プロジェクト直下を公開すると、.env や config/、var/log/ までWebから読める状態になりかねません。共用サーバーでドキュメントルートを変えられない場合は、Symfonyを置く前にサーバーの設定方法を確認してください。
**var/ は消してよい生成物です。** キャッシュが原因で設定変更が反映されないときは、php bin/console cache:clear で作り直せます。逆に、var/ に自分のファイルを置いてはいけません。
src/ の中は、Controller/、Entity/、Repository/ などに分かれ、App\ 名前空間で自動読み込み(PSR-4)されます。
設定は「config」と「.env」で役割を分ける
Symfonyの設定は2層になっています。
config/… アプリの振る舞い(どのバンドルをどう使うか、ルーティング、サービスの組み立て)。環境が違っても共通の内容を書き、Gitで管理します。.env系 … 環境ごとに変わる値(APP_ENV、DB接続先のDATABASE_URLなど)。
.env 系のファイルは読み込み順が決まっています。
| ファイル | 用途 | Gitに入れるか |
|---|---|---|
.env |
既定値(秘密を含まない) | 入れる |
.env.local |
その環境だけの上書き・秘密 | 入れない |
.env.test / .env.prod など |
環境ごとの既定値 | 入れる |
一般的な「.env はGitに入れない」という作法と逆に見えますが、Symfonyの .env は「秘密を含まない既定値の見本」という位置づけです。パスワードやAPIキーは .env に書かず、.env.local(.gitignore 済み)か、次に説明するシークレット機能に入れます。ここを取り違えて本番のパスワードを .env に書いてコミットしてしまう事故が多いので注意してください。
config/ の中から環境変数を参照するときは %env(DATABASE_URL)% のように書きます。
秘密情報はシークレット機能に入れる
本番のAPIキーなどは、Symfonyのシークレット機能で暗号化して保存できます。
php bin/console secrets:set PAYMENT_API_KEY --env=prod
暗号化された値は config/secrets/prod/ に保存され、Gitに入れても中身は読めません。ただし、復号用の秘密鍵(ファイル名に decrypt を含むもの)はGitに入れず、本番サーバーにだけ置きます。鍵を紛失すると値を取り出せなくなるので、安全な場所に控えを保管してください。
最初のページを表示する:コントローラーとルーティング
MakerBundle(webapp に含まれます)を使うと、コントローラーとテンプレートの雛形を作れます。
php bin/console make:controller HelloController
中身を次のように整えると、/hello でページが表示されます。
<?php
// src/Controller/HelloController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HelloController extends AbstractController
{
#[Route('/hello/{name}', name: 'app_hello', defaults: ['name' => 'world'])]
public function index(string $name): Response
{
return $this->render('hello/index.html.twig', [
'name' => $name,
]);
}
}
{# templates/hello/index.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Hello {{ name }}</h1>
{% endblock %}
ルートはPHPのアトリビュート #[Route] で定義します。古い記事では Annotation\Route を use していることがありますが、新しいバージョンでは Attribute\Route を使います。Twigの {{ }} は既定で自動エスケープされるため、URLから受け取った name をそのまま出してもHTMLとして解釈されません。|raw フィルターを付けるとエスケープが外れるので、利用者の入力には使わないでください。
ローカルでは次のコマンドで確認します。
symfony server:start # Symfony CLI のローカルサーバー
php bin/console debug:router # 登録されたルートの一覧
「ルートが見つからない(404)」ときは、debug:router に目的のパスが出ているかを最初に見ます。出ていなければ、名前空間の綴りかファイルの置き場所が src/Controller/ からずれていることが多いです。
サービスと自動配線(autowiring)
config/services.yaml では、既定で src/ 以下のクラスがサービスとして登録され、コンストラクタの型宣言を見て依存先が自動で注入されます(autowiring)。そのため、自作クラスをコントローラーの引数やコンストラクタに型付きで書くだけで使えます。
public function __construct(private readonly MailerInterface $mailer) {}
うまく注入されないときは php bin/console debug:container や debug:autowiring で、その型が登録されているかを確認できます。
本番へ出すときの設定
開発と本番で最も大きく変わるのは APP_ENV です。本番では prod にし、デバッグ表示(APP_DEBUG)を無効にします。開発用のエラー画面やプロファイラーが本番で見えると、内部の構成や設定値が外部に漏れます。
デプロイ時の基本的な流れは次のとおりです。手順はホスティング先に合わせて調整し、初回はステージング環境で試してください。
composer install --no-dev --optimize-autoloader
composer dump-env prod # .env 系を .env.local.php にまとめて読み込みを軽くする
APP_ENV=prod php bin/console cache:clear
composer dump-env prod を使う場合、生成された .env.local.php にも本番の値が入るので、Gitに入れないこと、Webから見えない場所(public/ の外)にあることを確認します。DBのマイグレーションを伴うリリースでは、実行前にデータベースのバックアップを取ってください。
WordPressとの関係
WordPress本体はSymfonyを使っていません。一方で、Symfonyの部品(コンポーネント)は単体のComposerパッケージとして配布されているため、WordPressプラグインの中で一部だけ使うことはできます。その場合、別のプラグインが同じライブラリの違うバージョンを読み込んで衝突することがあるため、配布するプラグインでは名前空間を書き換えて同梱する(PHP-ScoperやStraussなどのツールを使う)方法が取られます。WordPressとSymfonyアプリを同じドメインで併用するなら、サブドメインや別ディレクトリに分け、それぞれのドキュメントルートを独立させるのが管理しやすい形です。
まとめ
- 新規作成は
symfony new --webappかcomposer create-project symfony/skeletonで行い、最初にsymfony check:requirementsで要件を確認する - ドキュメントルートは
public/。var/はキャッシュとログの置き場で、消して作り直せる config/はアプリ共通の設定、.envは秘密を含まない既定値。秘密は.env.localかシークレット機能へ- ルートは
#[Route]アトリビュートで定義し、debug:routerで登録を確認する - 本番は
APP_ENV=prod、composer install --no-dev --optimize-autoloader、キャッシュの作り直しをセットで行う - バージョンごとの要件やサポート期間は変わるため、採用前に公式ドキュメントで確認する