The HttpKernel Component

The HttpKernel component provides a structured process for converting a Request into a Response by making use of the EventDispatcher component. It's flexible enough to create a full-stack framework (Symfony), a micro-framework (Silex) or an advanced CMS (Drupal).

HttpKernel コンポーネントは、EventDispatcher コンポーネントを利用して、リクエストをレスポンスに変換するための構造化されたプロセスを提供します。フルスタック フレームワーク (Symfony)、マイクロ フレームワーク (Silex)、または高度な CMS (Drupal) を作成するのに十分な柔軟性があります。

Installation

1
$ composer require symfony/http-kernel

Note

ノート

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

このコンポーネントを Symfony アプリケーションの外部にインストールする場合は、Composer が提供するクラス自動ロード メカニズムを有効にするために、コード内に vendor/autoload.php ファイルを必要とする必要があります。詳細については、この記事をお読みください。

The Workflow of a Request

See also

こちらもご覧ください

This article explains how to use the HttpKernel features as an independent component in any PHP application. In Symfony applications everything is already configured and ready to use. Read the Controller and Events and Event Listeners articles to learn about how to use it to create controllers and define events in Symfony applications.

この記事では、HttpKernel 機能を任意の PHP アプリケーションで独立したコンポーネントとして使用する方法について説明します。 Symfony アプリケーションでは、すべてがすでに構成されており、すぐに使用できます。 Symfony アプリケーションでコントローラーを作成し、イベントを定義するために使用する方法については、コントローラーとイベントおよびイベント リスナーの記事をお読みください。

Every HTTP web interaction begins with a request and ends with a response. Your job as a developer is to create PHP code that reads the request information (e.g. the URL) and creates and returns a response (e.g. an HTML page or JSON string). This is a simplified overview of the request workflow in Symfony applications:

すべての HTTP Web インタラクションは要求で始まり、応答で終わります。開発者としてのあなたの仕事は、要求情報 (URL など) を読み取り、応答 (HTML ページや JSON 文字列など) を作成して返す PHP コードを作成することです。これは、Symfony アプリケーションでのリクエスト ワークフローの簡単な概要です。
  1. The user asks for a resource in a browser;
    ユーザーはブラウザでリソースを要求します。
  2. The browser sends a request to the server;
    ブラウザはサーバーにリクエストを送信します。
  3. Symfony gives the application a Request object;
    symfony はアプリケーションに Request オブジェクトを提供します。
  4. The application generates a Response object using the data of the Request object;
    アプリケーションは、Request オブジェクトのデータを使用して Response オブジェクトを生成します。
  5. The server sends back the response to the browser;
    サーバーはブラウザに応答を返します。
  6. The browser displays the resource to the user.
    ブラウザはリソースをユーザーに表示します。

Typically, some sort of framework or system is built to handle all the repetitive tasks (e.g. routing, security, etc) so that a developer can build each page of the application. Exactly how these systems are built varies greatly. The HttpKernel component provides an interface that formalizes the process of starting with a request and creating the appropriate response. The component is meant to be the heart of any application or framework, no matter how varied the architecture of that system:

通常、開発者がアプリケーションの各ページを構築できるように、すべての繰り返しタスク (ルーティング、セキュリティなど) を処理するために、ある種のフレームワークまたはシステムが構築されます。これらのシステムの正確な構築方法は、大きく異なります。 HttpKernel コンポーネントは、要求から開始して適切な応答を作成するプロセスを形式化するインターフェースを提供します。コンポーネントは、そのシステムのアーキテクチャがどれほど多様であっても、アプリケーションまたはフレームワークの中心となることを意図しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace Symfony\Component\HttpKernel;

use Symfony\Component\HttpFoundation\Request;

interface HttpKernelInterface
{
    // ...

    /**
     * @return Response A Response instance
     */
    public function handle(
        Request $request,
        int $type = self::MAIN_REQUEST,
        bool $catch = true
    ): Response;
}

Internally, HttpKernel::handle() - the concrete implementation of HttpKernelInterface::handle() - defines a workflow that starts with a Request and ends with a Response.

内部的には、HttpKernel::handle() - HttpKernelInterface::handle() の具体的な実装 - は、Request で開始し、Response で終了するワークフローを定義します。

The exact details of this workflow are the key to understanding how the kernel (and the Symfony Framework or any other library that uses the kernel) works.

このワークフローの正確な詳細は、カーネル (および Symfony フレームワークまたはカーネルを使用する他のライブラリ) がどのように機能するかを理解するための鍵です。

HttpKernel: Driven by Events

The HttpKernel::handle() method works internally by dispatching events. This makes the method both flexible, but also a bit abstract, since all the "work" of a framework/application built with HttpKernel is actually done in event listeners.

HttpKernel::handle() メソッドは、イベントをディスパッチすることによって内部的に機能します。これにより、HttpKernel で構築されたフレームワーク/アプリケーションのすべての「作業」が実際にはイベント リスナーで行われるため、メソッドが柔軟になりますが、少し抽象的になります。

