bentools / where
PHP7.1 流式、不可变 SQL 查询构建器。无连接、无框架依赖、无依赖。
Requires
- php: >=7.1
Requires (Dev)
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^7.0
- squizlabs/php_codesniffer: ^3.2
- symfony/var-dumper: ^4.0
Suggests
- bentools/etl: PHP7.1 ETL pattern implementation
- bentools/pager: A simple OOP pager.
- bentools/simple-dbal: A PDO / MySqli wrapper handling lazy loading, parallel and asynchronous queries.
This package is auto-updated.
Last update: 2024-09-22 22:32:45 UTC
README
Where
最简单的流式 SQL 查询构建器。
在 PHP7.1 中构建,注重不可变性。
功能
- 无框架依赖,无连接依赖(你只需渲染一个字符串和一个值数组)
- 自然语言:where,and,or,...
- 支持命名和数字占位符
- 构建复杂、嵌套的 WHERE 条件
- 构建
SELECT
、INSERT
、UPDATE
、DELETE
、REPLACE
查询的辅助函数 - 构建 SQL 函数的辅助函数,如
IN
、BETWEEN
、IS NULL
、CASE ... WHEN
为什么?
在大多数情况下,简单的 SQL 查询就足够了。
但如果你的应用程序逻辑设计成几个类/方法可以修改 SQL 查询(如访问者模式),那么你可能需要查询构建器(例如,您可以在 WHERE 之前定义 LIMIT / OFFSET,查询将按正确的顺序渲染)。
条件构建器
Where 允许您使用 表达式 构建条件。 表达式 是可以
- 简单表达式:
date_added = CURRENT_DATE
- 复合表达式:
date_added = CURRENT_DATE OR date_added = SUBDATE(CURRENT_DATE, INTERVAL 1 DAY)
- 分组表达式:
(country = 'UK' OR country = 'BE')
- 否定表达式:
NOT date_added = CURRENT_DATE
一个 表达式 对象也可以包含一个参数数组来绑定(以避免 SQL 注入)。
您不需要实例化它们。只需依靠库提供的强大功能即可
require_once __DIR__ . '/vendor/autoload.php'; use function BenTools\Where\group; use function BenTools\Where\not; use function BenTools\Where\where; $where = where('country IN (?, ?)', ['FRA', 'UK']) ->and( not( group( where('continent = ?', 'Europe') ->or('population < ?', 100000) ) ) ); print((string) $where); print_r($where->getValues()); print_r($where->preview()); // For debugging purposes
输出
country IN (?, ?) AND NOT (continent = ? OR population < ?)
Array ( [0] => FRA [1] => UK [2] => Europe [3] => 100000 )
country IN ('FRA', 'UK') AND NOT (continent = 'Europe' OR population < 100000)
每个函数 where()
、group()
、not()
都接受一个已实例化的 Expression 对象、一个字符串和一些可选参数。
$where = where('date > NOW()'); // valid $where = where($where); // valid $where = where(group($where)); // valid $where = where(not($where)); // valid $where = where('date = ?', date('Y-m-d')); // valid $where = where('date BETWEEN ? AND ?', date('Y-m-d'), date('Y-m-d')); // valid $where = where('date BETWEEN ? AND ?', [date('Y-m-d'), date('Y-m-d')]); // valid $where = where('date BETWEEN :start AND :end', ['start' => date('Y-m-d'), 'end' => date('Y-m-d')]); // valid $where = where('date BETWEEN :start AND :end', ['start' => date('Y-m-d')], ['end' => date('Y-m-d')]); // not valid $where = where($where, date('Y-m-d'), date('Y-m-d')); // not valid (parameters already bound)
感谢流畅的接口,让您的 IDE 帮助您完成剩余部分。别忘了 Where 总是不可变的:每次您进行更改时都要重新分配 $where
。
选择查询构建器
现在您已经学会了如何构建条件,您将看到构建整个选择查询是多么容易
require_once __DIR__ . '/vendor/autoload.php'; use function BenTools\Where\group; use function BenTools\Where\not; use function BenTools\Where\select; use function BenTools\Where\where; $select = select('b.id', 'b.name AS book_name', 'a.name AS author_name') ->from('books as b') ->innerJoin('authors as a', 'a.id = b.author_id') ->limit(10) ->orderBy('YEAR(b.published_at) DESC', 'MONTH(b.published_at) DESC', 'b.name') ->where( group( where('b.series = ?', 'Harry Potter')->or('b.series IN (?, ?)', ['A Song of Ice and Fire', 'Game of Thrones']) ) ->and('b.published_at >= ?', new \DateTime('2010-01-01')) ->and( not('b.reviewed_at BETWEEN ? AND ?', new \DateTime('2016-01-01'), new \DateTime('2016-01-31 23:59:59')) ) ); print_r((string) $select); // The SQL string print_r($select->preview()); // For debugging purposes
SELECT b.id, b.name AS book_name, a.name AS author_name FROM books as b INNER JOIN authors as a ON a.id = b.author_id WHERE (b.series = ? OR b.series IN (?, ?)) AND b.published_at >= ? AND NOT b.reviewed_at BETWEEN ? AND ? ORDER BY YEAR(b.published_at) DESC, MONTH(b.published_at) DESC, b.name LIMIT 10;
SELECT b.id, b.name AS book_name, a.name AS author_name FROM books as b INNER JOIN authors as a ON a.id = b.author_id WHERE (b.series = 'Harry Potter' OR b.series IN ('A Song of Ice and Fire', 'Game of Thrones')) AND b.published_at >= '2010-01-01 00:00:00' AND NOT b.reviewed_at BETWEEN '2016-01-01 00:00:00' AND '2016-01-31 23:59:59' ORDER BY YEAR(b.published_at) DESC, MONTH(b.published_at) DESC, b.name LIMIT 10;
让您的 IDE 使用自动完成完成剩余部分。
RulerZ
Where 主要与出色的 RulerZ DSL 兼容。
请确保对您的语句进行 group
以避免副作用。
示例
use function BenTools\Where\group; use function BenTools\Where\not; $fruits = [ 'banana', 'apple', ]; $colors = [ 'yellow', 'red', ]; $condition = group('fruit IN :fruits', ['fruits' => $fruits])->and(group('color IN :colors', ['colors' => $colors])); $condition = not($condition); var_dump($rulerz->satisfies(['fruit' => 'strawberry', 'color' => 'red'], (string) $condition, $condition->getValues())); // true var_dump($rulerz->satisfies(['fruit' => 'apple', 'color' => 'yellow'], (string) $condition, $condition->getValues())); // false
安装
composer require bentools/where
测试
./vendor/bin/phpunit
另请参阅
bentools/simple-dbal - 一个 PHP 7.1+ 的 PDO & Mysqli 包装器。可以绑定 DateTime
参数。
bentools/pager - 一个 PHP 7.1+ 分页器。
bentools/flatten-iterator - 将多个 array
或 Traversable
转换为一个迭代器。
bentools/etl - 一个 PHP7.1 ETL 模式实现。
latitude/latitude - 另一个 SQL 查询构建器 Where 受其启发。