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
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 ENDKeys are raw SQL conditions (not bound); values (and else) are the result
literals and are bound.
raw
Qb::raw(string $query, array $binds = []): QbInjects $query verbatim, optionally with binds. $binds accepts CDOBind
objects and/or name => value pairs (the leading : is optional):
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
Qb::empty(): QbA no-op fragment ('' with no binds). Silently ignored by and / or / xor
and the add* methods — useful as a neutral default.
Related
- Building conditions — composition patterns
- Configuration —
CDOBindnamed binds - CDO API — methods that consume a
Qb