Controller

A controller is a PHP function you create that reads information from the Request object and creates and returns a Response object. The response could be an HTML page, JSON, XML, a file download, a redirect, a 404 error or anything else. The controller runs whatever arbitrary logic your application needs to render the content of a page.

コントローラーは、Request オブジェクトから情報を読み取り、Response オブジェクトを作成して返す PHP 関数です。応答は、HTML ページ、JSON、XML、ファイルのダウンロード、リダイレクト、404 エラーなどです。コントローラーは、アプリケーションがページのコンテンツをレンダリングするために必要な任意のロジックを実行します。

Tip

ヒント

If you haven't already created your first working page, check out Create your First Page in Symfony and then come back!

最初の作業ページをまだ作成していない場合は、Symfony で最初のページを作成するを確認してから、戻ってきてください!

A Basic Controller

While a controller can be any PHP callable (function, method on an object, or a Closure), a controller is usually a method inside a controller class:

コントローラーは任意の PHP 呼び出し可能 (関数、オブジェクトのメソッド、またはクロージャー) にすることができますが、コントローラーは通常、コントローラークラス内のメソッドです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/LuckyController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class LuckyController
{
    #[Route('/lucky/number/{max}', name: 'app_lucky_number')]
    public function number(int $max): Response
    {
        $number = random_int(0, $max);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}

The controller is the number() method, which lives inside the controller class LuckyController.

コントローラは、コントローラ クラス LuckyController 内に存在する number() メソッドです。

This controller is pretty straightforward:

このコントローラーは非常に簡単です。
  • line 2: Symfony takes advantage of PHP's namespace functionality to namespace the entire controller class.
    行 2: Symfony は PHP の名前空間機能を利用して、コントローラー クラス全体の名前空間を作成します。
  • line 4: Symfony again takes advantage of PHP's namespace functionality: the use keyword imports the Response class, which the controller must return.
    4 行目: symfony は再び PHP の名前空間機能を利用します: use キーワードは、コントローラが返さなければならない Response クラスをインポートします。
  • line 7: The class can technically be called anything, but it's suffixed with Controller by convention.
    7 行目: クラスは技術的には何とでも呼ぶことができますが、慣例により Controller というサフィックスが付きます。
  • line 10: The action method is allowed to have a $max argument thanks to the {max} wildcard in the route.
    10 行目: ルートの {max} ワイルドカードのおかげで、アクション メソッドは $max 引数を持つことができます。
  • line 14: The controller creates and returns a Response object.
    14 行目: コントローラーは Response オブジェクトを作成して返します。

Mapping a URL to a Controller

In order to view the result of this controller, you need to map a URL to it via a route. This was done above with the #[Route('/lucky/number/{max}')] route attribute.

このコントローラーの結果を表示するには、ルートを介して URL をマップする必要があります。これは、上記の #[Route('/lucky/number/{max}')]route 属性で行われました。

To see your page, go to this URL in your browser: http://localhost:8000/lucky/number/100

ページを表示するには、ブラウザで次の URL にアクセスします: http://localhost:8000/lucky/number/100

For more information on routing, see Routing.

ルーティングの詳細については、ルーティングを参照してください。

The Base Controller Class & Services

To aid development, Symfony comes with an optional base controller class called AbstractController. It can be extended to gain access to helper methods.

開発を支援するために、Symfony には、AbstractController と呼ばれるオプションの基本コントローラー クラスが付属しています。これを拡張して、ヘルパー メソッドにアクセスすることができます。

Add the use statement atop your controller class and then modify LuckyController to extend it:

コントローラー クラスの上に use ステートメントを追加し、LuckyController を変更してそれを拡張します。
1
2
3
4
5
6
7
8
9
10
// src/Controller/LuckyController.php
  namespace App\Controller;

+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

- class LuckyController
+ class LuckyController extends AbstractController
  {
      // ...
  }

That's it! You now have access to methods like $this->render() and many others that you'll learn about next.

それでおしまい! $this->render() のようなメソッドや、次に学習する他の多くのメソッドにアクセスできるようになりました。

Generating URLs

The generateUrl() method is just a helper method that generates the URL for a given route:

generateUrl() メソッドは、特定のルートの URL を生成する単なるヘルパー メソッドです。
1
$url = $this->generateUrl('app_lucky_number', ['max' => 10]);

Redirecting

If you want to redirect the user to another page, use the redirectToRoute() and redirect() methods:

ユーザーを別のページにリダイレクトする場合は、redirectToRoute() および redirect() メソッドを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

// ...
public function index(): RedirectResponse
{
    // redirects to the "homepage" route
    return $this->redirectToRoute('homepage');

    // redirectToRoute is a shortcut for:
    // return new RedirectResponse($this->generateUrl('homepage'));

    // does a permanent HTTP 301 redirect
    return $this->redirectToRoute('homepage', [], 301);
    // if you prefer, you can use PHP constants instead of hardcoded numbers
    return $this->redirectToRoute('homepage', [], Response::HTTP_MOVED_PERMANENTLY);

    // redirect to a route with parameters
    return $this->redirectToRoute('app_lucky_number', ['max' => 10]);

    // redirects to a route and maintains the original query string parameters
    return $this->redirectToRoute('blog_show', $request->query->all());

    // redirects to the current route (e.g. for Post/Redirect/Get pattern):
    return $this->redirectToRoute($request->attributes->get('_route'));

    // redirects externally
    return $this->redirect('http://symfony.com/doc');
}

Caution

注意

The redirect() method does not check its destination in any way. If you redirect to a URL provided by end-users, your application may be open to the unvalidated redirects security vulnerability.

redirect() メソッドは、その宛先をまったくチェックしません。エンドユーザーから提供された URL にリダイレクトする場合、アプリケーションは検証されていないリダイレクトのセキュリティ上の脆弱性にさらされる可能性があります。

Rendering Templates

If you're serving HTML, you'll want to render a template. The render() method renders a template and puts that content into a Response object for you:

HTML を提供している場合は、テンプレートをレンダリングする必要があります。 render() メソッドはテンプレートをレンダリングし、そのコンテンツを Response オブジェクトに入れます。
1
2
// renders templates/lucky/number.html.twig
return $this->render('lucky/number.html.twig', ['number' => $number]);

Templating and Twig are explained more in the Creating and Using Templates article.

テンプレートと Twig については、テンプレートの作成と使用の記事で詳しく説明されています。

Fetching Services

Symfony comes packed with a lot of useful classes and functionalities, called services. These are used for rendering templates, sending emails, querying the database and any other "work" you can think of.

Symfony には、サービスと呼ばれる多くの便利なクラスと機能が詰め込まれています。これらは、テンプレートのレンダリング、電子メールの送信、データベースのクエリ、および考えられるその他の「作業」に使用されます。

If you need a service in a controller, type-hint an argument with its class (or interface) name. Symfony will automatically pass you the service you need:

コントローラーでサービスが必要な場合は、そのクラス (またはインターフェイス) 名で引数を型ヒントします。 symfony は、必要なサービスを自動的に渡します。
1
2
3
4
5
6
7
8
9
10
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
// ...

#[Route('/lucky/number/{max}')]
public function number(int $max, LoggerInterface $logger): Response
{
    $logger->info('We are logging!');
    // ...
}

Awesome!

素晴らしい!

What other services can you type-hint? To see them, use the debug:autowiring console command:

タイプヒントできる他のサービスは何ですか?それらを表示するには、debug:autowiring コンソール コマンドを使用します。
1
$ php bin/console debug:autowiring

Tip

ヒント

If you need control over the exact value of an argument, or require a parameter, you can use the #[Autowire] attribute:

引数の正確な値を制御する必要がある場合、またはパラメーターが必要な場合は、 #[Autowire] 属性を使用できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ...
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;

class LuckyController extends AbstractController
{
    public function number(
        int $max,

        // inject a specific logger service
        #[Autowire(service: 'monolog.logger.request')]
        LoggerInterface $logger,

        // or inject parameter values
        #[Autowire('%kernel.project_dir%')]
        string $projectDir
    ): Response
    {
        $logger->info('We are logging!');
        // ...
    }
}

You can read more about this attribute in Defining Services Dependencies Automatically (Autowiring).

この属性の詳細については、サービス依存関係の自動定義 (オートワイヤー) を参照してください。

6.1

6.1

The #[Autowire] attribute was introduced in Symfony 6.1.

#[Autowire] 属性は Symfony 6.1 で導入されました。

Like with all services, you can also use regular constructor injection in your controllers.

すべてのサービスと同様に、コントローラーで通常のコンストラクター インジェクションを使用することもできます。

For more information about services, see the Service Container article.

サービスの詳細については、サービス コンテナーの記事を参照してください。

Generating Controllers

To save time, you can install Symfony Maker and tell Symfony to generate a new controller class:

時間を節約するために、Symfony Maker をインストールして、Symfony に新しいコントローラー クラスを生成するように指示できます。
1
2
3
4
$ php bin/console make:controller BrandNewController

created: src/Controller/BrandNewController.php
created: templates/brandnew/index.html.twig

If you want to generate an entire CRUD from a Doctrine entity, use:

DoctrineエンティティからCRUD全体を生成したい場合は、次を使用します:
1
2
3
4
5
6
7
8
9
10
$ php bin/console make:crud Product

created: src/Controller/ProductController.php
created: src/Form/ProductType.php
created: templates/product/_delete_form.html.twig
created: templates/product/_form.html.twig
created: templates/product/edit.html.twig
created: templates/product/index.html.twig
created: templates/product/new.html.twig
created: templates/product/show.html.twig

Managing Errors and 404 Pages

When things are not found, you should return a 404 response. To do this, throw a special type of exception:

見つからない場合は、404 応答を返す必要があります。これを行うには、特別なタイプの例外をスローします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

// ...
public function index(): Response
{
    // retrieve the object from database
    $product = ...;
    if (!$product) {
        throw $this->createNotFoundException('The product does not exist');

        // the above is just a shortcut for:
        // throw new NotFoundHttpException('The product does not exist');
    }

    return $this->render(/* ... */);
}

The createNotFoundException() method is just a shortcut to create a special NotFoundHttpException object, which ultimately triggers a 404 HTTP response inside Symfony.

createNotFoundException() メソッドは、最終的に Symfony 内で 404 HTTP 応答をトリガーする、特別な NotFoundHttpException オブジェクトを作成するための単なるショートカットです。

If you throw an exception that extends or is an instance of HttpException, Symfony will use the appropriate HTTP status code. Otherwise, the response will have a 500 HTTP status code:

HttpException の拡張またはインスタンスである例外をスローすると、Symfony は適切な HTTP ステータス コードを使用します。それ以外の場合、応答には 500HTTP ステータス コードが含まれます。
1
2
// this exception ultimately generates a 500 status error
throw new \Exception('Something went wrong!');

In every case, an error page is shown to the end user and a full debug error page is shown to the developer (i.e. when you're in "Debug" mode - see Configuring Symfony).

いずれの場合も、エンドユーザーにはエラーページが表示され、開発者には完全なデバッグエラーページが表示されます (つまり、「デバッグ」モードの場合 - Symfony の設定を参照してください)。

To customize the error page that's shown to the user, see the How to Customize Error Pages article.

ユーザーに表示されるエラー ページをカスタマイズするには、エラー ページをカスタマイズする方法の記事を参照してください。

The Request object as a Controller Argument

What if you need to read query parameters, grab a request header or get access to an uploaded file? That information is stored in Symfony's Request object. To access it in your controller, add it as an argument and type-hint it with the Request class:

クエリ パラメータを読み取ったり、リクエスト ヘッダーを取得したり、アップロードされたファイルにアクセスしたりする必要がある場合はどうすればよいでしょうか。その情報は Symfony の Request オブジェクトに保存されます。コントローラーでアクセスするには、それを引数として追加し、Request クラスでタイプヒントを指定します。
1
2
3
4
5
6
7
8
9
10
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

public function index(Request $request): Response
{
    $page = $request->query->get('page', 1);

    // ...
}

Keep reading for more information about using the Request object.

Request オブジェクトの使用に関する詳細については、引き続きお読みください。

Managing the Session

Symfony provides a session object that you can use to store information about the user between requests. Session is enabled by default, but will only be started if you read or write from it.

symfony は、リクエスト間でユーザーに関する情報を保存するために使用できるセッション オブジェクトを提供します。セッションはデフォルトで有効になっていますが、セッションから読み取りまたは書き込みを行う場合にのみ開始されます。

Session storage and other configuration can be controlled under the framework.session configuration in config/packages/framework.yaml.

セッション ストレージとその他の構成は、config/packages/framework.yaml のframework.session 構成で制御できます。

To get the session, add an argument and type-hint it with SessionInterface:

セッションを取得するには、引数を追加し、SessionInterface で型ヒントを付けます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
// ...

public function index(SessionInterface $session): Response
{
    // stores an attribute for reuse during a later user request
    $session->set('foo', 'bar');

    // gets the attribute set by another controller in another request
    $foobar = $session->get('foobar');

    // uses a default value if the attribute doesn't exist
    $filters = $session->get('filters', []);

    // ...
}

Stored attributes remain in the session for the remainder of that user's session.

保存された属性は、そのユーザーのセッションの残りの間、セッションに残ります。

For more info, see Sessions.

詳細については、「セッション」を参照してください。

Flash Messages

You can also store special messages, called "flash" messages, on the user's session. By design, flash messages are meant to be used exactly once: they vanish from the session automatically as soon as you retrieve them. This feature makes "flash" messages particularly great for storing user notifications.

「フラッシュ」メッセージと呼ばれる特別なメッセージをユーザーのセッションに保存することもできます。設計上、フラッシュ メッセージは 1 回だけ使用されるようになっています。取得するとすぐにセッションから自動的に消えます。この機能により、「フラッシュ」メッセージは、ユーザー通知の保存に特に優れたものになります。

For example, imagine you're processing a form submission:

たとえば、フォームの送信を処理しているとします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

public function update(Request $request): Response
{
    // ...

    if ($form->isSubmitted() && $form->isValid()) {
        // do some sort of processing

        $this->addFlash(
            'notice',
            'Your changes were saved!'
        );
        // $this->addFlash() is equivalent to $request->getSession()->getFlashBag()->add()

        return $this->redirectToRoute(/* ... */);
    }

    return $this->render(/* ... */);
}

After processing the request, the controller sets a flash message in the session and then redirects. The message key (notice in this example) can be anything: you'll use this key to retrieve the message.

リクエストを処理した後、コントローラーはセッションにフラッシュ メッセージを設定し、リダイレクトします。メッセージ キー (この例では通知) は何でもかまいません。このキーを使用してメッセージを取得します。

In the template of the next page (or even better, in your base layout template), read any flash messages from the session using the flashes() method provided by the Twig global app variable:

次のページのテンプレート (またはベース レイアウト テンプレート) で、Twig グローバル アプリ変数によって提供される flashes() メソッドを使用して、セッションからのフラッシュ メッセージを読み取ります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{# templates/base.html.twig #}

{# read and display just one flash message type #}
{% for message in app.flashes('notice') %}
    <div class="flash-notice">
        {{ message }}
    </div>
{% endfor %}

{# read and display several types of flash messages #}
{% for label, messages in app.flashes(['success', 'warning']) %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

{# read and display all flash messages #}
{% for label, messages in app.flashes %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

It's common to use notice, warning and error as the keys of the different types of flash messages, but you can use any key that fits your needs.

さまざまな種類のフラッシュ メッセージのキーとして通知、警告、およびエラーを使用するのが一般的ですが、必要に応じて任意のキーを使用できます。

Tip

ヒント

You can use the peek() method instead to retrieve the message while keeping it in the bag.

代わりに peek() メソッドを使用して、メッセージをバッグに入れたままで取り出すことができます。

The Request and Response Object

As mentioned earlier, Symfony will pass the Request object to any controller argument that is type-hinted with the Request class:

前に述べたように、Symfony は Request オブジェクトを、Request クラスで型ヒントされたコントローラー引数に渡します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

public function index(Request $request): Response
{
    $request->isXmlHttpRequest(); // is it an Ajax request?

    $request->getPreferredLanguage(['en', 'fr']);

    // retrieves GET and POST variables respectively
    $request->query->get('page');
    $request->request->get('page');

    // retrieves SERVER variables
    $request->server->get('HTTP_HOST');

    // retrieves an instance of UploadedFile identified by foo
    $request->files->get('foo');

    // retrieves a COOKIE value
    $request->cookies->get('PHPSESSID');

    // retrieves an HTTP request header, with normalized, lowercase keys
    $request->headers->get('host');
    $request->headers->get('content-type');
}

The Request class has several public properties and methods that return any information you need about the request.

Request クラスには、要求に関して必要な情報を返すパブリック プロパティとメソッドがいくつかあります。

Like the Request, the Response object has a public headers property. This object is of the type ResponseHeaderBag and provides methods for getting and setting response headers. The header names are normalized. As a result, the name Content-Type is equivalent to the name content-type or content_type.

Request と同様に、Response オブジェクトには public headers プロパティがあります。このオブジェクトは ResponseHeaderBag 型であり、応答ヘッダーを取得および設定するためのメソッドを提供します。ヘッダー名は正規化されています。その結果、Content-Type という名前は、content-type または content_type という名前と同じになります。

In Symfony, a controller is required to return a Response object:

Symfony では、コントローラーは Response オブジェクトを返す必要があります。
1
2
3
4
5
6
7
8
use Symfony\Component\HttpFoundation\Response;

// creates a simple Response with a 200 status code (the default)
$response = new Response('Hello '.$name, Response::HTTP_OK);

// creates a CSS-response with a 200 status code
$response = new Response('<style> ... </style>');
$response->headers->set('Content-Type', 'text/css');

To facilitate this, different response objects are included to address different response types. Some of these are mentioned below. To learn more about the Request and Response (and different Response classes), see the HttpFoundation component documentation.

これを容易にするために、さまざまな応答タイプに対処するために、さまざまな応答オブジェクトが含まれています。これらのいくつかを以下に示します。 Request と Response (およびさまざまな Response クラス) の詳細については、HttpFoundation コンポーネントのドキュメントを参照してください。

Accessing Configuration Values

To get the value of any configuration parameter from a controller, use the getParameter() helper method:

コントローラーから構成パラメーターの値を取得するには、getParameter() ヘルパー メソッドを使用します。
1
2
3
4
5
6
// ...
public function index(): Response
{
    $contentsDir = $this->getParameter('kernel.project_dir').'/contents';
    // ...
}

Returning JSON Response

To return JSON from a controller, use the json() helper method. This returns a JsonResponse object that encodes the data automatically:

コントローラーから JSON を返すには、json() ヘルパー メソッドを使用します。これは、データを自動的にエンコードする JsonResponse オブジェクトを返します。
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\HttpFoundation\JsonResponse;
// ...

public function index(): JsonResponse
{
    // returns '{"username":"jane.doe"}' and sets the proper Content-Type header
    return $this->json(['username' => 'jane.doe']);

    // the shortcut defines three optional arguments
    // return $this->json($data, $status = 200, $headers = [], $context = []);
}

If the serializer service is enabled in your application, it will be used to serialize the data to JSON. Otherwise, the json_encode function is used.

アプリケーションでシリアライザー サービスが有効になっている場合は、データを JSON にシリアル化するために使用されます。それ以外の場合は、json_encode 関数が使用されます。

Streaming File Responses

You can use the file() helper to serve a file from inside a controller:

file() ヘルパーを使用して、コントローラー内からファイルを提供できます。
1
2
3
4
5
6
7
8
use Symfony\Component\HttpFoundation\BinaryFileResponse;
// ...

public function download(): BinaryFileResponse
{
    // send the file contents and force the browser to download it
    return $this->file('/path/to/some_file.pdf');
}

The file() helper provides some arguments to configure its behavior:

file() ヘルパーは、その動作を設定するためのいくつかの引数を提供します:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
// ...

public function download(): BinaryFileResponse
{
    // load the file from the filesystem
    $file = new File('/path/to/some_file.pdf');

    return $this->file($file);

    // rename the downloaded file
    return $this->file($file, 'custom_name.pdf');

    // display the file contents in the browser instead of downloading it
    return $this->file('invoice_3241.pdf', 'my_invoice.pdf', ResponseHeaderBag::DISPOSITION_INLINE);
}

Final Thoughts

In Symfony, a controller is usually a class method which is used to accept requests, and return a Response object. When mapped with a URL, a controller becomes accessible and its response can be viewed.

Symfony では、コントローラーは通常、リクエストを受け入れ、Response オブジェクトを返すために使用されるクラス メソッドです。 URL でマップすると、コントローラーにアクセスできるようになり、その応答を表示できます。

To facilitate the development of controllers, Symfony provides an AbstractController. It can be used to extend the controller class allowing access to some frequently used utilities such as render() and redirectToRoute(). The AbstractController also provides the createNotFoundException() utility which is used to return a page not found response.

コントローラーの開発を容易にするために、Symfony は、AbstractController を提供します。これを使用してコントローラー クラスを拡張し、render() や redirectToRoute() などの頻繁に使用されるユーティリティにアクセスできるようにすることができます。 AbstractController は、ページが見つからないという応答を返すために使用される createNotFoundException() ユーティリティも提供します。

In other articles, you'll learn how to use specific services from inside your controller that will help you persist and fetch objects from a database, process form submissions, handle caching and more.

他の記事では、データベースからのオブジェクトの永続化とフェッチ、フォーム送信の処理、キャッシュの処理などに役立つ特定のサービスをコントローラー内から使用する方法を学習します。

Keep Going!

Next, learn all about rendering templates with Twig.

次に、Twig を使用したレンダリング テンプレートについて学習します。

Learn more about Controllers