31. Filters

Doctrine ORM features a filter system that allows the developer to add SQL to the conditional clauses of queries, regardless the place where the SQL is generated (e.g. from a DQL query, or by loading associated entities).

Doctrine ORM は、SQL が生成される場所 (例えば、DQL クエリから、または関連付けられたエンティティをロードすることによって) に関係なく、開発者がクエリの条件句に SQL を追加できるようにするフィルター システムを備えています。

The filter functionality works on SQL level. Whether a SQL query is generated in a Persister, during lazy loading, in extra lazy collections or from DQL. Each time the system iterates over all the enabled filters, adding a new SQL part as a filter returns.

フィルター機能は SQL レベルで機能します。 SQL クエリが Persister で生成されるか、遅延読み込み中、余分な遅延コレクションで生成されるか、または DQL から生成されるか。

By adding SQL to the conditional clauses of queries, the filter system filters out rows belonging to the entities at the level of the SQL result set. This means that the filtered entities are never hydrated (which can be expensive).

クエリの条件節に SQL を追加することにより、フィルター システムは、エンティティーに属する行を SQL 結果セットのレベルで除外します。これは、フィルタリングされたエンティティが決して水和されないことを意味します (これは高価になる可能性があります)。

31.1. Example filter class

Throughout this document the example MyLocaleFilter class will be used to illustrate how the filter feature works. A filter class must extend the base Doctrine\ORM\Query\Filter\SQLFilter class and implement the addFilterConstraint method. The method receives the ClassMetadata of the filtered entity and the table alias of the SQL table of the entity.

このドキュメントでは、サンプル MyLocaleFilter クラスを使用して、フィルター機能がどのように機能するかを示します。フィルター クラスは、baseDoctrine\ORM\Query\Filter\SQLFilter クラスを拡張し、addFilterConstraint メソッドを実装する必要があります。このメソッドは、フィルタリングされたエンティティの ClassMetadata とエンティティの SQL テーブルのテーブル エイリアスを受け取ります。

Note

ノート

In the case of joined or single table inheritance, you always get passed the ClassMetadata of the inheritance root. This is necessary to avoid edge cases that would break the SQL when applying the filters.

結合または単一テーブルの継承の場合、常に継承ルートの ClassMetadata が渡されます。これは、フィルターを適用するときに SQL を壊すような極端なケースを避けるために必要です。

For the filter to correctly function, the following rules must be followed. Failure to do so will lead to unexpected results from the query cache.
  1. Parameters for the query should be set on the filter object by SQLFilter#setParameter() before the filter is used by the ORM ( i.e. do not set parameters inside SQLFilter#addFilterConstraint() function ).

    クエリのパラメーターは、フィルターが ORM によって使用される前に、SQLFilter#setParameter() によってフィルター オブジェクトに設定する必要があります (つまり、SQLFilter#addFilterConstraint() 関数内でパラメーターを設定しないでください)。

  2. The filter must be deterministic. Don’t change the values base on external inputs.

    フィルターは確定的でなければなりません。外部入力に基づいて値を変更しないでください。

The SQLFilter#getParameter() function takes care of the proper quoting of parameters.

SQLFilter#getParameter() 関数は、パラメーターの適切な引用符を処理します。

<?php
namespace Example;
use Doctrine\ORM\Mapping\ClassMetadata,
    Doctrine\ORM\Query\Filter\SQLFilter;

class MyLocaleFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        // Check if the entity implements the LocalAware interface
        if (!$targetEntity->reflClass->implementsInterface('LocaleAware')) {
            return "";
        }

        return $targetTableAlias.'.locale = ' . $this->getParameter('locale'); // getParameter applies quoting automatically
    }
}

If the parameter is an array and should be quoted as a list of values for an IN query this is possible with the alternative SQLFilter#setParameterList() and SQLFilter#getParameterList() functions.

パラメータが配列であり、IN クエリの値のリストとして引用する必要がある場合、これは代替の SQLFilter#setParameterList() および SQLFilter#getParameterList() 関数で可能です。

31.2. Configuration

Filter classes are added to the configuration as following:

フィルター クラスは、次のように構成に追加されます。

<?php
$config->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");

The Configuration#addFilter() method takes a name for the filter and the name of the class responsible for the actual filtering.

Configuration#addFilter() メソッドは、フィルタの名前と、実際のフィルタリングを担当するクラスの名前を受け取ります。

31.3. Disabling/Enabling Filters and Setting Parameters

Filters can be disabled and enabled via the FilterCollection which is stored in the EntityManager. The FilterCollection#enable($name) method will retrieve the filter object. You can set the filter parameters on that object.

フィルターは、EntityManager に格納されている FilterCollection を介して無効化および有効化できます。 FilterCollection#enable($name) メソッドは、フィルター オブジェクトを取得します。そのオブジェクトにフィルタ パラメータを設定できます。

<?php
$filter = $em->getFilters()->enable("locale");
$filter->setParameter('locale', 'en');

// Disable it
$filter = $em->getFilters()->disable("locale");

Warning

警告

Disabling and enabling filters has no effect on managed entities. If you want to refresh or reload an object after having modified a filter or the FilterCollection, then you should clear the EntityManager and re-fetch your entities, having the new rules for filtering applied.

フィルターを無効化および有効化しても、管理対象エンティティには影響しません。フィルタまたは FilterCollection を変更した後でオブジェクトを更新または再ロードする場合は、EntityManager をクリアしてエンティティを再フェッチし、フィルタリングの新しいルールを適用する必要があります。

Table Of Contents

Previous topic

29. Limitations and Known Issues

29. 制限事項と既知の問題

Next topic

32. Implementing a NamingStrategy

32. NamingStrategy の実装

This Page

Fork me on GitHub