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:

SyntaxSQL
'age[>]' => 18age > 18
'age[>=]' => 18age >= 18
'age[<]' => 65age < 65
'age[<=]' => 65age <= 65
'age[!]' => 0age != 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

SyntaxMeaning
'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:

KeyExample
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.