To help explain this process, this document looks at each step of the process and talks about how one specific implementation of the HttpKernel - the Symfony Framework - works.

このプロセスを説明するために、このドキュメントではプロセスの各ステップを見て、HttpKernel の 1 つの特定の実装である SymfonyFramework がどのように機能するかについて説明します。

Initially, using the HttpKernel does not take many steps. You create an event dispatcher and a controller and argument resolver (explained below). To complete your working kernel, you'll add more event listeners to the events discussed below:

最初は、HttpKernel を使用するのに多くの手順は必要ありません。イベント ディスパッチャー、コントローラー、および引数リゾルバー (以下で説明) を作成します。動作するカーネルを完成させるために、以下で説明するイベントにさらにイベント リスナーを追加します。
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\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\HttpKernel;

// create the Request object
$request = Request::createFromGlobals();

$dispatcher = new EventDispatcher();
// ... add some event listeners

// create your controller and argument resolvers
$controllerResolver = new ControllerResolver();
$argumentResolver = new ArgumentResolver();

// instantiate the kernel
$kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver);

// actually execute the kernel, which turns the request into a response
// by dispatching events, calling a controller, and returning the response
$response = $kernel->handle($request);

// send the headers and echo the content
$response->send();

// trigger the kernel.terminate event
$kernel->terminate($request, $response);

See "The HttpKernel Component" for a more concrete implementation.

より具体的な実装については、「HttpKernel コンポーネント」を参照してください。

For general information on adding listeners to the events below, see The HttpKernel Component.

以下のイベントへのリスナーの追加に関する一般的な情報については、「HttpKernel コンポーネント」を参照してください。

Caution

注意

As of 3.1 the HttpKernel accepts a fourth argument, which must be an instance of ArgumentResolverInterface. In 4.0 this argument will become mandatory.

3.1 の時点で、HttpKernel は 4 番目の引数を受け入れます。これは、ArgumentResolverInterface のインスタンスでなければなりません。4.0 では、この引数は必須になります。

See also

こちらもご覧ください

There is a wonderful tutorial series on using the HttpKernel component and other Symfony components to create your own framework. See Introduction.

HttpKernel コンポーネントとその他の Symfony コンポーネントを使用して独自のフレームワークを作成するための素晴らしいチュートリアル シリーズがあります。はじめにを参照してください。

1) The kernel.request Event

Typical Purposes: To add more information to the Request, initialize parts of the system, or return a Response if possible (e.g. a security layer that denies access).

一般的な目的: リクエストにさらに情報を追加する、システムの一部を初期化する、または可能であればレスポンスを返す (アクセスを拒否するセキュリティ層など)。

Kernel Events Information Table

カーネル イベント情報テーブル

The first event that is dispatched inside HttpKernel::handle is kernel.request, which may have a variety of different listeners.

HttpKernel::handle 内でディスパッチされる最初のイベントは、kernel.request であり、さまざまな異なるリスナーを持つ可能性があります。

Listeners of this event can be quite varied. Some listeners - such as a security listener - might have enough information to create a Response object immediately. For example, if a security listener determined that a user doesn't have access, that listener may return a RedirectResponse to the login page or a 403 Access Denied response.

このイベントのリスナーは非常に多様です。一部のリスナー (セキュリティ リスナーなど) は、Response オブジェクトをすぐに作成するのに十分な情報を持っている場合があります。応答。

If a Response is returned at this stage, the process skips directly to the kernel.response event.

この段階で Response が返された場合、プロセスは kernel.response イベントに直接スキップします。

Other listeners initialize things or add more information to the request. For example, a listener might determine and set the locale on the Request object.

他のリスナーは、物事を初期化したり、要求に情報を追加したりします。たとえば、リスナーは、Request オブジェクトのロケールを決定して設定する場合があります。

Another common listener is routing. A router listener may process the Request and determine the controller that should be rendered (see the next section). In fact, the Request object has an "attributes" bag which is a perfect spot to store this extra, application-specific data about the request. This means that if your router listener somehow determines the controller, it can store it on the Request attributes (which can be used by your controller resolver).

もう 1 つの一般的なリスナーはルーティングです。ルーター リスナーは、Request を処理し、レンダリングする必要があるコントローラーを決定します (次のセクションを参照)。これは、ルーター リスナーが何らかの方法でコントローラーを決定した場合、それを Request 属性 (コントローラー リゾルバーで使用できる) に格納できることを意味します。

Overall, the purpose of the kernel.request event is either to create and return a Response directly, or to add information to the Request (e.g. setting the locale or setting some other information on the Request attributes).

全体として、kernel.request イベントの目的は、Response を作成して直接返すか、Request に情報を追加することです (例: ロケールの設定または Request 属性に関するその他の情報の設定)。

Note

ノート

When setting a response for the kernel.request event, the propagation is stopped. This means listeners with lower priority won't be executed.

kernel.request イベントの応答を設定すると、伝播が停止します。これは、優先度の低いリスナーが実行されないことを意味します。
Symfony フレームワークの kernel.request

