Как построить динамический c doctrine запрос? - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь создать динамический c doctrine запрос. Когда я пробую вот так, он работает

    $qb->andWhere($qb->expr()->orX(
        $qb->expr()->andX(
            $qb->expr()->eq('t.width', '245'),
            $qb->expr()->eq('t.height', '45'),
        ),
        $qb->expr()->andX(
            $qb->expr()->eq('t.width', '225'),
            $qb->expr()->eq('t.height', '65'),
        )
    ));

Но я передам ключ и значение из массива.

Мой массив выглядит так:

[
  0 => [
    "width" => "245"
    "height" => "45"
  ]
  1 => [
    "width" => "225"
    "height" => "65"
  ]
]

Теперь я попробовал следующий код.

    $conditions = $qb->expr()->orX(
        $qb->expr()->andX()
    );

    foreach ($wheres as $outerKey => $outerValue) {
        foreach ($outerValue as $innerKey => $innerValue) {
            $conditions->add("te.$innerKey = :innerValue");
            $qb->setParameter('innerValue', $innerValue);
        }
    }
    $qb->andWhere($conditions);

    dd($qb->getDQL());

Но возвращенный SQL не такой, как когда я пытался использовать значение stati c.

1 Ответ

0 голосов
/ 19 июня 2020

Так что вы можете сделать это двумя способами (которые я мог придумать). Во-первых, используя выражения, подобные тем, которые вы показали выше, но с дополнительной частной функцией:

private function getExpressions(QueryBuilder $qb, array $fields)
{
    $andX = $qb->expr()->andX();
    foreach ($fields as $field => $value) {
        $andX->add($qb->expr()->eq('t.' . $field, $value));
    }

    return $andX;
}

public function getDQL($conditions)
{
    $qb = $this->createQueryBuilder('t');

    $orX = $qb->expr()->orX();
    foreach ($conditions as $i => $fields) {
        $orX->add($this->getExpressions($qb, $fields));
    }
    $qb->add('where', $orX);

    dump($qb->getDQL());
    exit;
}

Мне потребовалось немного времени, чтобы понять это. На самом деле я сделал это намного быстрее способом, упомянутым выше (создание предложения where вручную):

$i = 0;
foreach ($conditions as $fields) {
    $j = 0;
    foreach ($fields as $field => $value){
        $whereStr .= " " . $field . " = " . $value;
        $j++;
        if ($j < count($fields)){
            $whereStr .= " AND";
        }
    }
    
    $i++;
    if ($i < count($conditions)){
        $whereStr .= " OR";
    }
}

Если я правильно понимаю ваш logi c, это должно сработать. Вы можете переключать выражения orX / иX, если я неправильно понял ваши требования.

...