-
Notifications
You must be signed in to change notification settings - Fork 0
Raw Queries
RawQuery is the explicit escape hatch for SQL fragments that should be
inlined verbatim — no identifier escaping, no parameter binding. Use it
where the fluent DSL does not (or should not) cover the case.
-
Database functions —
NOW(),CURRENT_TIMESTAMP,JSON_EXTRACT(…),INET_ATON(…), custom UDFs. -
Dialect-specific operators — PostgreSQL
~, SQLiteLIKE ESCAPE …, MySQLMATCH () AGAINST (). -
Inline sub-queries — a static SQL fragment you have hand-written
and want to embed without
subQuery()'s closure indirection. - Anything the builder doesn't expose directly — set-returning functions, window functions, lateral joins.
🚨 Never embed unsanitized user input.
RawQuerybypasses the parameter bag entirely — if you concatenate a$_GETvalue into the string, you've reintroduced SQL injection. Route user values throughwhere()/set()/setParameter(). See Security.
RawQuery::__construct(mixed $rawQuery) accepts:
use InitORM\QueryBuilder\RawQuery;
$raw = new RawQuery('NOW()');
echo (string) $raw;
// NOW()The closure is invoked with a fresh QueryBuilder. It may either:
- return a string — the string becomes the raw fragment;
-
return a stringable object — its
__toString()is captured; -
return nothing — the inner builder's
__toString()is captured (the closure built a query against the supplied builder).
$raw = new RawQuery(function () {
return 'CURRENT_TIMESTAMP';
});
// CURRENT_TIMESTAMP
$raw = new RawQuery(function (QueryBuilder $qb) {
$qb->select('id')->from('users')->where('active', 1);
});
// SELECT `id` FROM `users` WHERE `active` = 1$raw = new RawQuery(42);
echo (string) $raw;
// 42// Inside a builder chain
$qb->from('users')->where('created_at', '>=', $qb->raw('NOW() - INTERVAL 7 DAY'));
// Outside a chain
$now = RawQuery::raw('NOW()');$qb->raw() is the convenience for use inside chains; RawQuery::raw()
is the static factory for use anywhere.
Anywhere the builder accepts RawQuery|string (or RawQuery|<other>):
-
Projections —
select($qb->raw('NOW() AS now')),selectAs($qb->raw('JSON_EXTRACT(payload, "$.name")'), 'name'). -
Tables —
from($qb->raw('users FORCE INDEX (idx_status)')). -
JOIN ON —
innerJoin('posts', $qb->raw('posts.user_id = users.id')). -
WHERE values —
where('created_at', '<', $qb->raw('NOW()')). -
BETWEEN bounds —
between('ts', $qb->raw('NOW() - INTERVAL 1 DAY'), $qb->raw('NOW()')). -
IN values —
whereIn('id', $qb->raw('(SELECT user_id FROM bans)')). -
SET column values —
set('updated_at', $qb->raw('NOW()')). -
LIKE values —
like('name', $qb->raw("'custom%pattern'"))(opts out of the v2 wildcard auto-escape, see Security §V4).
$qb->set([
'created_at' => $qb->raw('NOW()'),
'token' => $qb->raw('UUID()'),
'name' => 'Muhammet',
]);
// (`created_at`, `token`, `name`) VALUES (NOW(), UUID(), :name)PostgreSQL ILIKE:
$qb->from('users')->where('email', $qb->raw('ILIKE :search'));
$qb->setParameter('search', '%@example.test');$qb->select('author_id')
->selectCount('id', 'post_count')
->from('post')
->groupBy('author_id')
->having($qb->raw('COUNT(id) > 5'));
// HAVING COUNT(id) > 5$qb->whereIn('user_id', $qb->raw('(SELECT id FROM admin_users)'));
// WHERE `user_id` IN (SELECT id FROM admin_users)For dynamic inner SELECTs prefer [[Sub Queries|subQuery()]] — it gives
you the fluent DSL inside the closure.
Useful for one-liner derived expressions:
$raw = $qb->raw(function (QueryBuilder $inner) {
$inner->select('AVG(views)')->from('posts')->where('status', 1);
});
$qb->select('post.title')
->selectAs($raw, 'avg_views')
->from('post');$raw = new RawQuery('NOW()');
$raw->set('CURRENT_TIMESTAMP');
echo (string) $raw;
// CURRENT_TIMESTAMPset() returns the RawQuery for chaining.
$raw = new RawQuery('NOW()');
echo $raw->get(); // 'NOW()'
echo (string) $raw; // 'NOW()'__toString() and get() are equivalent.
Next: Parameters
InitORM QueryBuilder — MIT licensed · authored by Muhammet ŞAFAK · part of the InitORM family · report an issue · security disclosure