The most important listener to kernel.request in the Symfony Framework is the RouterListener. This class executes the routing layer, which returns an array of information about the matched request, including the _controller and any placeholders that are in the route's pattern (e.g. {slug}). See the Routing documentation.

Symfony フレームワークの kernel.request に対する最も重要なリスナーは RouterListener です。このクラスはルーティング レイヤーを実行し、_controller とルートのパターン ({slug} など) にあるプレースホルダーを含む、一致したリクエストに関する情報の配列を返します。ルーティングのドキュメントを参照してください。

This array of information is stored in the Request object's attributes array. Adding the routing information here doesn't do anything yet, but is used next when resolving the controller.

この情報の配列は、Requestobject の属性配列に格納されます。ここにルーティング情報を追加しても、まだ何も実行されませんが、次にコントローラーを解決するときに使用されます。

2) Resolve the Controller

Assuming that no kernel.request listener was able to create a Response, the next step in HttpKernel is to determine and prepare (i.e. resolve) the controller. The controller is the part of the end-application's code that is responsible for creating and returning the Response for a specific page. The only requirement is that it is a PHP callable - i.e. a function, method on an object or a Closure.

どの kernel.request リスナーも Response を作成できなかったと仮定すると、HttpKernel の次のステップは、コントローラーを決定して準備する (つまり、解決する) ことです。コントローラーは、特定のページの応答を作成して返すエンドアプリケーションのコードの一部です。唯一の要件は、それが PHP 呼び出し可能であることです。つまり、関数、オブジェクトのメソッド、またはクロージャーです。

But how you determine the exact controller for a request is entirely up to your application. This is the job of the "controller resolver" - a class that implements ControllerResolverInterface and is one of the constructor arguments to HttpKernel.

ただし、リクエストの正確なコントローラーをどのように決定するかは、完全にアプリケーション次第です。これは、「コントローラー リゾルバー」の仕事です。これは、ControllerResolverInterface を実装するクラスであり、HttpKernel のコンストラクター引数の 1 つです。

Your job is to create a class that implements the interface and fill in its method: getController(). In fact, one default implementation already exists, which you can use directly or learn from: ControllerResolver. This implementation is explained more in the sidebar below:

あなたの仕事は、インターフェイスを実装し、そのメソッドを埋めるクラスを作成することです: getController()。実際、1 つのデフォルト実装が既に存在し、直接使用するか、ControllerResolver から学ぶことができます。この実装については、以下のサイドバーで詳しく説明します。
1
2
3
4
5
6
7
8
namespace Symfony\Component\HttpKernel\Controller;

use Symfony\Component\HttpFoundation\Request;

interface ControllerResolverInterface
{
    public function getController(Request $request);
}

Internally, the HttpKernel::handle() method first calls getController() on the controller resolver. This method is passed the Request and is responsible for somehow determining and returning a PHP callable (the controller) based on the request's information.

内部的には、HttpKernel::handle() メソッドは最初にコントローラー リゾルバーで getController() を呼び出します。このメソッドにはリクエストが渡され、リクエストの情報に基づいて PHP 呼び出し可能オブジェクト (コントローラ) を何らかの形で決定して返す役割を果たします。
Symfony フレームワークでコントローラーを解決する

The Symfony Framework uses the built-in ControllerResolver class (actually, it uses a subclass with some extra functionality mentioned below). This class leverages the information that was placed on the Request object's attributes property during the RouterListener.

Symfony フレームワークは、組み込みの ControllerResolver クラスを使用します (実際には、以下で説明するいくつかの追加機能を備えたサブクラスを使用します)。このクラスは、RouterListener 中に Request オブジェクトの属性プロパティに配置された情報を利用します。

getController

getController

The ControllerResolver looks for a _controller key on the Request object's attributes property (recall that this information is typically placed on the Request via the RouterListener). This string is then transformed into a PHP callable by doing the following:

ControllerResolver は、Request オブジェクトの属性プロパティで _controllerkey を探します (この情報は通常、RouterListener を介して Request に配置されることを思い出してください)。次に、この文字列は、次のようにして PHP 呼び出し可能オブジェクトに変換されます。
a) If the _controller key doesn't follow the recommended PHP namespace
format (e.g. App\Controller\DefaultController::index) its format is transformed into it. For example, the legacy FooBundle:Default:index format would be changed to Acme\FooBundle\Controller\DefaultController::indexAction. This transformation is specific to the ControllerResolver sub-class used by the Symfony Framework.
フォーマット (例: App\Controller\DefaultController::index) そのフォーマットはそれに変換されます。たとえば、従来の FooBundle:Default:indexformat は Acme\FooBundle\Controller\DefaultController::indexAction に変更されます。この変換は、Symfony フレームワークで使用される ControllerResolver サブクラスに固有です。
b) A new instance of your controller class is instantiated with no
constructor arguments.
コンストラクターの引数。
c) If the controller implements ContainerAwareInterface,
setContainer() is called on the controller object and the container is passed to it. This step is also specific to the ControllerResolver sub-class used by the Symfony Framework.
コントローラ オブジェクトで setContainer() が呼び出され、コンテナが渡されます。このステップは、Symfony フレームワークで使用される ControllerResolver サブクラスにも固有です。

