gajus / klaus
用户输入解释器,用于构建 SQL WHERE 子句。
0.1.0
2014-04-25 15:55 UTC
Requires
- php: >=5.5
Requires (Dev)
- satooshi/php-coveralls: dev-master
This package is not auto-updated.
Last update: 2024-09-14 14:11:11 UTC
README
用户输入解释器,用于构建 SQL WHERE 子句。Klaus 可以构建具有不同分组条件的复杂深度的 WHERE 子句。
文档
准备查询
原始查询由分组运算符定义(AND 或 OR)和条件组成。有两种类型的条件
比较条件
比较由用户输入名称、值和比较运算符组成,例如。
[
'name' => 'foo_name', // User input name
'value' => '1', // User input value
'operator' => '=' // Condition operator
]
分组条件
条件本身可以定义新分组,例如。
$query = [ 'group' => 'AND', 'condition' => [ ['name' => 'foo_name', 'value' => '1', 'operator' => '='], ['name' => 'bar_name', 'value' => '2', 'operator' => '='], [ 'group' => 'OR', 'condition' => [ ['name' => 'foo_name', 'value' => '1', 'operator' => '='], ['name' => 'bar_name', 'value' => '2', 'operator' => '='] ] ] ] ]
完整的查询必须至少包含一个分组和一个比较运算符。
使用输入映射
映射用于限制可以包含在查询中的列,以及为依赖于别名或更复杂结构的列提供支持。
SELECT `f1`.`name`, `b1`.`name` FROM `foo` `f1` INNER JOIN `bar` `b1` ON [..]
在上面的示例中,您需要定义查询中使用的参数名称与 SQL 查询中的列名称之间的关系,例如。
$map = [ 'foo_name' => '`f1`.`name`', 'bar_name' => '`b1`.`name`' ];
构建 WHERE 子句
前面的示例解释了如何为 Where 构造函数准备数据。
/** * @param array $query * @param array $map Map input name to the aliased column in the SQL query, e.g. ['name' => '`p1`.`name`']. */ $where = new \Gajus\Klaus\Where($query, $map);
我们将使用前面的示例中的 SQL 构建一个预处理语句并执行它。
使用 getClause 方法生成 WHERE 子句本身
/** * @return string SQL WHERE clause representng the query. */ $where->getClause();
如果查询不生成条件,则 getClause 将始终返回 1=1,例如。
$sql = " SELECT `f1`.`name`, `b1`.`name` FROM `foo` `f1` INNER JOIN `bar` `b1` ON [..] WHERE {$where->getClause()} ";
在上面的示例中,$sql 是
SELECT `f1`.`name`, `b1`.`name` FROM `foo` `f1` INNER JOIN `bar` `b1` ON [..] WHERE `f1`.`name` = :foo_name_0 AND `b1`.`name` = :bar_name_1 AND ( `f1`.`name` = :foo_name_2 OR `b1`.`name` = :bar_name_3 )
要执行查询,您必须构建 PDOStatement,例如。
$sth = $db->prepare($sql);
并使用输入数据执行它
/** * @return array Input mapped to the prepared statement bindings present in the WHERE clause. */ $input = $where->getInput(); $sth->execute($input);
在上面的示例中,$input 等于
[
'foo_name_0' => '1',
'bar_name_1' => '2',
'foo_name_2' => '1',
'bar_name_3' => '2',
]
输入模板
对于基本搜索,您可以使用 Gajus\Klaus\Where::queryTemplate。
- 基本查询模板采用名称 => 值对,并将它们转换为使用
AND分组的WHERE子句。 - 空值将被忽略。
- 以
%开头的值将使用LIKE比较运算符。 - 以
%结尾的值将使用LIKE比较运算符。 - 不包含
%或%不是查询开头或结尾的值将使用=比较运算符。
示例
$query = \Gajus\Klaus\Where::queryTemplate(['foo' => 'bar', 'baz' => 'qux%']); // $query is now eq. to: $query = [ 'group' => 'AND', 'condition' => [ ['name' => 'foo', 'value' => 'bar', 'operator' => '='], ['name' => 'baz', 'value' => 'qux%', 'operator' => 'LIKE'] ] ]; // Which you then pass to the Where constructor. $where = new \Gajus\Klaus\Where($query, ['foo' => '`foo`', 'baz' => '`baz`']); $sth = $db->prepare("SELECT `foo`, `baz` FROM `quux` WHERE {$where->getClause()}"); $sth->execute($where->getInput()); // ..
替代方案
elasticsearch (ES) 提供了一个具有查询 DSL 的 API。使用 ES 的唯一缺点是需要数据复制。