WHERE DSL Reference
Porm passes WHERE arrays to Piql, which implements a Medoo-compatible DSL. Use them in where(), filter(), all($where), get($where), aggregates, and Agg / Where builders.
Prefer the fluent where() syntax for readability: where('username', 'jet'), where('name', 'starts_with', 'Pi'), etc.
Equality (default)
['status' => 'active', 'role' => 'admin']
// status = 'active' AND role = 'admin'
Comparison operators
Prefix the column with the operator:
| Syntax | SQL |
|---|---|
'age[>]' => 18 | age > 18 |
'age[>=]' => 18 | age >= 18 |
'age[<]' => 65 | age < 65 |
'age[<=]' => 65 | age <= 65 |
'age[!]' => 0 | age != 0 or IS NOT NULL |
'age[<>]' => [10, 20] | BETWEEN 10 AND 20 |
'age[><]' => [10, 20] | NOT BETWEEN |
table('users')->filter(['age[>]' => 18, 'score[<=]' => 100])->all();LIKE
| Syntax | Meaning |
|---|---|
'name[~]' => 'john' | LIKE '%john%' |
'name[!~]' => 'john' | NOT LIKE |
'name[~]' => ['john', 'jane'] | OR of LIKEs |
IN / NOT IN
['id' => [1, 2, 3]] // IN (1,2,3)
['status[!]' => ['banned']] // NOT IN
NULL
['deleted_at' => null] // IS NULL
['email[!]' => null] // IS NOT NULL
AND / OR groups
[
'AND' => [
'active' => 1,
'OR' => [
'role' => 'admin',
'role' => 'editor',
],
],
]Top-level keys in a flat array are AND-ed. Use explicit AND / OR keys for nesting.
ORDER, LIMIT, GROUP, HAVING
On a Builder chain, prefer fluent methods. In raw WHERE arrays:
| Key | Example |
|---|---|
ORDER | ['ORDER' => ['date' => 'DESC']] |
LIMIT | ['LIMIT' => 10] or ['LIMIT' => [20, 10]] (offset, limit) |
GROUP | ['GROUP' => 'user_id'] |
HAVING | ['HAVING' => ['count[>]' => 5]] |
startAt($offset) on the Builder requires a prior limit() call — it maps to LIMIT [$offset, $limit].
FULLTEXT — match()
On the Builder:
table('articles')
->filter()
->match('title,body', 'pionia framework', 'natural')
->all();Adds a MATCH … AGAINST style clause (driver-dependent).
Column aliases & casts
Select with alias: 'column(alias)' in columns().
Cast on read: suffix [Int], [Bool], [Number], [String], [JSON], [Object]:
table('meta')->columns(['payload[JSON]'])->get(1);[Object] uses PHP unserialize() — only use with trusted database content.
Programmatic builders
Where builder
use Pionia\Porm\Database\Builders\Where;
$clause = Where::builder()
->and(['age[>]' => 18])
->or(['role' => 'admin'])
->build();
table('users')->filter($clause)->all();Agg builder
For HAVING-style expressions, comparisons in WHERE, and computed columns — see Aggregation.
Raw fragments
use Pionia\Porm\Core\Piql;
table('orders')->filter([
'created_at[>]' => Piql::raw('DATE_SUB(NOW(), INTERVAL 7 DAY)'),
])->all();See also Transactions & raw SQL.