3) The kernel.controller Event

Typical Purposes: Initialize things or change the controller just before the controller is executed.

典型的な目的: コントローラーが実行される直前に、物事を初期化するか、コントローラーを変更します。

Kernel Events Information Table

カーネル イベント情報テーブル

After the controller callable has been determined, HttpKernel::handle() dispatches the kernel.controller event. Listeners to this event might initialize some part of the system that needs to be initialized after certain things have been determined (e.g. the controller, routing information) but before the controller is executed.

コントローラーの呼び出し可能オブジェクトが決定された後、HttpKernel::handle() は kernel.controller イベントをディスパッチします。このイベントのリスナーは、特定の事柄 (コントローラー、ルーティング情報など) が決定された後、コントローラーが実行される前に、初期化する必要があるシステムの一部を初期化する場合があります。

Another typical use-case for this event is to retrieve the attributes from the controller using the getAttributes() method. See the Symfony section below for some examples.

このイベントのもう 1 つの一般的な使用例は、getAttributes() メソッドを使用してコントローラーから属性を取得することです。いくつかの例については、以下の Symfony セクションを参照してください。

6.2

6.2

The ControllerEvent::getAttributes() method was introduced in Symfony 6.2.

ControllerEvent::getAttributes() メソッドは Symfony 6.2 で導入されました。

Listeners to this event can also change the controller callable completely by calling ControllerEvent::setController on the event object that's passed to listeners on this event.

このイベントのリスナーは、このイベントでリスナーに渡されたイベント オブジェクトで ControllerEvent::setController を呼び出すことにより、呼び出し可能なコントローラーを完全に変更することもできます。
Symfony フレームワークの kernel.controller

An interesting listener to kernel.controller in the Symfony Framework is CacheAttributeListener. This class fetches #[Cache] attribute configuration from the controller and uses it to configure HTTP caching on the response.

SymfonyFramework の kernel.controller に対する興味深いリスナーは CacheAttributeListener です。このクラスはコントローラーから #[Cache] 属性の設定を取得し、それを使用して応答の HTTP キャッシングを設定します。

There are a few other minor listeners to the kernel.controller event in the Symfony Framework that deal with collecting profiler data when the profiler is enabled.

Symfony フレームワークの kernel.controller イベントには、プロファイラーが有効な場合にプロファイラー データの収集を処理するマイナー リスナーが他にもいくつかあります。

4) Getting the Controller Arguments

Next, HttpKernel::handle() calls ArgumentResolverInterface::getArguments(). Remember that the controller returned in getController() is a callable. The purpose of getArguments() is to return the array of arguments that should be passed to that controller. Exactly how this is done is completely up to your design, though the built-in ArgumentResolver is a good example.

次に、HttpKernel::handle() が ArgumentResolverInterface::getArguments() を呼び出します。getController() で返されたコントローラーは呼び出し可能であることを思い出してください。これがどのように行われるかは完全に設計次第ですが、組み込みの ArgumentResolver が良い例です。

At this point the kernel has a PHP callable (the controller) and an array of arguments that should be passed when executing that callable.

この時点で、カーネルには PHP 呼び出し可能オブジェクト (コントローラー) と、その呼び出し可能オブジェクトの実行時に渡される引数の配列があります。
Symfony フレームワークでコントローラー引数を取得する

Now that you know exactly what the controller callable (usually a method inside a controller object) is, the ArgumentResolver uses reflection on the callable to return an array of the names of each of the arguments. It then iterates over each of these arguments and uses the following tricks to determine which value should be passed for each argument:

コントローラー呼び出し可能オブジェクト (通常はコントローラー オブジェクト内のメソッド) が正確に何であるかがわかったので、ArgumentResolver は呼び出し可能オブジェクトのリフレクションを使用して、各引数の名前の配列を返します。次に、これらの各引数を反復処理し、次を使用します。各引数に渡す値を決定するためのトリック:
a) If the Request attributes bag contains a key that matches the name
of the argument, that value is used. For example, if the first argument to a controller is $slug and there is a slug key in the Request attributes bag, that value is used (and typically this value came from the RouterListener).
その値が使用されます。たとえば、コントローラの最初の引数が $slug で、Requestattributes バッグにスラッグ キーがある場合、その値が使用されます (通常、この値は RouterListener から取得されます)。
b) If the argument in the controller is type-hinted with Symfony's
Request object, the Request is passed in as the value.
Request オブジェクト。theRequest が値として渡されます。
c) If the function or method argument is variadic and the Request
attributes bag contains an array for that argument, they will all be available through the variadic argument.
属性バッグにはその引数の配列が含まれており、それらはすべて可変引数を介して使用できます。

This functionality is provided by resolvers implementing the ArgumentValueResolverInterface. There are four implementations which provide the default behavior of Symfony but customization is the key here. By implementing the ArgumentValueResolverInterface yourself and passing this to the ArgumentResolver, you can extend this functionality.

