我有以下功能:
public function latestNews($tags = array(), $categories = array(), $authors = array(), $lang = 'en', $source = '', $limit = 20) {
return $this->createQueryBuilder('News')
->field('tags')->in($tags)
->field('categories')->in($category)
->field('authors')->in($authors)
->field('lang')->equals($lang)
->sort('date' -> 'DESC')
->field('source')->equals($source)
->limit($limit)
->getQuery()
->execute();
}
我想如果函数调用者提供的变量$tags
,$categories
,$authors
或$source
这些变量会影响createQueryBuilder
,但如果每个变量都有效它们不是由函数调用者(具有默认值的变量)提供的,它们不会影响createQueryBuilder并使这个条件在查询中保持中立。
一种方法是我用许多if条件进行查询,但它非常混乱。
有没有更好的解决方案?
答案 0 :(得分:3)
这样的事情可以解决问题:
public function latestNews($tags = array(), $categories = array(), authors = array(), $lang = 'en', $source = '', $limit = 20) {
$inClauses = ['tags', 'categories', 'authors'];
$equalClauses = ['lang', 'source'];
$qb = $this->createQueryBuilder('News');
foreach ($inClauses as $field) {
$realVar = ${$field};
if (!empty($realVar)) {
$qb->field($field)->in($realVar);
}
}
foreach ($equalClauses as $field) {
$realVar = ${$field};
if ($realVar) {
$qb->field($field)->equals($realVar);
}
}
return $qb
->sort('date' -> 'DESC')
->limit($limit)
->getQuery()
->execute();
}
有点难看,但我没有看到更好的选择。
答案 1 :(得分:1)
chalasr的反应很好,但我建议将构建条件的逻辑提取到特定的特征,这样就可以避免代码重复(DRY)。
您可以执行以下操作:
<?php
namespace Xthiago\My\Path;
use \Doctrine\DBAL\Query\QueryBuilder;
trait DoctrineQueryHelper
{
public function in(QueryBuilder $qb, array $filter, $field)
{
if (empty($filter[$field])) {
return $this;
}
$qb->field($field)->in($filter[$field]);
return $this;
}
public function equals(QueryBuilder $qb, array $filter, $field)
{
if (empty($filter[$field])) {
return $this;
}
$qb->field($field)->equals($filter[$field]);
return $this;
}
public function lang(QueryBuilder $qb, $value = 'en')
{
$qb->field('lang')->equals($value);
return $this;
}
public function limit(QueryBuilder $qb, $value = 20)
{
$qb->limit($value);
return $this;
}
// you can create a lot of helper methods here in order to avoid duplicity.
}
然后你的班级以这种方式利用这个特性:
<?php
namespace Xthiago\My\Path;
use \Doctrine\DBAL\Query\QueryBuilder;
class NewsRepository
{
use DoctrineQueryHelper;
/**
* @param array $filter as follow:
* <code>
* [
* 'tags' => [],
* 'categories' => [],
* 'authors' => [],
* 'lang' => 'en',
* 'source' => '',
* 'limit' => 20,
* ]
* </code>
*
* @return array with results.
*/
public function latestNews(array $filter = [])
{
$qb = $this->createQueryBuilder('News');
$this->in($qb, $filter, 'tags')
->in($qb, $filter, 'categories')
->in($qb, $filter, 'authors')
->equals($qb, $filter, 'source')
->lang($qb, $filter)
->limit($qb, $filter);
return $qb->sort('date', 'DESC')
->getQuery()
->execute();
}
}