Package · cdo

Qb operators

The complete Qb operator set. Every method is a static factory returning an immutable Qb; every value argument accepts a raw scalar or a CDOBind. Auto-generated placeholders are named :iqb0, :iqb1, … in creation order.

Column names must be trusted identifiers

Only values are parameterised. The $col argument of every method is interpolated into the SQL verbatim, without quoting or escaping — as is the raw fragment of raw() and the WHEN conditions of case(). Never pass user input as a column name: Qb::eq('status', $userInput) is safe, Qb::eq($userInput, 'active') is a SQL-injection vector.

Reading the fragment

Two accessors give you the pieces:

Method Returns
getQuery() the SQL fragment string, e.g. status = :iqb0
getBinds() CDOBind[] — one per placeholder
getData() ['query' => string, 'binds' => CDOBind[]]

Comparison

Method SQL Value types
eq($col, $v) col = :v `CDOBind\
neq($col, $v) col != :v `CDOBind\
gt($col, $v) col > :v `CDOBind\
gte($col, $v) col >= :v `CDOBind\
lt($col, $v) col < :v `CDOBind\
lte($col, $v) col <= :v `CDOBind\
nsEq($col, $v) col <=> :v `CDOBind\

eq and neq have special cases for non-scalar values:

Value eq produces neq produces
null col IS NULL col IS NOT NULL
true col IS TRUE col IS NOT TRUE
false col IS FALSE col IS NOT FALSE

nsEq is MySQL/MariaDB syntax

<=> (NULL-safe equal) is native to MySQL/MariaDB. The PostgreSQL / standard-SQL equivalent is IS NOT DISTINCT FROM — write it with raw there.

NULL checks

Method SQL
isNull($col) col IS NULL
isNotNull($col) col IS NOT NULL

Set membership

Method SQL
in($col, $values) col IN (:a, :b, …)
notIn($col, $values) col NOT IN (:a, :b, …)

Empty arrays throw

in() and notIn() throw InvalidArgumentException on an empty array. Filter empty lists out of dynamic filters before calling — e.g. $ids ? Qb::in('id', $ids) : null inside an and().

Pattern matching

Method SQL $insensitive = true
like($col, $v, $insensitive = false) col LIKE :v col ILIKE :v (PostgreSQL)
notLike($col, $v, $insensitive = false) col NOT LIKE :v col NOT ILIKE :v (PostgreSQL)

Include the % / _ wildcards in the value yourself. On MySQL LIKE is already case-insensitive for non-binary columns — do not set $insensitive. Oracle has no ILIKE; use REGEXP_LIKE(col, val, 'i') via raw.

Range

Method SQL
between($col, $min, $max) col BETWEEN :min AND :max
notBetween($col, $min, $max) col NOT BETWEEN :min AND :max
betweenBy($v, $col1, $col2) :v BETWEEN col1 AND col2
notBetweenBy($v, $col1, $col2) :v NOT BETWEEN col1 AND col2

The *By variants invert the shape: a scalar value tested against two columns (e.g. a date inside a per-row validity window). Both bounds are inclusive.

Logical & grouping

Method SQL Notes
and(...$conds) a AND b AND … skips null / empty conditions
or(...$conds) a OR b OR … skips null / empty conditions
xor(...$conds) a XOR b XOR … native on MySQL/MariaDB
clip($cond) (cond) wraps in parentheses; empty passed through

Mutable builders

These mutate the instance in place (no return value) instead of composing a new one — useful for accumulating in a loop:

Method Effect
addAnd($qb) append AND $qb
addOr($qb) append OR $qb
addXor($qb) append XOR $qb

CASE

php
Qb::case([
  'score >= 90' => 'A',
  'score >= 75' => 'B',
  'score >= 60' => 'C',
], else: 'F');
// CASE WHEN score >= 90 THEN :iqb0
//      WHEN score >= 75 THEN :iqb1
//      WHEN score >= 60 THEN :iqb2
//      ELSE :iqb3 END

Keys are raw SQL conditions (not bound); values (and else) are the result literals and are bound.

raw

php
Qb::raw(string $query, array $binds = []): Qb

Injects $query verbatim, optionally with binds. $binds accepts CDOBind objects and/or name => value pairs (the leading : is optional):

php
Qb::raw('JSON_CONTAINS(tags, :tag)', ['tag' => '"php"']);
Qb::raw('views > :v', [new CDOBind('v', 100)]);

raw is not sanitised

The query string is emitted as-is. Never interpolate user input into it — bind values through $binds. Qb::custom() is a deprecated alias for raw.

empty

php
Qb::empty(): Qb

A no-op fragment ('' with no binds). Silently ignored by and / or / xor and the add* methods — useful as a neutral default.