この機能は、ArgumentValueResolverInterface を実装するリゾルバーによって提供されます。Symfony のデフォルトの動作を提供する 4 つの実装がありますが、ここではカスタマイズが重要です。 ArgumentValueResolverInterface を自分で実装し、これを ArgumentResolver に渡すことで、この機能を拡張できます。

5) Calling the Controller

The next step of HttpKernel::handle() is executing the controller.

HttpKernel::handle() の次のステップは、コントローラーの実行です。

The job of the controller is to build the response for the given resource. This could be an HTML page, a JSON string or anything else. Unlike every other part of the process so far, this step is implemented by the "end-developer", for each page that is built.

コントローラーの仕事は、指定されたリソースの応答を作成することです。これは、HTML ページ、JSON 文字列、またはその他のものである可能性があります。これまでのプロセスの他のすべての部分とは異なり、このステップは、作成されるページごとに「最終開発者」によって実装されます。

Usually, the controller will return a Response object. If this is true, then the work of the kernel is just about done! In this case, the next step is the kernel.response event.

通常、コントローラは Response オブジェクトを返します。これが正しい場合、カーネルの作業はほぼ完了です!この場合、次のステップは kernel.response イベントです。

But if the controller returns anything besides a Response, then the kernel has a little bit more work to do - kernel.view (since the end goal is always to generate a Response object).

しかし、コントローラーが応答以外の何かを返す場合、カーネルはもう少し作業を行う必要があります - kernel.view (最終目標は常に応答オブジェクトを生成することであるため)。

Note

ノート

A controller must return something. If a controller returns null, an exception will be thrown immediately.

コントローラーは何かを返さなければなりません。コントローラーが null を返すと、すぐに例外がスローされます。

6) The kernel.view Event

Typical Purposes: Transform a non-Response return value from a controller into a Response

典型的な目的: コントローラからのレスポンス以外の戻り値をレスポンスに変換する

Kernel Events Information Table

カーネル イベント情報テーブル

If the controller doesn't return a Response object, then the kernel dispatches another event - kernel.view. The job of a listener to this event is to use the return value of the controller (e.g. an array of data or an object) to create a Response.

コントローラーが Response オブジェクトを返さない場合、カーネルは別のイベント (kernel.view) を送出します。このイベントに対するリスナーの仕事は、コントローラーの戻り値 (データの配列やオブジェクトなど) を使用してレスポンスを作成することです。

This can be useful if you want to use a "view" layer: instead of returning a Response from the controller, you return data that represents the page. A listener to this event could then use this data to create a Response that is in the correct format (e.g HTML, JSON, etc).

これは、「ビュー」レイヤーを使用する場合に便利です。コントローラーから応答を返す代わりに、ページを表すデータを返します。このイベントのリスナーは、このデータを使用して正しい形式の応答を作成できます。 (例: HTML、JSON など)。

At this stage, if no listener sets a response on the event, then an exception is thrown: either the controller or one of the view listeners must always return a Response.

この段階で、イベントに応答を設定するリスナーがない場合は、例外がスローされます。コントローラーまたはビュー リスナーのいずれかが常に応答を返す必要があります。

Note

ノート

When setting a response for the kernel.view event, the propagation is stopped. This means listeners with lower priority won't be executed.

kernel.view イベントの応答を設定すると、伝播が停止します。これは、優先度の低いリスナーが実行されないことを意味します。
Symfony フレームワークの kernel.view

There is a default listener inside the Symfony Framework for the kernel.view event. If your controller action returns an array, and you apply the #[Template()] attribute to that controller action, then this listener renders a template, passes the array you returned from your controller to that template, and creates a Response containing the returned content from that template.

Symfony フレームワーク内には、kernel.viewevent 用のデフォルトのリスナーがあります。コントローラー アクションが配列を返し、#[Template()] 属性をそのコントローラー アクションに適用する場合、このリスナーはテンプレートをレンダリングし、コントローラーから返された配列をそのテンプレートに渡し、そのテンプレートから返されたコンテンツを含む Response を作成します。テンプレート。

Additionally, a popular community bundle FOSRestBundle implements a listener on this event which aims to give you a robust view layer capable of using a single controller to return many different content-type responses (e.g. HTML, JSON, XML, etc).

さらに、人気のあるコミュニティ バンドル FOSRestBundle は、このイベントにリスナーを実装します。これは、単一のコントローラーを使用して多くの異なるコンテンツ タイプの応答 (HTML、JSON、XML など) を返すことができる堅牢なビュー レイヤーを提供することを目的としています。

7) The kernel.response Event

Typical Purposes: Modify the Response object just before it is sent

一般的な目的: 送信直前に Response オブジェクトを変更する

Kernel Events Information Table

カーネル イベント情報テーブル

The end goal of the kernel is to transform a Request into a Response. The Response might be created during the kernel.request event, returned from the controller, or returned by one of the listeners to the kernel.view event.

カーネルの最終目標は、リクエストをレスポンスに変換することです。 TheResponse は、kernel.request イベント中に作成されるか、コントローラーから返されるか、リスナーの 1 つによって kernel.viewevent に返されます。

