PHPackages                             dealnews/db - 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. dealnews/db

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

dealnews/db
===========

Database Library providing a PDO factory and CRUD operations

4.1.0(1mo ago)139514BSD-3-ClausePHPPHP ^8.2CI passing

Since Jul 5Pushed 1mo ago4 watchersCompare

[ Source](https://github.com/dealnews/db)[ Packagist](https://packagist.org/packages/dealnews/db)[ RSS](/packages/dealnews-db/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (12)Versions (26)Used By (4)

DealNews Datbase Library
========================

[](#dealnews-datbase-library)

Factory
-------

[](#factory)

The factory creates PDO objects using [DealNews\\GetConfig](https://github.com/dealnews/get-config) to read database settings (from `[app home]/etc/config.ini`) and create a PDO database connection.

### Supported Settings

[](#supported-settings)

SettingDescriptiontypeThis may be one of `pdo`, `mysql`, or `pgsql`. All types return PDO connections.dsnA valid PDO DSN. See each driver for specificsdbThe name of the database. For PDO, this is usually in the DSN.serverOne of more comma separated servers names. Not used by the `pdo` type.portServer port. Not used by the `pdo` type.userDatabase user name. Not all PDO drivers require one.passDatabase password. Not all PDO drivers require one.charsetCharacter set to use for `mysql` connections. The default is `utf8mb4`.optionsA JSON encoded array of options to pass to the PDO constructor. These vary by driver.### Example config.ini file

[](#example-configini-file)

This file should be stored in a directory named `etc` in the application's home directory.

```
db.mydb.type   = mysql
db.mydb.server = 127.0.0.1
db.mydb.user   = example
db.mydb.pass   = example
```

### Usage

[](#usage)

Example:

```
$mydb = \DealNews\DB\Factory::init("mydb");
```

CRUD
----

[](#crud)

The `CRUD` class is a helper that wraps up common PDO logic for CRUD operations.

### Basic Usage

[](#basic-usage)

```
$crud = \DealNews\DB\CRUD::factory('mydb');

// Create
$result = $crud->create(
    // table name
    "test",
    // data to add
    [
        "name"        => $name,
        "description" => $description,
    ]
);

// Read
$rows = $crud->read(
    // table name
    "test",
    // where clause data
    ["id" => $id]
);

// Update
$result = $crud->update(
    // table name
    "test",
    // data to update
    ["name" => "Test"],
    // where clause data
    ["id" => $id]
);

// Delete
$result = $crud->delete(
    // table name
    "test",
    // where clause data
    ["id" => $row["id"]]
);
```

### Advanced Usage

[](#advanced-usage)

The class also exposes a `run` method which is used internally by the other methods. Complex queries can be run using this method by providing an SQL query and a parameter array which will be mapped to the prepared query. It returns a PDOStatement object.

```
// Run a select with no parameters
$stmt = $crud->run("select * from table limit 10");

// Run a select query with paramters
$stmt = $crud->run(
    "select * from table where foo = :foo"
    [
        ":foo" => $foo
    ]
);
```

Data Mapper Pattern
-------------------

[](#data-mapper-pattern)

This library includes an abstract mapper class for creating [data mapper](https://en.wikipedia.org/wiki/Data_mapper_pattern)classes. The data mapper pattern separates the object from how it is stored. A [value object](https://en.wikipedia.org/wiki/Value_object)is created and a data mapper that is responsible for CRUD operations to and from a datastore.

```
// value object
class Book {
    public string $title = '';
    public string $author = '';
    public string $isbn = '';
}
```

```
// mapper
class BookMapper extends \DealNews\DB\AbstractMapper {

    public const DATABASE_NAME = 'example';

    public const TABLE = 'books';

    public const PRIMARY_KEY = 'isbn';

    public const MAPPED_CLASS = Book::class;

    public const MAPPING = [
        'title'  => [],
        'author' => [],
        'isbn'   => []
    ];
}
```

To load, save, delete, etc. the mapper is used like so.

```
$book = new Book();
$book->title = 'Professional PHP Programming';
$book->author = 'Jesus Castagnetto';
$book->isbn = '1-861002-96-3';

$mapper = new BookMapper();
$book = $mapper->save($book); // the entity is returned from save, reloaded from the database

// load a book
$book = $mapper->load('1-861002-96-3');

// delete a book
$mapper->delete('1-861002-96-3');

// find books based on author
$books = $mapper->find(['author' => 'Rasmus Lerdorf'], limit: 10, start: 0, order: 'title');
```

### Generating Value Objects and Mappers

[](#generating-value-objects-and-mappers)

This library includes a script for generating value objects and mappers. It has been tested and works with MySQL and PostgreSQL. Once installed in your project, the script can be run from the `vendor/bin` directory.

```
$ ./bin/create_objects.php -h

This script builds data objects and mappers.
USAGE:
  create_objects.php  -h | --db DBNAME | --namespace NAMESPACE | --table TABLE [--base-class CLASS] [--dir DIR] [--ini-file FILE] [-q] [--schema SCHEMA] [-v]

OPTIONS:
  --base-class  CLASS      Optional base class for value objects. See README
                           for recommendations.
  --db          DBNAME     Name of the databse configuration in config.ini
  --dir         DIR        Directory to write objects to. Defaults to `src`.
   -h                      Shows this help
  --ini-file    FILE       Alternate ini file to use. Defaults to
                           etc/config.ini.
  --namespace   NAMESPACE  Base namespace for objects.
   -q                      Be quiet. Will override -v
  --schema      SCHEMA     Name of the databse schema if different from the
                           database configuration name.
  --table       TABLE      Name of the databse table to create objects for.
   -v                      Be verbose. Additional v will increase verbosity.
                           e.g. -vvv

Copyright DealNews.com, Inc.  1997-2025
```

### Base Class for Value Objects

[](#base-class-for-value-objects)

This library will work with plan PHP classes that do not extend any other class. However, using a base class such as [Moonspot\\ValueObjects](https://github.com/brianlmoon/value-objects) can make working with the value objects easier.

Nested Mappers, Relational Data, and More
-----------------------------------------

[](#nested-mappers-relational-data-and-more)

Documentation coming

Query Builder
-------------

[](#query-builder)

The `Query` class provides a fluent interface for building complex SELECT queries with JOINs, subqueries, GROUP BY, HAVING, and more. It complements CRUD for queries that go beyond simple single-table operations.

### Basic Usage

[](#basic-usage-1)

```
$crud = \DealNews\DB\CRUD::factory('mydb');
$query = new \DealNews\DB\Util\Query($crud);

$query->select(['id', 'name', 'email'])
    ->from('users')
    ->where('status', '=', 'active')
    ->orderBy('created_at', 'DESC')
    ->limit(10);

$rows = $crud->runFetch($query->getSql(), $query->getParams());
```

### Complex Queries with JOINs

[](#complex-queries-with-joins)

```
$query = new \DealNews\DB\Util\Query($crud);

$query->select([
        'u.id',
        'u.name',
        \DealNews\DB\Util\Query::raw('COUNT(p.id) AS post_count'),
        \DealNews\DB\Util\Query::raw('AVG(p.views) AS avg_views'),
    ])
    ->from('users', 'u')
    ->leftJoin('posts', 'p', 'p.user_id', '=', 'u.id')
    ->leftJoin('profiles', 'pr', 'pr.user_id', '=', 'u.id')
    ->where('u.status', '=', 'active')
    ->where('pr.verified', '=', true)
    ->groupBy(['u.id', 'u.name'])
    ->having('post_count', '>', 5)
    ->orderBy('post_count', 'DESC')
    ->limit(20);

$rows = $crud->runFetch($query->getSql(), $query->getParams());
```

### Nested WHERE Conditions

[](#nested-where-conditions)

```
$query->select(['id'])
    ->from('users')
    ->where('status', '=', 'active')
    ->where(function ($q) {
        $q->where('role', '=', 'admin')
          ->orWhere('role', '=', 'moderator');
    });

// Generates: WHERE status = :p0 AND (role = :p1 OR role = :p2)
```

### Available Methods

[](#available-methods)

MethodDescription`select(array $columns)`Set SELECT columns`from(string $table, ?string $alias)`Set FROM table`join()`, `innerJoin()`, `leftJoin()`, `rightJoin()`Add JOIN clauses`where()`, `orWhere()`Add WHERE conditions`whereIn()`, `whereNotIn()`Add IN conditions`whereNull()`, `whereNotNull()`Add NULL checks`whereRaw(string $sql, array $params)`Add raw WHERE SQL`groupBy(array $columns)`Add GROUP BY`having()`, `orHaving()`Add HAVING conditions`orderBy(string $column, string $direction)`Add ORDER BY`limit(int $limit)`Set LIMIT`offset(int $offset)`Set OFFSET`getSql()`Build and return the SQL string`getParams()`Get the bound parameters`Query::raw(string $value, array $params)`Create a raw SQL fragmentTesting
-------

[](#testing)

By default, only unit tests are run. To run the functional tests the host machine will need to be a docker host. Also, the pdo\_pgsql, pdo\_mysql, and pdo\_sqlite extensions must be installed on the host machine. PHPUnit will start and stop docker containers to test the MySQL and Postgres connections. Use `--group functional` when running PHPUnit to run these tests.

###  Health Score

55

—

FairBetter than 98% of packages

Maintenance89

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 91.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 ~129 days

Recently: every ~41 days

Total

20

Last Release

58d ago

Major Versions

v1.2.0 → 2.0.02020-04-23

2.0.1 → 3.0.02023-11-20

3.4.0 → 4.0.02025-09-19

PHP version history (5 changes)v1.0PHP &gt;=7.1.0

2.0.0PHP ^7.3

3.0.0PHP ^8.0

3.4.0PHP ^8.1

4.0.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/49531?v=4)[Brian Moon](/maintainers/brianlmoon)[@brianlmoon](https://github.com/brianlmoon)

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

---

Top Contributors

[![brianlmoon](https://avatars.githubusercontent.com/u/49531?v=4)](https://github.com/brianlmoon "brianlmoon (84 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/dealnews-db/health.svg)

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

###  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)
