DoctrineのandWhereとorWhereの使用例[Symfony]

SymfonyとDoctrineの記事になります。
私の環境の各バージョンは次の通りです。
Symfony 3.4
Doctrine 2.12
今回はORMで記述しているときに、下記のようなWhere文のSQLはどのように書くのか?

WHERE foo = 1 AND (bar = 1 OR bar = 2)

そしてORの値やネストされる数をPHPで可変にしたいという場合も合わせて解説してみたいと思います。

あらかじめ条件が決まっている場合

$q->where("foo = 1")
  ->andWhere("bar = 1 OR bar = 2");

こちらは単純で、andWhereの中で、OR文にしてあげればよいです。

OR文の条件を変数や配列から受け取り指定したい

単純にif文を使ってorWhereを追加しても、想定したSQLにはなりません。
このような場合、Expr Classを使用して記述します。
参考 : Expr Class
詳細は上記をご覧ください。今回はeqを使ってみます。

$qb->where('foo = 1')
   ->andWhere($qb->expr()->orX(
      $qb->expr()->eq('bar', 1),
      $qb->expr()->eq('bar', 2)
   ));

最初の例をexpr classを使用して記述すると上記のようになります。
今度は上記例に対して、条件部分を配列から取得してみたいと思います。

// tagList is array
$q->where("foo = 1");
$statements = $qb->expr()->orX();
foreach ($taglist as $tag) {
    $statements->add(
        $qb->expr()->eq('bar', $tag['id'])
    );
}
$qb->andWhere($statements);

tagListという配列から、比較対象となる数値部分を変数として割り当ててみました。

まとめ

WHERE foo = 1 AND (bar = 1 OR bar = 2)

は結構単純な構造だと思うのですが、可変できるように記述すると結構面倒でした。
Expr Classは、他にも便利なclassが用意されているので、参照先をぜひご覧ください。

Symfonyおすすめ書籍

あまり種類がないのと、そもそもフレームワークとして情報が膨大なので、入門でも結構読み応えがあります。
「PHPフレームワーク Symfony 4入門」