Regardless of who creates the Response, another event - kernel.response is dispatched directly afterwards. A typical listener to this event will modify the Response object in some way, such as modifying headers, adding cookies, or even changing the content of the Response itself (e.g. injecting some JavaScript before the end </body> tag of an HTML response).

誰がレスポンスを作成したかに関係なく、別のイベント - kernel.responseis が直後にディスパッチされます。このイベントの一般的なリスナーは、ヘッダーの変更、Cookie の追加、または Response 自体のコンテンツの変更 (HTML 応答の終了タグの前に JavaScript を挿入するなど) など、何らかの方法で Response オブジェクトを変更します。

After this event is dispatched, the final Response object is returned from handle(). In the most typical use-case, you can then call the send() method, which sends the headers and prints the Response content.

このイベントが送出された後、最後の Response オブジェクトが handle() から返されます。最も典型的な使用例では、send() メソッドを呼び出して、ヘッダーを送信し、応答コンテンツを出力できます。
Symfony フレームワークの kernel.response

There are several minor listeners on this event inside the Symfony Framework, and most modify the response in some way. For example, the WebDebugToolbarListener injects some JavaScript at the bottom of your page in the dev environment which causes the web debug toolbar to be displayed. Another listener, ContextListener serializes the current user's information into the session so that it can be reloaded on the next request.

Symfony フレームワーク内のこのイベントにはいくつかのマイナー リスナーがあり、ほとんどが何らかの方法で応答を変更します。たとえば、WebDebugToolbarListener は、開発環境のページの下部に JavaScript を挿入します。これにより、Web デバッグ ツールバーが表示されます。別のリスナーである ContextListener は、現在のユーザーの情報をセッションにシリアル化し、次のリクエストで再読み込みできるようにします。

8) The kernel.terminate Event

Typical Purposes: To perform some "heavy" action after the response has been streamed to the user

一般的な目的: 応答がユーザーにストリーミングされた後に、何らかの「重い」アクションを実行するため

Kernel Events Information Table

カーネル イベント情報テーブル

The final event of the HttpKernel process is kernel.terminate and is unique because it occurs after the HttpKernel::handle() method, and after the response is sent to the user. Recall from above, then the code that uses the kernel, ends like this:

HttpKernel プロセスの最後のイベントは kernel.terminate であり、HttpKernel::handle() メソッドの後、応答がユーザーに送信された後に発生するため、一意です。上記を思い出してください。カーネルを使用するコードは、次のように終了します。
1
2
3
4
5
// sends the headers and echoes the content
$response->send();

// triggers the kernel.terminate event
$kernel->terminate($request, $response);

As you can see, by calling $kernel->terminate after sending the response, you will trigger the kernel.terminate event where you can perform certain actions that you may have delayed in order to return the response as quickly as possible to the client (e.g. sending emails).

ご覧のように、応答を送信した後に $kernel->terminate を呼び出すと、kernel.terminate イベントがトリガーされ、応答をできるだけ早くクライアントに返すために遅延した可能性のある特定のアクションを実行できます (例:メール)。

Caution

注意

Internally, the HttpKernel makes use of the fastcgi_finish_request PHP function. This means that at the moment, only the PHP FPM server API is able to send a response to the client while the server's PHP process still performs some tasks. With all other server APIs, listeners to kernel.terminate are still executed, but the response is not sent to the client until they are all completed.

内部的には、HttpKernel は fastcgi_finish_requestPHP 関数を利用します。これは、現時点では、サーバーの PHP プロセスがまだいくつかのタスクを実行している間、PHP FPM サーバー API のみがクライアントに応答を送信できることを意味します。他のすべてのサーバー API では、kernel.terminate へのリスナーは引き続き実行されますが、応答はすべて完了するまでクライアントに送信されません。

Note

ノート

Using the kernel.terminate event is optional, and should only be called if your kernel implements TerminableInterface.

kernel.terminate イベントの使用はオプションであり、カーネルが TerminableInterface を実装している場合にのみ呼び出す必要があります。

Handling Exceptions: the kernel.exception Event

Typical Purposes: Handle some type of exception and create an appropriate Response to return for the exception

典型的な目的: 何らかのタイプの例外を処理し、例外に対して返す適切なResponseを作成します

Kernel Events Information Table

カーネル イベント情報テーブル

If an exception is thrown at any point inside HttpKernel::handle(), another event - kernel.exception is dispatched. Internally, the body of the handle() method is wrapped in a try-catch block. When any exception is thrown, the kernel.exception event is dispatched so that your system can somehow respond to the exception.

HttpKernel::handle() 内の任意の時点で例外がスローされると、anotherevent - kernel.exception が送出されます。内部的には、handle() メソッドの本体は try-catch ブロックでラップされています。例外がスローされると、kernel.exception イベントが送出され、システムが例外に何らかの形で応答できるようになります。

Each listener to this event is passed a ExceptionEvent object, which you can use to access the original exception via the getThrowable() method. A typical listener on this event will check for a certain type of exception and create an appropriate error Response.

