PHPackages                             phpgt/sqlbuilder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. phpgt/sqlbuilder

ActiveLibrary[Database &amp; ORM](/categories/database)

phpgt/sqlbuilder
================

Object oriented representation of SQL queries.

v1.1.0(1w ago)17581[2 PRs](https://github.com/PhpGt/SqlBuilder/pulls)PHPPHP &gt;=8.4CI passing

Since Mar 13Pushed 6d ago1 watchersCompare

[ Source](https://github.com/PhpGt/SqlBuilder)[ Packagist](https://packagist.org/packages/phpgt/sqlbuilder)[ GitHub Sponsors](https://github.com/sponsors/phpgt)[ RSS](/packages/phpgt-sqlbuilder/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (7)Dependencies (8)Versions (12)Used By (0)

Object oriented representation of SQL queries.
==============================================

[](#object-oriented-representation-of-sql-queries)

This library does not generate any SQL, instead it provides an object oriented representation of SQL queries, allowing the structure of queries to be defined by the developer whilst gaining the benefits of inheritance.

When a PHP application reaches scale, it is often the database that is the performance bottleneck. When queries are generated on behalf of the developer, they are often difficult to optimise because control is lost. With SqlBuilder, the developer is always in control of the raw SQL.

---

[ ![Build status](https://camo.githubusercontent.com/f3794f88adf7e050180af5722238b84ec5a1c0d9a297328c0acd3b74e7af5d92/68747470733a2f2f62616467652e7374617475732e7068702e67742f73716c6275696c6465722d6275696c642e737667)](https://github.com/PhpGt/SqlBuilder/actions)[ ![Code quality](https://camo.githubusercontent.com/c6aab0b6c788d72f225f2ecd4c0c6bd6097de521ecb4ebf252f77dae2dd3be2f/68747470733a2f2f62616467652e7374617475732e7068702e67742f73716c6275696c6465722d7175616c6974792e737667)](https://app.codacy.com/gh/PhpGt/SqlBuilder)[ ![Code coverage](https://camo.githubusercontent.com/8939821f45f69040fe541471913d4c6f3974e53f08cbf2d460ff40f8ac81b013/68747470733a2f2f62616467652e7374617475732e7068702e67742f73716c6275696c6465722d636f7665726167652e737667)](https://app.codecov.io/gh/PhpGt/SqlBuilder)[ ![Current version](https://camo.githubusercontent.com/f0ba02074a3c2ab679e6a4f4895a970483e616accf55616a2169d58a3d69b667/68747470733a2f2f62616467652e7374617475732e7068702e67742f73716c6275696c6465722d76657273696f6e2e737667)](https://packagist.org/packages/PhpGt/SqlBuilder)[ ![PHP.GT/SqlBuilder documentation](https://camo.githubusercontent.com/3447d816eba49a7db4e67ed10ce81fc2b108451110d42f5fcf9ca6747723162d/68747470733a2f2f62616467652e7374617475732e7068702e67742f73716c6275696c6465722d646f63732e737667)](http://www.php.gt/sqlbuilder)Example usage: a class that represents a SELECT query
-----------------------------------------------------

[](#example-usage-a-class-that-represents-a-select-query)

Imagine a typical database application with a `student` table used to store details of each student. A basic select might look something like this:

```
select
	id,
	forename,
	surname,
	dateOfBirth
from
	student
```

The above query will return a list of all students. The problem here is that when you come to need to select from the student table again, this time with some constraints such as an age range or ordered by surname, the whole query will need to be repeated and only a small portion of the original query will need to be changed.

Instead, the following class can be used to *represent* the above query:

```
use GT\SqlBuilder\Query\SelectQuery;

class StudentSelect extends SelectQuery {
	public function select():array {
		return [
			"id",
			"forename",
			"surname",
			"dateOfBirth",
		];
	}

	public function from():array {
		return [
			"student",
		];
	}
}
```

The `__toString` method of the above class will produce identical SQL to the original query.

Now, to write another query that returns students of a certain age:

```
class StudentSelectByAge extends StudentSelect {
	public function where():array {
		return [
			"year(now()) - year(dateOfBirth) = :age",
		];
	}
}
```

Example usage: A fluent class that *builds* a SELECT query (coming in v2 release)
---------------------------------------------------------------------------------

[](#example-usage-a-fluent-class-that-builds-a-select-query-coming-in-v2-release)

As you can see in the example above, `SqlQuery` functions always return an array of expressions. The `SqlBuilder` classes have the same methods (`select`, `from`, `where`, etc.) but take the expressions as parameters, acting as a **[fluent interface](https://en.wikipedia.org/wiki/Fluent_interface)**.

To create the same query as in the example above with fluent syntax:

```
use GT\SqlBuilder\SelectBuilder;

$selectQuery = new SelectBuilder(
	"id",
	"forename",
	"surname",
	"dateOfBirth"
)->from(
	"student"
)->where(
	"year(now()) - year(dateOfBirth) = :age"
);
```

This is particularly useful for when there is a base query, say `StudentSelect`, and your code only requires a single additional condition. Rather than having to create a separate class for this single usage, it can be called inline:

```
use GT\SqlBuilder\SelectBuilder;

// Start by using a base StudentSelect, then add a single inline condition to it.
$studentSelect = new StudentSelect();

$selectQuery = new SelectBuilder($studentSelect)
->where(
	"year(now()) - year(dateOfBirth) = :age"
);
```

Conditionals
------------

[](#conditionals)

Expressions within `where` and `having` clauses can be connected with logical operators, which are often combined. To avoid logical errors, `Condition` objects are used to specify the precedence of logic.

For example, to select students with a specific age *and* gender:

```
use GT\SqlBuilder\Condition\AndCondition;

class StudentSelectByAge extends StudentSelect {
	public function where():array {
		return [
			new AndCondition("year(now()) - year(dateOfBirth) = :age"),
			new AndCondition("gender = :gender"),
		];
	}
}
```

Subqueries
----------

[](#subqueries)

`SqlQuery` objects have a `__toString()` function, and `SqlBuilder` results create `SqlQuery` instances. Because of this, they can be used in place of any other expression within a Query or Builder.

Limitations of plain SQL
------------------------

[](#limitations-of-plain-sql)

The only tools provided by plain SQL that can be used to write [DRY code](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) are [views](https://en.wikipedia.org/wiki/View_(SQL)) and [stored procedures](https://en.wikipedia.org/wiki/Stored_procedure), both of which have their own set of limitations when writing clean and maintainable code.

The solution provided by this library is to break down an SQL query into its different sections, represented by a PHP class which can be extended by other classes, while still retaining the plain SQL that is being represented.

SQL compatibility
-----------------

[](#sql-compatibility)

This library does not provide any SQL processing capabilities by design. Any driver-specific SQL used will not be compatible with other drivers. This allows the developer to fully utilise their SQL driver of choice, rather than generating *generic* SQL.

Proudly sponsored by
====================

[](#proudly-sponsored-by)

[JetBrains Open Source sponsorship program](https://www.jetbrains.com/community/opensource/)

[![JetBrains logo.](https://camo.githubusercontent.com/b5639e7738c6dfae9fe3f3e20175570b7376ce2577a772e09c25c2d4f14bf86e/68747470733a2f2f7265736f75726365732e6a6574627261696e732e636f6d2f73746f726167652f70726f64756374732f636f6d70616e792f6272616e642f6c6f676f732f6a6574627261696e732e737667)](https://www.jetbrains.com/community/opensource/)

###  Health Score

58

—

FairBetter than 98% of packages

Maintenance98

Actively maintained with recent releases

Popularity22

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 92.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~435 days

Recently: every ~481 days

Total

7

Last Release

8d ago

Major Versions

v0.2.0 → v1.0.02022-11-14

PHP version history (4 changes)v0.0.1PHP ^7.2

v0.1.0PHP ^7.4

v0.1.1PHP &gt;=8.0

v1.1.0PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/9e42344b91ce4b91ab57875969f67a0a6a48de570a08bc65d673b06b72fd3a3f?d=identicon)[g105b](/maintainers/g105b)

---

Top Contributors

[![g105b](https://avatars.githubusercontent.com/u/358014?v=4)](https://github.com/g105b "g105b (12 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

databasedatabase-queriesfluentfluent-apino-aioopphpgtquery-buildersql

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpgt-sqlbuilder/health.svg)

```
[![Health](https://phpackages.com/badges/phpgt-sqlbuilder/health.svg)](https://phpackages.com/packages/phpgt-sqlbuilder)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90340.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
