Symfonyの雑なメモ:2018-01-23

Service Container

サービスを作ると、それは自動的にプライベートとなる。
サービスは基本的にプライベートであるべきであり $container->get() を使ってサービスを取得しないほうが良い。

ただし、必要があるならば、設定を変えることでサービスをパブリックなものとして扱うことができる。

config/services.yaml

services:
    App\Service\MessageGenerator:
        public: true

MyController.php

<?php
// ...
public function new()
{
    $generator = $this->container->get(MessageGenerator::class); // パブリックであればこれで取得できる
}

Service Container (Symfony Docs)

Organizing Your Business Logic (Symfony 4.1 Best Practices)

AbstractController

ControllerAbstractController を継承してコントローラを作成することで、ヘルパーメソッドを扱うことができるようになる。
ただし AbstractController を継承した場合は $this->get()$this->container->get() を使ってもパブリックなサービスにアクセスすることができなくなる。
直接アクセスする必要があるなら Controller を使用しなければならない。

Controller (Symfony Docs)

ベストプラクティスでは AbstractController を継承することを推奨している。

Controllers (Symfony 4.1 Best Practices)

Prefix imported route names

New in Symfony 4.1: Prefix imported route names (Symfony Blog)

Symfony3.4, 4.0, 4.1 では、1つのコントローラクラス内の全てのルート名に、プレフィックスを付けることが可能になった。

例えば以下のような書き方が、

<?php
// ...
/** @Route("/blog") */
class BlogController extends AbstractController
{
    /** @Route("/", name="blog_index") */
    public function indexAction() { ... }

    /** @Route("/posts/{slug}", name="blog_post") */
    public function showAction(Post $post) { ... }
}

このように書けるようになって、いちいち各ルート名にプレフィックスを付ける必要がなくなる。

<?php
// ...
/** @Route("/blog", name="blog_") */
class BlogController extends AbstractController
{
    /** @Route("/", name="index") */
    public function indexAction() { ... }

    /** @Route("/posts/{slug}", name="post") */
    public function showAction(Post $post) { ... }
}

Command is not defined.

SymfonyではConsole componentを使うことで簡単にコマンドを作ることができる。

Console Commands (Symfony Docs)

あるとき、これを使ってコマンド作ったら Command is not defined. と出てしまい困っていたのだが、サフィックスCommand と付けて命名してなかったことが原因で、なんとも無駄な時間を食ってしまった。

symfony - Symfony2 custom console command appears as "not defined" upon execution - Stack Overflow