このイベントの各リスナーには、getThrowable() メソッドを介して元の例外にアクセスするために使用できる ExceptionEvent オブジェクトが渡されます。このイベントの一般的なリスナーは、特定のタイプの例外をチェックし、適切なエラー応答を作成します。

For example, to generate a 404 page, you might throw a special type of exception and then add a listener on this event that looks for this exception and creates and returns a 404 Response. In fact, the HttpKernel component comes with an ErrorListener, which if you choose to use, will do this and more by default (see the sidebar below for more details).

たとえば、404 ページを生成するには、特殊なタイプの例外をスローし、この例外を探して 404 応答を作成して返すリスナーをこのイベントに追加します。実際、HttpKernel コンポーネントには ErrorListener が付属しており、これを使用することを選択した場合、デフォルトでこれ以上のことが行われます (詳細については、以下のサイドバーを参照してください)。

Note

ノート

When setting a response for the kernel.exception event, the propagation is stopped. This means listeners with lower priority won't be executed.

kernel.exception イベントの応答を設定すると、伝播が停止します。これは、優先度の低いリスナーが実行されないことを意味します。
Symfony フレームワークの kernel.exception

There are two main listeners to kernel.exception when using the Symfony Framework.

Symfony フレームワークを使用する場合、kernel.exception には 2 つの主要なリスナーがあります。

ErrorListener in the HttpKernel Component

HttpKernel コンポーネントの ErrorListener

The first comes core to the HttpKernel component and is called ErrorListener. The listener has several goals:

1 つ目は HttpKernel コンポーネントのコアであり、ErrorListener と呼ばれます。リスナーにはいくつかの目標があります。
  1. The thrown exception is converted into a FlattenException object, which contains all the information about the request, but which can be printed and serialized.
    スローされた例外は、リクエストに関するすべての情報を含む FlattenException オブジェクトに変換されますが、出力およびシリアル化が可能です。
  2. If the original exception implements HttpExceptionInterface, then getStatusCode() and getHeaders() are called on the exception and used to populate the headers and status code of the FlattenException object. The idea is that these are used in the next step when creating the final response. If you want to set custom HTTP headers, you can always use the setHeaders() method on exceptions derived from the HttpException class.
    元の例外が HttpExceptionInterface を実装している場合、例外で getStatusCode() と getHeaders() が呼び出され、FlattenException オブジェクトのヘッダーとステータス コードを設定するために使用されます。これらは、最終的な応答を作成する次のステップで使用されるという考えです。カスタム HTTP ヘッダーを設定する場合は、HttpException クラスから派生した例外に対して常に setHeaders() メソッドを使用できます。
  3. If the original exception implements RequestExceptionInterface, then the status code of the FlattenException object is populated with 400 and no other headers are modified.
    元の例外が RequestExceptionInterface を実装している場合、FlattenException オブジェクトのステータス コードには 400 が入力され、他のヘッダーは変更されません。
  4. A controller is executed and passed the flattened exception. The exact controller to render is passed as a constructor argument to this listener. This controller will return the final Response for this error page.
    コントローラーが実行され、フラット化された例外が渡されます。レンダリングする正確なコントローラーは、コンストラクター引数としてこのリスナーに渡されます。このコントローラーは、このエラー ページの最終的な応答を返します。

ExceptionListener in the Security Component

セキュリティ コンポーネントの ExceptionListener

The other important listener is the ExceptionListener. The goal of this listener is to handle security exceptions and, when appropriate, help the user to authenticate (e.g. redirect to the login page).

もう 1 つの重要なリスナーは ExceptionListener です。このリスナーの目的は、セキュリティ例外を処理し、必要に応じてユーザーの認証を支援することです (例: ログインページへのリダイレクト)。

Creating an Event Listener

As you've seen, you can create and attach event listeners to any of the events dispatched during the HttpKernel::handle() cycle. Typically a listener is a PHP class with a method that's executed, but it can be anything. For more information on creating and attaching event listeners, see The EventDispatcher Component.

これまで見てきたように、イベント リスナーを作成して、HttpKernel::handle() サイクル中にディスパッチされた任意のイベントにアタッチできます。通常、リスナーはメソッドが実行される PHPclass ですが、何でもかまいません。イベント リスナーの作成とアタッチの詳細については、「EventDispatcher コンポーネント」を参照してください。

The name of each of the "kernel" events is defined as a constant on the KernelEvents class. Additionally, each event listener is passed a single argument, which is some subclass of KernelEvent. This object contains information about the current state of the system and each event has their own event object:

各「カーネル」イベントの名前は、KernelEvents クラスで定数として定義されます。さらに、各イベント リスナーには、KernelEvent のサブクラスである単一の引数が渡されます。このオブジェクトには、システムの現在の状態に関する情報が含まれており、各イベントには独自のイベント オブジェクトがあります。
Name KernelEvents Constant Argument passed to the listener
kernel.request KernelEvents::REQUEST RequestEvent
kernel.controller KernelEvents::CONTROLLER ControllerEvent
kernel.controller_arguments KernelEvents::CONTROLLER_ARGUMENTS ControllerArgumentsEvent
kernel.view KernelEvents::VIEW ViewEvent
kernel.response KernelEvents::RESPONSE ResponseEvent
kernel.finish_request KernelEvents::FINISH_REQUEST FinishRequestEvent
kernel.terminate KernelEvents::TERMINATE TerminateEvent
kernel.exception KernelEvents::EXCEPTION ExceptionEvent

