PopSQL (pronounced "popsicle") provides a simple, objective approach to conditionally constructing MySQL statements.
Building conditional queries by hand is tedious, error prone, and ugly:
$fields = ['field1', 'field2'];
if ($someCondition)
$fields[] = 'field3';
else$fields[] = 'field4';
$fieldClause = implode(',', $fields);
$whereConditions = [];
$whereParameters = [];
if ($someCondition) {
$whereConditions[] = 'field1 > ? AND field3 < ?';
$whereParameters[] = 0;
$whereParameters[] = 1337;
} elseif ($someOtherCondition) {
$whereConditions[] = 'field4 != "" OR field2 < ?';
$whereParameters[] = 0;
}
if ($whereConditions)
$whereClause = 'WHERE (' . implode('', ) . ')';
else$whereClause = '';
$query = <<<EOTSELECT $fieldClauseFROM my_table mtJOIN my_other_table mot ON mt.field1 > mot.value + ?$whereClauseEOT;
$params = array_merge([7], $whereParameters);Working with an object is much prettier, and much harder to mess up:
$qGen = newQueryGenerator();
$qGen->select(['field1', 'field2']);
$qGen->select($someCondition ? 'field3' : 'field4');
$qGen->from('my_table mt')->
join('JOIN my_other_table mot ON mt.field1 > mot.value + ?', 7);
if ($someCondition) {
$qGen->where('field1 > ? AND field3 < ?', [0, 1337]);
} elseif ($someOtherCondition) {
$qGen->where('field4 != "" OR field2 < ?', 0);
}
list($query, $params) = $qGen->build();Assuming $someCondition is true and $someOtherCondition is false, the
above example produces the following query:
SELECT field1, field2, field3
FROM my_table mt
JOIN my_other_table mot ONmt.field1>mot.value+ ?
WHERE field1 > ? AND field3 < ?... and the following parameters:
[7, 0, 1337]QueryGenerator has support for SELECT, INSERT, REPLACE, UPDATE, and DELETE queries. Each of those query types supports a selection of different clauses:
- select: from, join, where, group, having, union, order, limit, offset, forupdate
- insert: set, columns, values, duplicate
- replace: set, columns, values
- update: set, where, order, limit
- delete: from, where, order, limit
Simply call the member function of the clause you want to add to, passing strings of SQL and (optionally) parameters for use in prepared statements.
SELECT queries can be combined with union() and unionAll(). Operands
must be complete SELECT statements, either another QueryGenerator or a raw
SQL string:
$archived = newQueryGenerator();
$archived->select('id')->from('archived_orders')->where('total > ?', 100);
$qGen = newQueryGenerator();
$qGen->select('id')->from('orders')->where('total > ?', 100);
$qGen->union($archived);
$qGen->unionAll('SELECT id FROM pending_orders');
$qGen->order('id');A trailing order() or limit() applies to the whole union result. To
order or limit an individual operand, pass it as a parenthesized string.
QueryGenerator operands are rendered when union() or unionAll() is
called; mutating the operand afterward has no effect on the outer query.