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 的唯一缺点是需要数据复制。