A full Working Example

When using the HttpKernel component, you're free to attach any listeners to the core events, use any controller resolver that implements the ControllerResolverInterface and use any argument resolver that implements the ArgumentResolverInterface. However, the HttpKernel component comes with some built-in listeners and everything else that can be used to create a working example:

HttpKernel コンポーネントを使用する場合、任意のリスナーをコア イベントに自由にアタッチし、ControllerResolverInterface を実装する任意のコントローラー リゾルバーを使用し、ArgumentResolverInterface を実装する任意の引数リゾルバーを使用できます。実際の例を作成するために使用されます:
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
30
31
32
33
34
35
36
37
38
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

$routes = new RouteCollection();
$routes->add('hello', new Route('/hello/{name}', [
    '_controller' => function (Request $request) {
        return new Response(
            sprintf("Hello %s", $request->get('name'))
        );
    }]
));

$request = Request::createFromGlobals();

$matcher = new UrlMatcher($routes, new RequestContext());

$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack()));

$controllerResolver = new ControllerResolver();
$argumentResolver = new ArgumentResolver();

$kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver);

$response = $kernel->handle($request);
$response->send();

$kernel->terminate($request, $response);

Sub Requests

In addition to the "main" request that's sent into HttpKernel::handle(), you can also send a so-called "sub request". A sub request looks and acts like any other request, but typically serves to render just one small portion of a page instead of a full page. You'll most commonly make sub-requests from your controller (or perhaps from inside a template, that's being rendered by your controller).

HttpKernel::handle() に送信される「メイン」リクエストに加えて、いわゆる「サブ リクエスト」を送信することもできます。サブ リクエストは、他のリクエストと同じように見え、動作しますが、通常、ページ全体ではなく、ページの小さな部分のみをレンダリングする役割を果たします。ほとんどの場合、コントローラーから (または、コントローラーによってレンダリングされているテンプレート内から) サブリクエストを作成します。

To execute a sub request, use HttpKernel::handle(), but change the second argument as follows:

サブリクエストを実行するには、HttpKernel::handle() を使用しますが、2 番目の引数を次のように変更します。
1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;

// ...

// create some other request manually as needed
$request = new Request();
// for example, possibly set its _controller manually
$request->attributes->set('_controller', '...');

$response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
// do something with this response

This creates another full request-response cycle where this new Request is transformed into a Response. The only difference internally is that some listeners (e.g. security) may only act upon the main request. Each listener is passed some subclass of KernelEvent, whose isMainRequest() method can be used to check if the current request is a "main" or "sub" request.

これにより、この新しい要求が応答に変換される別の完全な要求応答サイクルが作成されます。内部での唯一の違いは、一部のリスナー (セキュリティなど) がメインの要求に対してのみ動作する可能性があることです。各リスナーには KernelEvent のサブクラスが渡され、その isMainRequest() メソッドを使用して、現在のリクエストが「メイン」リクエストか「サブ」リクエストかを確認できます。

For example, a listener that only needs to act on the main request may look like this:

たとえば、メインのリクエストに対してのみ動作する必要があるリスナーは次のようになります。
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\HttpKernel\Event\RequestEvent;
// ...

public function onKernelRequest(RequestEvent $event)
{
    if (!$event->isMainRequest()) {
        return;
    }

    // ...
}

Locating Resources

The HttpKernel component is responsible of the bundle mechanism used in Symfony applications. The key feature of the bundles is that they allow to override any resource used by the application (config files, templates, controllers, translation files, etc.)

HttpKernel コンポーネントは、Symfony アプリケーションで使用されるバンドル メカニズムを担当します。バンドルの重要な機能は、アプリケーションが使用するリソース (構成ファイル、テンプレート、コントローラー、翻訳ファイルなど) をオーバーライドできることです。

This overriding mechanism works because resources are referenced not by their physical path but by their logical path. For example, the services.xml file stored in the Resources/config/ directory of a bundle called FooBundle is referenced as @FooBundle/Resources/config/services.xml. This logical path will work when the application overrides that file and even if you change the directory of FooBundle.

リソースは物理パスではなく論理パスによって参照されるため、このオーバーライド メカニズムは機能します。たとえば、FooBundle というバンドルの Resources/config/ ディレクトリに保存されている services.xml ファイルは、@FooBundle/Resources/config/services.xml として参照されます。この論理パスは、アプリケーションがそのファイルをオーバーライドする場合や、FooBundle のディレクトリを変更した場合でも機能します。

The HttpKernel component provides a method called locateResource() which can be used to transform logical paths into physical paths:

HttpKernel コンポーネントは、論理パスを物理パスに変換するために使用できる、locateResource() と呼ばれるメソッドを提供します。
1
$path = $kernel->locateResource('@FooBundle/Resources/config/services.xml');

Learn more