A PHP library for building and managing SQL WHERE conditions with a flexible, object-oriented approach.
Build SQL WHERE clauses programmatically with a clean, type-safe, and composable expression system. Supports 16 SQL operators with named parameter binding for PDO.
- 16 SQL operators: comparison (
=,<>,>,>=,<,<=), pattern matching (LIKE,NOT LIKE), set membership (IN,NOT IN), range (BETWEEN,NOT BETWEEN), null checks (IS NULL,IS NOT NULL), boolean (IS TRUE,IS FALSE) - Named parameter (
:value_column) output for PDO prepared statements - Composable
Conditionclass with AND/OR logic and nested grouping - LIKE anchor support (left, right, both)
- Static factory
Expression::EQ(),Expression::GT(), etc. for concise expression creation - Zero runtime dependencies, PHP 8.3+ with strict types
composer require changhorizon/sql-conditionsrc/
├── Condition.php # Expression combiner with AND/OR logic
├── Expression.php # Static factory (EQ, NEQ, GT, ...)
├── Enums/
│ ├── Anchor.php # LIKE anchor direction
│ ├── Logic.php # AND / OR
│ └── Operator.php # 16 SQL operators
├── Expressions/
│ ├── Between.php / NotBetween.php
│ ├── Equal.php (+ NEQ, GT, GTE, LT, LTE via inheritance)
│ ├── In.php / NotIn.php
│ ├── IsNull.php (+ IsNotNull, IsTrue, IsFalse via inheritance)
│ └── Like.php / NotLike.php
└── Interfaces/
└── ExpressionInterface.phpuse ChangHorizon\SqlCondition\Expression;
// Simple conditions
$eq = Expression::EQ('name', 'John');
$gt = Expression::GT('age', '18');
$in = Expression::IN('status', ['active', 'pending']);
$like = Expression::LIKE('title', 'hello');
$eq->getString(); // "name = :value_name"
$eq->getParams(); // [':value_name' => 'John']use ChangHorizon\SqlCondition\Condition;
use ChangHorizon\SqlCondition\Expression;
$cond = new Condition([
Expression::EQ('name', 'John'),
Expression::GT('age', '18'),
Expression::IS_NULL('deleted_at'),
]);
$cond->getString(); // "name = :value_name AND age > :value_age AND deleted_at IS NULL"
$cond->getParams(); // [':value_name' => 'John', ':value_age' => '18']use ChangHorizon\SqlCondition\Condition;
use ChangHorizon\SqlCondition\Enums\Logic;
$cond = new Condition([
Expression::EQ('role', 'admin'),
Expression::EQ('role', 'moderator'),
], Logic::OR);
$cond->getString(); // "role = :value_role OR role = :value_role"$adminOrMod = new Condition([
Expression::EQ('role', 'admin'),
Expression::EQ('role', 'moderator'),
], Logic::OR);
$cond = new Condition([
$adminOrMod,
Expression::IS_TRUE('is_active'),
]);
$cond->getString(); // "(role = :value_role OR role = :value_role) AND is_active IS TRUE"use ChangHorizon\SqlCondition\Enums\Anchor;
use ChangHorizon\SqlCondition\Expressions\Like;
// Default (both sides): %value%
new Like('title', 'hello')->getParams(); // [':value_title' => '%:hello%']
// Left anchor only: value%
new Like('title', 'hello', Anchor::LEFT)->getParams(); // [':value_title' => ':hello%']
// Right anchor only: %value
new Like('title', 'hello', Anchor::RIGHT)->getParams(); // [':value_title' => '%:hello']$cond = new Condition([
Expression::EQ('email', 'user@example.com'),
Expression::IS_NOT_NULL('verified_at'),
]);
$sql = 'SELECT * FROM users WHERE ' . $cond->getString();
$stmt = $pdo->prepare($sql);
$stmt->execute($cond->getParams());| Method | Returns | Description |
|---|---|---|
getString(): string |
SQL fragment (e.g. age > :value_age) |
|
getParams(): array |
Named params for PDO binding | |
getLogic(): ?Logic |
null for leaf expressions |
| Method | Expression | SQL Output |
|---|---|---|
EQ($col, $val) |
Equal | col = :val |
NEQ($col, $val) |
NotEqual | col <> :val |
GT($col, $val) |
GreaterThan | col > :val |
GTE($col, $val) |
GreaterThanOrEqual | col >= :val |
LT($col, $val) |
LessThan | col < :val |
LTE($col, $val) |
LessThanOrEqual | col <= :val |
IS_NULL($col) |
IsNull | col IS NULL |
IS_NOT_NULL($col) |
IsNotNull | col IS NOT NULL |
IS_TRUE($col) |
IsTrue | col IS TRUE |
IS_FALSE($col) |
IsFalse | col IS FALSE |
IN($col, $vals) |
In | col IN (:v0, :v1) |
NOT_IN($col, $vals) |
NotIn | col NOT IN (:v0) |
BT($col, $min, $max) |
Between | col BETWEEN :min AND :max |
NOT_BT($col, $min, $max) |
NotBetween | col NOT BETWEEN :min AND :max |
LIKE($col, $pattern) |
Like | col LIKE :val |
NOT_LIKE($col, $pattern) |
NotLike | col NOT LIKE :val |
composer stancomposer cs:chk # check
composer cs:fix # auto-fixcomposer test
composer test:coverageMIT License. See LICENSE for details.
欢迎 Issue 与 PR,建议遵循以下流程:
- Fork 仓库
- 创建新分支进行开发
- 提交 PR 前请确保测试通过、风格一致
- 提交详细描述