Skip to content
Oleg Grigoriev edited this page Mar 27, 2016 · 2 revisions

Where

Здесь приводится формат для раздела WHERE, используемый в плейсхолдере ?w (?where), доступным с 2.0.3 и в другом функционале (например, в классе Table).

Массив условий столбец => значение, все из которых должны выполниться (AND).

$where = [
    'a' => 1,
    'b' => 2,
    'c' => 'string',
];

$pattern = 'SELECT * FROM `table` WHERE ?w';
$data = array($where);

$db($pattern, $data); // SELECT * FROM `table` WHERE `a`=1 AND `b`=2 AND `c`="string"

Обрабатывается также null и true (указывает, что столбец не может быть NULL):

$where = [
    'a' => 1,
    'b' => null,
    'c' => true,
];

// WHERE `a`=1 AND `b` IS NULL AND `c` IS NOT NULL

Порядковый массив указывает возможные значения для данного столбца:

$where = [
    'a' => 1,
    'b' => [1, 2, 3],
];

// WHERE `a`=1 AND `b` IN (1, 2, 3)

Пустой массив указывает на то, что для данного столбца нет разрешённых значений, что приводит к ложности всего условия (1=0).

1/0

Пустой массив приводится к 1 (выборка всех строк). Подразумевается, что $where, это нечто вроде фильтра, который может постепенно накапливаться в коде. Если ничего не накопилось, то и фильтровать не надо - возвращаем всё.

Если вместо $where передать FALSE - это приводится к 0. Любой другой скаляр, в том числе NULL - приводится к 1.

Расширенный формат

Значением, соответствующим определённому столбцу, может быть ассоциативным массив, с форматом аналогичным формату COL с дополнительным полем op (операция сравнения, по умолчанию =).

$where = [
    'id' => [
        'op' => '<',
        'value' => 1000,
    ],
    'value' => [
        'op' => '<>',
        'db' => 'd',
        'table' => 't',
        'col' => 'c',
        'value' => 3,
        'func' => 'FUNC',        
    ],
];
$pattern = 'SELECT * FROM `table` WHERE ?where';
$data = [$where];
SELECT * FROM `table` WHERE `id`<1000 AND `value`<>FUNC(`d`.`t`.`c`)+3

Совсем-совсем расширенный

Следующий формат может быть полезным, но лучше им не злоупотреблять, а то получится какой-нибудь query-builder.

$where = [
    'group_or' => [
        'sep' => 'OR',
        'group' => [
            'x' => 1,
            'and' => [
                'group' => [
                    'x' => 5,
                    'y' => [
                        'op' => '>',
                        'table' => 't',
                        'col' => 'col',
                        'value' => -4,
                    ],
                ],
            ],
            'y' => [1, 2],
        ],
    ],
    'x' => 10,
];
$pattern = 'SELECT * FROM `t` WHERE ?where';
SELECT * FROM `t` WHERE (`x`=1 OR (`x`=5 AND `y`>`p_t`.`col`-4) OR `y` IN (1,2)) AND `x`=10

Если в качестве значения указан ассоциативный массив с полем group, то содержимое этого поля, рассматривается, как вложенное условие, разбирается по всем правилам отдельного WHERE и заключается в скобки. При этом с помощью поля sep можно указать разделитель (по умолчанию AND).

Ключ, соответствующий группе (group_or и and в примере) ни на что не влияет, но его следует придумать и проследить за тем, чтобы он был уникальным.