smalldb / flupdo
Flupdo:一个简单且功能齐全的流式查询构建器
Requires
- php: >=5.4
- ext-pdo: *
Requires (Dev)
- smalldb/doc-tools: dev-master
Suggests
- ext-pdo_mysql: MySQL driver for PDO
- ext-pdo_sqlite: Sqlite driver for PDO
Replaces
README
Flupdo是用PHP编写的简单SQL查询构建器。它设计得简单、确定、透明且易于使用。Flupdo不包含任何通常在出现小错误时难以预测的智能逻辑。
Flupdo支持(或应支持)100%的MySQL语法。Sqlite和SphinxQL也得到支持,但未经过良好测试。计划支持PostgreSQL,可能只需要进行一些小的调整,因此可能已经可以使用。
Flupdo基于PDO构建。它不替换fetch方法或任何其他PDO API,它只添加了几个构建方法,这些方法创建查询构建器对象,从而保持与PDO的完全兼容性。当执行查询时,将返回普通的PDOStatement实例。
Flupdo支持位置和命名占位符,但不能混用。位置占位符在将值与SQL语句一起传递给查询构建器时很有用(请参阅“基本用法”部分)。命名占位符用于预处理查询,其中所有值一次性传递(请参阅“预处理查询”部分)。
Flupdo使用PHPT进行测试,这是PHP本身使用的工具。请参阅“test”目录。
Flupdo使用Doxygen进行文档编写 -- make doc 就可以了。
Flupdo不提供构建常见查询的智能构造和辅助工具。这些功能超出了Flupdo的范围。Flupdo旨在成为一个基本工具,用于由这些辅助工具和智能查询构建器使用来拼接查询。因此,如果您需要更智能的功能,请在其之上构建。例如,Smalldb就是这样一种框架。
有关更多详细信息,请参阅项目网站: https://smalldb.org/
基本用法
所有构建方法都接受SQL片段作为第一个参数,参数作为任何其他参数。例如
$q->where('id = ?', $id);
它将在WHERE子句中添加条件 (id = ?) 并将 $id 添加到参数列表中。因此,整个查询将如下所示
SELECT ...
WHERE ... AND (id = ?)
要执行查询,您可以使用 query() 或 exec() 方法。它们具有与 PDO::query() 和 PDO::exec() 相同的语义,但它们不接受任何参数,因为查询已经包含在查询构建器中。例如,要执行上述查询,请使用此方法
$pdostmt = $q->query();
然后可以像往常一样检索结果
print_r($pdostmt->fetchAll(PDO::FETCH_ASSOC));
预处理查询
当查询需要为多次使用进行预处理时,最好使用命名占位符
$pdostmt = $q->insert()->into('users')
->set('name = :name')
->set('password = :password')
->prepare();
然后可以轻松地重复执行
$flupdo->beginTransaction();
foreach ($users as $u) {
$pdostmt->execute(array('name' => $u['name'], 'password' => $u['password']));
}
$flupdo->commit();
子查询
可以逐字将简短子查询传递给任何构建方法
$q->select('(SELECT MAX(`id`) + 1 FROM users) AS `next_id`');
更复杂的查询应由Flupdo构建,并通过数组作为第一个参数传递给构建方法
$q2 = $flupdo->select('MAX(`id`) + 1')->from('users');
$q->select(array($q2, 'AS `next_id`'));
这两个示例将生成相同的SELECT语句。
警告:在子查询之前不允许使用位置占位符
$q->where(array($subquery, ' > ?'), $n); // Good
$q->where(array('n + ? IN ', $subquery), $c); // Bad
构建方法
构建方法与转换为小骆驼式的SQL关键字同名
- select(), where(), from(), join(), leftJoin(), innerJoin(), orderBy(), groupBy(), having(), ...
- distinct(), highPriority(), sqlNoCache(), ...
还有所有查询类型中都可用的注释方法 headerComment() 和 footerComment()。它们在SQL查询前后添加简单的注释。这些可能很有用,可以标记查询在代码中的位置,以便从慢查询日志中轻松找到查询
$q->footerComment(__FILE__.':'.__LINE__);
复杂连接
请注意,连接被视为独立子句,而不是FROM子句的一部分。这意味着不可能进行复杂连接,但简单的多个连接链很容易。要构建复杂的FROM子句,请将FROM子句逐字指定为单个 from() 调用
$q->from('t1, (t2, t3), t4');
这也意味着,这段代码
$q->from('t1');
$q->join('t2 ...');
$q->from('t3');
... 将生成以下SQL查询
SELECT ...
FROM t1, t3
JOIN t2 ...
这种行为是有意为之的,因为它简化了复杂过滤查询的构建。
内部逻辑
Flupdo的内部逻辑非常简单,但功能强大。它只包含少量缓冲区,用于存储构建方法调用。在查询执行之前,根据查询需要,通过正确排序这些缓冲区的内容(使用正确的连接词和关键词)来编译最终查询。
第一个构建方法调用(在Flupdo实例上)确定查询的类型,并返回FlupdoBuilder子类的实例。之后无法更改查询的类型。
Flupdo不会解析也不会理解SQL片段。它只使用字符串级别的连接。如果需要更复杂的行为,可以在Flupdo之上编写额外的辅助方法或更高级的查询构建器。
示例
这些示例可以作为test目录中的测试使用。
初始化
$flupdo = new Flupdo($dsn, $username, $password); // Same as PDO.
简单的选择
$q = $flupdo->select('n AS TheNumber')
->select('n + 1')
->distinct()
->select('n + 2')
->headerComment('Simple select')
->from('numbers')
->where('n > ?', 5)
->where('n < ?', 200)
->orderBy('n DESC');
查询结果与Flupdo生成的完全一致(包括空白字符)
-- Simple select
SELECT DISTINCT n AS TheNumber,
n + 1,
n + 2
FROM numbers
WHERE (n > ?)
AND (n < ?)
ORDER BY n DESC
带有子查询的更复杂示例
$q = $flupdo->select('n')
->from('numbers')
->where(array('n >', $flupdo->select('MIN(n) + ?', 2)->from('numbers')))
->where('n < ?', 100)
->orderBy('n DESC');
查询结果与Flupdo生成的完全一致(包括空白字符)
SELECT n
FROM numbers
WHERE (n > (
SELECT MIN(n) + ?
FROM numbers
))
AND (n < ?)
ORDER BY n DESC
文档
请参阅https://smalldb.org/doc/flupdo/master/
许可证
大部分代码在Apache 2.0许可证下发布。有关详细信息,请参阅LICENSE文件。
贡献指南
项目的主要仓库托管在https://git.frozen-doe.net/smalldb/flupdo,您可以在此处提交问题或创建合并请求。