PHPackages                             ray/aura-sql-module - 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. ray/aura-sql-module

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

ray/aura-sql-module
===================

aura/sql module for Ray.Di

1.17.1(2mo ago)8419.3k—8.8%166MITPHPPHP ^8.1CI passing

Since Dec 24Pushed 2mo ago4 watchersCompare

[ Source](https://github.com/ray-di/Ray.AuraSqlModule)[ Packagist](https://packagist.org/packages/ray/aura-sql-module)[ RSS](/packages/ray-aura-sql-module/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (10)Dependencies (22)Versions (56)Used By (6)

Ray.AuraSqlModule
=================

[](#rayaurasqlmodule)

[![codecov](https://camo.githubusercontent.com/0023a9b111f8c3066d33ae331b9cd4fdfd33f68269487560cdf27adfb212f67c/68747470733a2f2f636f6465636f762e696f2f67682f7261792d64692f5261792e4175726153716c4d6f64756c652f6272616e63682f312e782f67726170682f62616467652e7376673f746f6b656e3d6763576166747a6f5870)](https://codecov.io/gh/ray-di/Ray.AuraSqlModule)[![Type Coverage](https://camo.githubusercontent.com/3b1889854cc9321e245b2488894f1fc889031d08338c53ad89a7a10f2009470f/68747470733a2f2f73686570686572642e6465762f6769746875622f7261792d64692f5261792e4175726153716c4d6f64756c652f636f7665726167652e737667)](https://shepherd.dev/github/ray-di/Ray.AuraSqlModule)[![Continuous Integration](https://github.com/ray-di/Ray.AuraSqlModule/actions/workflows/continuous-integration.yml/badge.svg?branch=2.x)](https://github.com/ray-di/Ray.AuraSqlModule/actions/workflows/continuous-integration.yml)

An [Aura.Sql](https://github.com/auraphp/Aura.Sql) Module for [Ray.Di](https://github.com/koriym/Ray.Di)

Installation
------------

[](#installation)

```
composer require ray/aura-sql-module
```

Getting started
---------------

[](#getting-started)

### Module install

[](#module-install)

```
use Ray\Di\AbstractModule;
use Ray\AuraSqlModule\AuraSqlModule;
use Ray\AuraSqlModule\AuraSqlQueryModule;

class AppModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(
            new AuraSqlModule(
                'mysql:host=localhost;dbname=test',
                'username',
                'password',
                'slave1,slave2,slave3', // optional slave server list
                $options,               // optional key=>value array of driver-specific connection options
                $queries                // Queries to execute after the connection.
            )
        );
    }
}
```

Use AuraSqlEnvModule to get the value from the environment variable each time at runtime, instead of specifying the value directly.

```
$this->install(
    new AuraSqlEnvModule(
        'PDO_DSN',             // getenv('PDO_DSN')
        'PDO_USER',            // getenv('PDO_USER')
        'PDO_PASSWORD',        // getenv('PDO_PASSWORD')
        'PDO_SLAVE',           // getenv('PDO_SLAVE')
        $options,              // optional key=>value array of driver-specific connection options
        $queries               // Queries to execute after the connection.
    )
);
```

Replication
-----------

[](#replication)

Installing `AuraSqlReplicationModule` using a `connection locator` for master/slave connections.

```
use Ray\Di\AbstractModule;
use Ray\AuraSqlModule\AuraSqlModule;
use Aura\Sql\ConnectionLocator;
use Aura\Sql\Connection;

class AppModule extends AbstractModule
{
    protected function configure()
    {
        $locator = new ConnectionLocator;
        $locator->setWrite('master', new Connection('mysql:host=localhost;dbname=master', 'id', 'pass'));
        $locator->setRead('slave1',  new Connection('mysql:host=localhost;dbname=slave1', 'id', 'pass'));
        $locator->setRead('slave2',  new Connection('mysql:host=localhost;dbname=slave2', 'id', 'pass'));
        $this->install(new AuraSqlReplicationModule($locator));
    }
}
```

You will now have a slave db connection when using HTTP GET, or a master db connection in other HTTP methods.

Multiple DB
-----------

[](#multiple-db)

You may want to inject different connection destinations on the same DB interface with `#[Named($qualifier)]` attribute. Two modules are provided. `NamedPdoModule` is for non replication use. and `AuraSqlReplicationModule` is for replication use.

```
#[Inject]
public function setLoggerDb(#[Named('log_db')] ExtendedPdoInterface $pdo)
{
    // ...
}
```

### with no replication

[](#with-no-replication)

Use `NamedPdoModule ` to inject different named `Pdo` instance for **non** Replication use. For instance, This module install `log_db` named `Pdo` instance.

```
class AppModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new NamedPdoModule('log_db', 'mysql:host=localhost;dbname=log', 'username', 'password'));
    }
}
```

Or

```
class AppModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new NamedPdoEnvModule('log_db', 'LOG_DSN', 'LOG_USERNAME', 'LOG_PASSWORD'));
    }
}
```

### with replication

[](#with-replication)

You can set `$qualifier` in 2nd parameter of AuraSqlReplicationModule.

```
class AppModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new AuraSqlReplicationModule($locator, 'log_db'));
    }
}
```

Transaction
-----------

[](#transaction)

Any method marked with `#[Transactional]` will have a transaction started before, and ended after it is called.

```
use Ray\AuraSqlModule\Annotation\WriteConnection; // important
use Ray\AuraSqlModule\Annotation\Transactional;   // important

class User
{
    public $pdo;

    #[WriteConnection, Transactional]
    public function write()
    {
         // $this->pdo->rollback(); when exception thrown.
    }
}
```

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

[](#query-builder)

[Aura.SqlQuery](https://github.com/auraphp/Aura.SqlQuery) provides query builders for MySQL, Postgres, SQLite, and Microsoft SQL Server. Following four interfaces are bound and can be injected via constructor:

- `Aura\SqlQuery\Common\SelectInterface`
- `Aura\SqlQuery\Common\InsertInterface`
- `Aura\SqlQuery\Common\UpdateInterface`
- `Aura\SqlQuery\Common\DeleteInterface`

```
use Aura\SqlQuery\Common\SelectInterface;
use Aura\Sql\ExtendedPdoInterface;

class UserRepository
{
    public function __construct(
        private readonly SelectInterface $select,
        private readonly ExtendedPdoInterface $pdo
    ) {}

    public function findById(int $id): array
    {
        $statement = $this->select
            ->distinct()                    // SELECT DISTINCT
            ->cols([                        // select these columns
                'id',                       // column name
                'name AS namecol',          // one way of aliasing
                'col_name' => 'col_alias',  // another way of aliasing
                'COUNT(foo) AS foo_count'   // embed calculations directly
            ])
            ->from('users AS u')            // FROM these tables
            ->where('id = :id')
            ->getStatement();

        return $this->pdo->fetchAssoc($statement, ['id' => $id]);
    }
}
```

### Multiple Query Builders

[](#multiple-query-builders)

```
use Aura\SqlQuery\Common\SelectInterface;
use Aura\SqlQuery\Common\InsertInterface;
use Aura\SqlQuery\Common\UpdateInterface;
use Aura\Sql\ExtendedPdoInterface;

class UserService
{
    public function __construct(
        private readonly SelectInterface $select,
        private readonly InsertInterface $insert,
        private readonly UpdateInterface $update,
        private readonly ExtendedPdoInterface $pdo
    ) {}

    public function createUser(array $userData): int
    {
        $statement = $this->insert
            ->into('users')
            ->cols($userData)
            ->getStatement();

        $this->pdo->perform($statement, $this->insert->getBindValues());

        return (int) $this->pdo->lastInsertId();
    }

    public function updateUser(int $id, array $userData): bool
    {
        $statement = $this->update
            ->table('users')
            ->cols($userData)
            ->where('id = :id')
            ->bindValue('id', $id)
            ->getStatement();

        return $this->pdo->perform($statement, $this->update->getBindValues());
    }
}
```

Pagination
----------

[](#pagination)

Pagination service is provided for both `ExtendedPdo` raw sql and `Select` query builder.

**ExtendedPdo**

```
use Ray\AuraSqlModule\Pagerfanta\AuraSqlPagerFactoryInterface;
use Aura\Sql\ExtendedPdoInterface;

class UserListService
{
    public function __construct(
        private readonly AuraSqlPagerFactoryInterface $pagerFactory,
        private readonly ExtendedPdoInterface $pdo
    ) {}

    public function getUserList(int $page): Page
    {
        $sql = 'SELECT * FROM users WHERE active = :active';
        $params = ['active' => 1];
        $pager = $this->pagerFactory->newInstance($this->pdo, $sql, $params, 10, '/?page={page}&category=users');

        return $pager[$page];
    }
}
```

**Select query builder**

```
use Ray\AuraSqlModule\Pagerfanta\AuraSqlQueryPagerFactoryInterface;
use Aura\SqlQuery\Common\SelectInterface;
use Aura\Sql\ExtendedPdoInterface;

class ProductListService
{
    public function __construct(
        private readonly AuraSqlQueryPagerFactoryInterface $queryPagerFactory,
        private readonly SelectInterface $select,
        private readonly ExtendedPdoInterface $pdo
    ) {}

    public function getProductList(int $page, string $category): Page
    {
        $select = $this->select
            ->from('products')
            ->where('category = :category')
            ->bindValue('category', $category);

        $pager = $this->queryPagerFactory->newInstance($this->pdo, $select, 10, '/?page={page}&category=' . $category);

        return $pager[$page];
    }
}
```

An array access with page number returns `Page` value object.

```
/* @var Pager \Ray\AuraSqlModule\Pagerfanta\Page */

// $page->data // sliced data
// $page->current;
// $page->total
// $page->hasNext
// $page->hasPrevious
// $page->maxPerPage;
// (string) $page // pager html
```

It is iterable.

```
foreach ($page as $item) {
    // ...
}
```

### View

[](#view)

The view template can be changed with binding. See more at [Pagerfanta](https://github.com/whiteoctober/Pagerfanta#views).

```
use Pagerfanta\View\Template\TemplateInterface;
use Pagerfanta\View\Template\TwitterBootstrap3Template;
use Ray\AuraSqlModule\Annotation\PagerViewOption;

$this->bind(TemplateInterface::class)->to(TwitterBootstrap3Template::class);
$this->bind()->annotatedWith(PagerViewOption::class)->toInstance($pagerViewOption);
```

Profile
-------

[](#profile)

To log SQL execution, install `AuraSqlProfileModule`. It will be logged by a logger bound to the [PSR-3](https://www.php-fig.org/psr/psr-3/) logger. This example binds a minimal function logger created in an anonymous class.

```
class DevModule extends AbstractModule
{
    protected function configure()
    {
        // ...
        $this->install(new AuraSqlProfileModule());
        $this->bind(LoggerInterface::class)->toInstance(
            new class extends AbstractLogger {
                /** @inheritDoc */
                public function log($level, $message, array $context = [])
                {
                    $replace = [];
                    foreach ($context as $key => $val) {
                        if (! is_array($val) && (! is_object($val) || method_exists($val, '__toString'))) {
                            $replace['{' . $key . '}'] = $val;
                        }
                    }

                    error_log(strtr($message, $replace));
                }
            }
        );
    }
}
```

###  Health Score

65

—

FairBetter than 99% of packages

Maintenance86

Actively maintained with recent releases

Popularity45

Moderate usage in the ecosystem

Community29

Small or concentrated contributor base

Maturity85

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 95.8% 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 ~75 days

Recently: every ~30 days

Total

55

Last Release

67d ago

PHP version history (9 changes)1.2.0PHP &gt;=5.5.0

1.5.0PHP ~5.6|~7.0

1.6.4PHP &gt;=7.0.0

1.8.0PHP &gt;=7.2

1.9.0PHP ^7.3 || ^8.0

1.11.0PHP ^7.4 || ^8.0

1.14.0PHP ^8.4

1.13.4PHP ^8.0

1.17.0PHP ^8.1

### Community

Maintainers

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

---

Top Contributors

[![koriym](https://avatars.githubusercontent.com/u/529021?v=4)](https://github.com/koriym "koriym (530 commits)")[![jingu](https://avatars.githubusercontent.com/u/892913?v=4)](https://github.com/jingu "jingu (5 commits)")[![yutakachiba](https://avatars.githubusercontent.com/u/5999747?v=4)](https://github.com/yutakachiba "yutakachiba (3 commits)")[![fiahfy](https://avatars.githubusercontent.com/u/7123916?v=4)](https://github.com/fiahfy "fiahfy (3 commits)")[![piotzkhider](https://avatars.githubusercontent.com/u/7950487?v=4)](https://github.com/piotzkhider "piotzkhider (3 commits)")[![kuma-guy](https://avatars.githubusercontent.com/u/7978290?v=4)](https://github.com/kuma-guy "kuma-guy (2 commits)")[![apple-x-co](https://avatars.githubusercontent.com/u/8497012?v=4)](https://github.com/apple-x-co "apple-x-co (2 commits)")[![inaka-phper](https://avatars.githubusercontent.com/u/13147509?v=4)](https://github.com/inaka-phper "inaka-phper (2 commits)")[![exsuzukishuhei](https://avatars.githubusercontent.com/u/3086888?v=4)](https://github.com/exsuzukishuhei "exsuzukishuhei (1 commits)")[![momospnr](https://avatars.githubusercontent.com/u/1066913?v=4)](https://github.com/momospnr "momospnr (1 commits)")[![MugeSo](https://avatars.githubusercontent.com/u/250446?v=4)](https://github.com/MugeSo "MugeSo (1 commits)")

---

Tags

auradatabaseray-modulesqlpdoAura SqlRay module

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ray-aura-sql-module/health.svg)

```
[![Health](https://phpackages.com/badges/ray-aura-sql-module/health.svg)](https://phpackages.com/packages/ray-aura-sql-module)
```

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k578.4M5.6k](/packages/doctrine-dbal)[kimai/kimai

Kimai - Time Tracking

4.6k7.4k1](/packages/kimai-kimai)[aura/sql

A PDO extension that provides lazy connections, array quoting, query profiling, value binding, and convenience methods for common fetch styles. Because it extends PDO, existing code that uses PDO can use this without any changes to the existing code.

5632.5M43](/packages/aura-sql)[tommyknocker/pdo-database-class

Framework-agnostic PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, and Oracle. Query Builder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord, CLI tools, AI-powered analysis. Zero external dependencies.

845.7k](/packages/tommyknocker-pdo-database-class)[ray/media-query

PHP interface-based SQL framework

11220.7k2](/packages/ray-media-query)[noahheck/e_pdostatement

Drop in replacement for default PDOStatement class allowing devs to view an interpolated version of a parameterized query

5121.2k](/packages/noahheck-e-pdostatement)

PHPackages © 2026

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