Symfony

PHP5に慣れ親しんだエンジニアが掲示板をSymfony4で作成してみる

この記事は約13分で読めます。
スポンサーリンク

Symfony4はPHP5時代と比べるとモダンな機能やベストプラクティスが多数導入されています。ここでは、ユーザ認証(ログイン・登録)、管理者権限、アクセス制限、データベースの活用といった要素を取り入れた掲示板(BBS)を段階的に実装してSymony4を習得していきます。

スポンサーリンク

1.必要な環境の準備

Linuxサーバの前提
  • OS
    Ubuntu、CentOS、Debianなど
  • PHP
    Symfony4はPHP 7.1以上が必要です
    php -v コマンドでバージョンを確認してください
  • Composer
    PHPパッケージ管理ツール
  • Webサーバ
    ApacheまたはNginx(ここではApacheの例を示します
ドメイン設定
  • DNSで「www.example.com」が対象サーバのIPを指していることを確認してください

2.Apacheによるドメイン設定

ApacheでのVirtualHost設定例(/etc/apache2/sites-available/example.com.conf)

<VirtualHost *:80>
    ServerName www.example.com
    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

設定後、以下のコマンドで有効化と再起動を行います

sudo a2ensite example.com
sudo a2enmod rewrite
sudo systemctl reload apache2

3.Symfony4プロジェクトの作成と配置

1.プロジェクトディレクトリの作成

Webサーバのドキュメントルート(例:/var/www/example.com)に移動し、ディレクトリを作成

sudo mkdir -p /var/www/example.com
cd /var/www/example.com
sudo chown $(whoami):$(whoami) .

2.Symfony4プロジェクトのインストール

Composerを使ってSymfony4プロジェクトを作成します。今回はDoctrineやセキュリティ機能が含まれるスターターキットを利用

composer create-project symfony/website-skeleton board_project

※ プロジェクトディレクトリ(例:board_project)内にpublicフォルダが作成されます。
※ ApacheのDocumentRootは、このpublicフォルダを指定してください(もしくはVirtualHost設定でパスを調整)。

4.データベース設定とエンティティ作成

掲示板の情報(ユーザ情報、投稿内容など)をデータベースに保存します。ここではMySQLを例にしています。

4.1. データベース接続情報の設定

プロジェクトルートの .env ファイルを編集し、DATABASE_URL を設定してください。

DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

4.2. ユーザエンティティの作成

Symfony MakerBundleを利用してユーザエンティティを作成します。

php bin/console make:user

プロンプトに従い、エンティティ名(例:User)や識別子(メールアドレスまたはユーザ名)、パスワードフィールド、既定のロール(通常ユーザには ROLE_USER、管理者には ROLE_ADMIN)を設定します。

4.3. 掲示板投稿(Post)エンティティの作成

投稿情報を保存するためのエンティティを作成します。

php bin/console make:entity Post

以下のフィールドを追加すると良いでしょう:

  • title : string
  • content : text
  • createdAt : datetime
  • user : ManyToOne(Userエンティティとの関連付け、投稿者情報)

4.4. マイグレーションの実行

エンティティ作成後、マイグレーションを作成してデータベースに反映させます

php bin/console make:migration
php bin/console doctrine:migrations:migrate

5.ユーザ認証と管理者機能の実装

Symfonyのセキュリティコンポーネントを利用して、ログイン・登録機能、アクセス制限を実装します。

5.1. ログイン・登録フォームの作成

Symfony MakerBundleを使用して、ログインフォーム認証を生成します

php bin/console make:auth

また、ユーザ登録フォームも作成する場合は

php bin/console make:registration-form

生成されたコントローラーやフォームクラスを適宜編集し、パスワードエンコーディングやCSRF保護の設定を確認してください。

5.2. security.yaml の設定

プロジェクトの config/packages/security.yaml を以下のように設定します。必要に応じてプロバイダやファイアウォールの設定を調整してください。

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt

    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            lazy: true
            provider: app_user_provider
            form_login:
                login_path: login
                check_path: login
                default_target_path: /
            logout:
                path: logout

    access_control:
        # 管理者エリアへのアクセスはROLE_ADMINに制限
        - { path: ^/admin, roles: ROLE_ADMIN }
        # 投稿作成・編集はログインユーザに制限
        - { path: ^/post/new, roles: ROLE_USER }
        - { path: ^/post/edit, roles: ROLE_USER }

5.3. 管理者権限の付与

ユーザ登録時や管理画面で、管理者ユーザには ROLE_ADMIN を割り当てます。管理エリア用のコントローラー(例:AdminDashboardController)はルートを /admin で始め、上記の access_control により管理者以外はアクセスできないようにします。

6.掲示板機能(BBS)の実装

掲示板の基本機能として、投稿の一覧表示、投稿詳細、投稿作成、編集、削除などの機能を実装します。

6.1. コントローラー作成

例として、BoardController を作成し、以下のようなアクションを実装します。

<?php
// src/Controller/BoardController.php
namespace App\Controller;

use App\Entity\Post;
use App\Repository\PostRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class BoardController extends AbstractController
{
    /**
     * @Route("/", name="board_index")
     */
    public function index(PostRepository $postRepository): Response
    {
        $posts = $postRepository->findBy([], ['createdAt' => 'DESC']);
        return $this->render('board/index.html.twig', [
            'posts' => $posts,
        ]);
    }

    /**
     * @Route("/post/{id}", name="board_view", requirements={"id"="\d+"})
     */
    public function view(Post $post): Response
    {
        return $this->render('board/view.html.twig', [
            'post' => $post,
        ]);
    }

    /**
     * @Route("/post/new", name="board_new")
     */
    public function new(Request $request): Response
    {
        // ログインユーザのみ投稿可能
        $this->denyAccessUnlessGranted('ROLE_USER');

        $post = new Post();
        // フォーム作成、リクエストのハンドリング(例:Symfony Formコンポーネントを利用)
        // ※ ここでは簡易例として、フォーム処理の詳細は省略

        // 保存処理
        // $entityManager = $this->getDoctrine()->getManager();
        // $post->setCreatedAt(new \DateTime());
        // $post->setUser($this->getUser());
        // $entityManager->persist($post);
        // $entityManager->flush();

        return $this->render('board/new.html.twig', [
            'post' => $post,
            // 'form' => $form->createView(),
        ]);
    }

    // 編集・削除アクションも必要に応じて実装
}

6.2. Twigテンプレート作成

templates/board/ 配下に各ビュー用テンプレートを作成します。

例:index.html.twig(投稿一覧表示)

{% extends 'base.html.twig' %}

{% block title %}掲示板{% endblock %}

{% block body %}
    <h1>掲示板投稿一覧</h1>
    {% for post in posts %}
        <div class="post">
            <h2><a href="{{ path('board_view', {id: post.id}) }}">{{ post.title }}</a></h2>
            <p>{{ post.content|raw }}</p>
            <small>投稿者: {{ post.user.email }} ・ 投稿日: {{ post.createdAt|date('Y-m-d H:i') }}</small>
        </div>
        <hr>
    {% else %}
        <p>まだ投稿がありません。</p>
    {% endfor %}
    {% if is_granted('ROLE_USER') %}
        <a href="{{ path('board_new') }}">新規投稿</a>
    {% else %}
        <p><a href="{{ path('login') }}">ログイン</a>して投稿しましょう。</p>
    {% endif %}
{% endblock %}

※ 各テンプレートは必要に応じてデザインやレイアウトを調整してください。

7.アクセス制限とセキュリティ対策

アクセス制限
  • /admin 以下のルートは ROLE_ADMIN のみアクセス可能とし、security.yamlaccess_control で管理
  • 投稿作成編集はログインユーザ(ROLE_USER)に限定するため、コントローラー内で denyAccessUnlessGranted() を利用
セキュリティ対策
  • フォームにCSRF保護を設定
  • ユーザ入力のバリデーションとサニタイズを実施
  • パスワードはエンコーダー(例:bcrypt)で暗号化

8.パーミッション設定と本番環境向け最適化

8.1. ディレクトリのパーミッション設定

Symfonyはキャッシュやログを書き込むため、Apache(例:ユーザ www-data)が書き込めるようACLを設定します。

sudo setfacl -R -m u:www-data:rwX -m u:$(whoami):rwX var
sudo setfacl -dR -m u:www-data:rwX -m u:$(whoami):rwX var

8.2. 本番環境向け設定の調整

.env で環境変数を設定(例:APP_ENV=prod, APP_DEBUG=0

キャッシュのウォームアップ

php bin/console cache:warmup --env=prod

9.テストと動作確認

ローカルでの動作確認

ビルトインサーバを使ってローカルテスト

php bin/console server:run

ブラウザで http://127.0.0.1:8000 にアクセスし、投稿一覧やログイン・登録、投稿作成など各機能を確認してください。

本番サーバでの確認

DNS設定が完了していることを確認した上で、http://www.example.com へアクセスし、各機能が正しく動作するかテストします。

トラブルシューティング

エラーが発生した場合は、var/log/ 内のログファイル(例:prod.logdev.log)を確認し、エラーメッセージに基づいて対処してください。

10.まとめ

今回のマニュアルでは、Symfony4を用いた掲示板アプリケーションの作成手順を、以下の要素を中心に解説しました

  • ユーザ認証・登録
    ログインフォームの生成とユーザエンティティ作成
  • 管理者権限
    ROLE_ADMIN による管理エリアの制限
  • アクセス制限
    各アクションへのアクセスをセキュリティコンポーネントで制御
  • データベース連携
    Doctrineを利用したユーザ・投稿エンティティの管理
  • 掲示板機能
    投稿の一覧表示、詳細表示、投稿作成・編集機能の実装

PHP5時代と比べ、Symfony4は構造化された設計や豊富なコンポーネントにより、拡張性・保守性に優れたアプリケーション開発が可能です。まずは本マニュアルの手順に沿って基本機能を実装し、そこからさらにカスタマイズや機能追加に挑戦してみてください。

スポンサーリンク
Symfony
フォローしてね
スポンサーリンク

コメント

タイトルとURLをコピーしました