PHPackages                             lushobarlett/query-manager - 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. lushobarlett/query-manager

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

lushobarlett/query-manager
==========================

manager for mysql queries to improve database code flexibility, security and automation of simpler database use cases

v3.0.0(4y ago)02941MITPHPPHP ^7CI failing

Since May 21Pushed 4y ago1 watchersCompare

[ Source](https://github.com/lushoBarlett/query-manager)[ Packagist](https://packagist.org/packages/lushobarlett/query-manager)[ RSS](/packages/lushobarlett-query-manager/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (2)Versions (19)Used By (0)

PHP query manager
=================

[](#php-query-manager)

Manager for query building and execution.

Objectives
----------

[](#objectives)

- Query code flexibility and reusability
- Solve security and fidelity issues
- Force their use, with no penalty to the programmer
- Make simple database use cases quicker to code

Implementation
--------------

[](#implementation)

### Query Pieces

[](#query-pieces)

The query building block is a `QueryPiece` class. In mathematical terms it is nothing more than a Monoid, because it acts as a pair of string and array. First constructor argument is the statement, the rest are the values filling that statement, called *fragments*. All arguments are optional, if nothing is provided you get the identity, empty string and array.

```
$qp = new QueryPiece(
	"SELECT * FROM mytable WHERE id = ? and name = ?", 1, "some name"
);
$qp->template // "SELECT * FROM mytable WHERE id = ? and name = ?"
$qp->fragments // [1, "some name"]
```

These can be made smaller and then be merged. Spaces are added automatically.

```
$qp1 = new QueryPiece("SELECT * FROM mytable");
$qp2 = new QueryPiece("WHERE id = ?", 1);
$qp3 = new QueryPiece("AND name = ?", "some name");

// produces the same object as the first example
$qp = QueryPiece::merge($qp1, $qp2, $qp3);
```

There's also a lot of static methods to make it look better, like `QueryPiece::Select(...)` which is the same as `new QueryPiece("SELECT ...")`.

### Formatters and Fields

[](#formatters-and-fields)

The `Formatter` and `Field` classes are very helpful tool for sanitizing input. They are quite useful in the `Table` class, explained later, but they are not restricted to that use.

A `Field` defines a pipeline of operations to be performed on a value. There's maps, replacements, options, type and class restrictions and type casts.

```
$pipe = new Field("name")
	->cast(Field::String)
	->in(["Hi", "Bye", "Hello", "Goodbye"])
	->replace([
		"Hi" => "Hello"
		"Bye" => "Goodbye"
	]),
	->map(fn($v) => $v . "!");

$pipe->pipeline("Hi"); // "Hello!"
$pipe->pipeline("Goodbye"); // "Goodbye!"
```

A `Formatter` is a just a set of those fields, but we can use new retrictions on those fields. Fields can be *optional* or *required*. If they are optional they can have a default value to be used in the pipeline. The `Formatter` can also take strings, those represent optional fields with no default and no pipeline.

```
$f = new Formatter(
	Field::default("first", 0),
	Field::required("second"),
	Field::optional("third")
);
```

Following this, you can call the formatting functions with some data. Note that formatting arrays and objects is the same, and they will be returned as such.

```
$data = ["unwanted key" => 0, "second" => 1];

$f->format($data); // ["first" => 0, "second" => 1]
$f->format((object)$data); // {"first": 0, "second": 1}
```

### Columns

[](#columns)

A `Column` class just holds a string, the name of the column. It can also specify if it is a primary column (also meaning unique), if it is unique, and if it is foreign. In the latter, it will hold a `Name` class referring to said foreign column.

```
$column = new Column("this_id")
	->primary()
	->foreign(new Name("db", "other_table", "other_id"));

echo $column // "this_id"
```

### Names

[](#names)

A `Name` is a class that holds a database, table, column name, and or alias. It can make a valid string for SQL to use, or just use the data internally.

For database, an `IConnection` is also accepted. For columns, a `Column` is also accepted.

Not all four are required, any combination will work. Be wary that some combinations don't make sense.

```
echo (new Name)
	->table("table")
	->alias("t") // `table` AS `t`

$fullname = new Name("database", "table", "column", "alias");

echo $fullname->db; // database
echo $fullname->table; // table
echo $fullname->column; // column
echo $fullname->alias; // alias
```

### Tables

[](#tables)

The `Table` is a *static* base class for any table. It implements many basic *static* functions, that are available for the subclasses.

The subclasses will need to implement one function, `connect`. There, the suclass will construct a `TableData` object and pass it to `initialize` along with the connection provided in `connect`.

Suppose we have a `mydb.person` table that has columns `id, name, age, fav_food`.

Construction

```
class Person extends Table {

	public static function connect(IConnection $conn) {
		// Note: if you don't need Column utilities,
		// you can use plain strings.
		$columns = [
			Column::make_primary("id"),
			"name",
			"age",
			"fav_food"
		];

		// forbids primary key insert
		$insert = new Formatter(
			"name",
			"age",
			Field::default("fav_food", "banana")
		);

		// also forbids name update
		$update = new Formatter(
			"age",
			"fav_food"
		);

		$data = (new TableData)
			->db("mydb")
			->name("person")
			->columns($columns)
			->on_insert($insert)
			->on_update($update);

		static::initialize($conn, $data);
	}
}

//...

$conn = get_my_connection();
Person::connect($conn);
```

The Table that execute a query on their own are public, so you can already call from outside, using any subclass. And always remember to `$conn->commit()`.

```
// $data can be put directly here, the formatter takes care of cleanup.
// Table and Connection take care statement preparation,
// which prevents SQL inyection.
$data = get_evil_raw_data();
Person::insert($data);
```

### Connections

[](#connections)

The Connection holds data necessary to connect to the database. It also prepares statements, passed as QueryPieces and it automatically uses a transaction model. The construction is the same as a normal mysqli class.

```
// Note: database is optional
$c = new Connection("host", "user", "password", "database");
```

But it **always** performs query preparation, and also has transaction managing functions exposed and used automatically as well. It starts a transaction in constructor, rolls back on any error and closes on destruction. It will not commit on its own, so you have to do it.

```
$qp = new QueryPiece(...);
$result = $c->execute($qp);
$c->commit();
$c->transaction();
$c->rollback();
```

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 96.4% 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 ~23 days

Recently: every ~90 days

Total

18

Last Release

1784d ago

Major Versions

v1.7.0 → v2.0.02021-03-22

v2.0.0 → v3.0.02021-06-20

### Community

Maintainers

![](https://www.gravatar.com/avatar/ed31e80ac855756b0b2e02c39e6e6e0692c134ec177e378bd19beeadf23ef271?d=identicon)[lushoBarlett](/maintainers/lushoBarlett)

---

Top Contributors

[![lushoBarlett](https://avatars.githubusercontent.com/u/37297979?v=4)](https://github.com/lushoBarlett "lushoBarlett (27 commits)")[![SebastianMestre](https://avatars.githubusercontent.com/u/36825825?v=4)](https://github.com/SebastianMestre "SebastianMestre (1 commits)")

---

Tags

databasequery

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lushobarlett-query-manager/health.svg)

```
[![Health](https://phpackages.com/badges/lushobarlett-query-manager/health.svg)](https://phpackages.com/packages/lushobarlett-query-manager)
```

###  Alternatives

[aura/sqlquery

Object-oriented query builders for MySQL, Postgres, SQLite, and SQLServer; can be used with any database connection library.

4572.9M34](/packages/aura-sqlquery)[envms/fluentpdo

FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.

925511.7k13](/packages/envms-fluentpdo)[lichtner/fluentpdo

FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.

921274.8k6](/packages/lichtner-fluentpdo)[bvanhoekelen/performance

PHP performance tool analyser your script on time, memory usage and db query. Support Laravel and Composer for web, web console and command line interfaces.

521774.3k4](/packages/bvanhoekelen-performance)[fpdo/fluentpdo

FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.

921244.9k7](/packages/fpdo-fluentpdo)[tpetry/laravel-query-expressions

Database-independent Query Expressions as a replacement to DB::raw calls

357436.5k2](/packages/tpetry-laravel-query-expressions)

PHPackages © 2026

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