PHPackages                             ray/query-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. [API Development](/categories/api)
4. /
5. ray/query-module

ActiveLibrary[API Development](/categories/api)

ray/query-module
================

An external media access framework

0.11.1(4mo ago)7315.2k↓34.5%5[1 issues](https://github.com/ray-di/Ray.QueryModule/issues)2MITPHPPHP ^8.2CI failing

Since May 16Pushed 4mo ago2 watchersCompare

[ Source](https://github.com/ray-di/Ray.QueryModule)[ Packagist](https://packagist.org/packages/ray/query-module)[ Docs](https://github.com/koriym/Koriym.PhpSkeleton)[ RSS](/packages/ray-query-module/feed)WikiDiscussions 1.x Synced 3d ago

READMEChangelog (10)Dependencies (22)Versions (23)Used By (2)

Ray.QueryModule
===============

[](#rayquerymodule)

[![codecov](https://camo.githubusercontent.com/af6b927f0121b4850737c7ec6cb5cc07af09bba11229c641cf490e30f4a8f2ca/68747470733a2f2f636f6465636f762e696f2f67682f7261792d64692f5261792e51756572794d6f64756c652f6272616e63682f312e782f67726170682f62616467652e7376673f746f6b656e3d363047324d46444f4252)](https://codecov.io/gh/ray-di/Ray.QueryModule)[![Type Coverage](https://camo.githubusercontent.com/d04a9856ae53d9a5c6073aeb8557a640d2416996139c69af8ea8f6f59b7f61ca/68747470733a2f2f73686570686572642e6465762f6769746875622f7261792d64692f5261792e51756572794d6f64756c652f636f7665726167652e737667)](https://shepherd.dev/github/ray-di/Ray.QueryModule)[![Continuous Integration](https://github.com/ray-di/Ray.QueryModule/workflows/Continuous%20Integration/badge.svg)](https://github.com/ray-di/Ray.QueryModule/workflows/Continuous%20Integration/badge.svg)

[Japanese](README.ja.md)

Overview
--------

[](#overview)

`Ray.QueryModule` makes a query to an external media such as a database or Web API with a function object to be injected.

- `SqlQueryModule` is for DB. Convert the SQL file to a simple function object that executes that SQL.
- `WebQueryModule` is for the Web API. Convert the URI and method set into a simple function object that Web requests to that URI.
- `PhpQueryModule` is a generic module. It provides storage access which can not be provided by static conversion by PHP function object.

Motivation
----------

[](#motivation)

- You can have a clear boundary between domain layer (usage code) and infrastructure layer (injected function) in code.
- Execution objects are generated automatically so you do not need to write procedural code for execution.
- Since usage codes are indifferent to the actual state of external media, storage can be changed later. Easy parallel development and stabbing.

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

[](#installation)

### Composer install

[](#composer-install)

```
$ composer require ray/query-module

```

### Module install

[](#module-install)

```
use Ray\Di\AbstractModule;
use Ray\Query\SqlQueryModule;

class AppModule extends AbstractModule
{
    protected function configure()
    {
        // SqlQueryModule install
        $this->install(new SqlQueryModule($sqlDir));

        // WebQueryModule install
        $webQueryConfig = [
            'post_todo' => ['POST', 'https://httpbin.org/todo'], // bind-name => [method, uri]
            'get_todo' => ['GET', 'https://httpbin.org/todo']
        ];
        $guzzleConfig = []; // @see http://docs.guzzlephp.org/en/stable/request-options.html
        $this->install(new WebQueryModule($webQueryConfig, $guzzleConfig));
    }
}
```

### SQL files

[](#sql-files)

$sqlDir/**todo\_insert.sql**

```
INSERT INTO todo (id, title) VALUES (:id, :title)
```

$sqlDir/**todo\_item\_by\_id.sql**

```
SELECT * FROM todo WHERE id = :id
```

Convert SQL to SQL invocation object
------------------------------------

[](#convert-sql-to-sql-invocation-object)

A callable object injected into the constructor. Those object was made in specified sql with `@Named` binding.

```
class Todo
{
    /**
     * @var callable
     */
    private $createTodo;

    /**
     * @var callable
     */
    private $todo;

    /**
     * @Named("createTodo=todo_insert, todo=todo_item_by_id")
     */
    public function __construct(
        callable $createTodo,
        callable $todo
    ){
        $this->createTodo = $createTodo;
        $this->todo = $todo;
    }

    public function get(string $uuid)
    {
        return ($this->todo)(['id' => $uuid]);
    }

    public function create(string $uuid, string $title)
    {
        ($this->createTodo)([
            'id' => $uuid,
            'title' => $title
        ]);
    }
}
```

Row or RowList
--------------

[](#row-or-rowlist)

You can specify expected return value type is either `Row` or `RowList` with `RowInterface` or `RowListInterface`. `RowInterface` is handy to specify SQL which return single row.

```
use Ray\Query\RowInterface;

class Todo
{
    /**
     * @Named("todo_item_by_id")
     */
    public function __construct(RowInterface $todo)
    {
        $this->todo = $todo;
    }

    public function get(string $uuid)
    {
        $todo = ($this->todo)(['id' => $uuid]); // single row data
    }
}
```

```
use Ray\Query\RowListInterface;

class Todos
{
    /**
     * @Named("todos")
     */
    public function __construct(RowListInterface $todos)
    {
        $this->todos = $todos;
    }

    public function get(string $uuid)
    {
        $todos = ($this->todos)(); // multiple row data
    }
}
```

Override the method with callable object
----------------------------------------

[](#override-the-method-with-callable-object)

Entire method invocation can be override with callable object in specified with `@Query`.

```
class Foo
{
    /**
     * @Query(id="todo_item_by_id")
     */
    public function get(string $id)
    {
    }
}
```

When parameter name is different method arguments and Query object arguments, uri\_template style expression can solve it.

```
class FooTempalted
{
    /**
     * @Query(id="todo_item_by_id?id={a}", templated=true)
     */
    public function get(string $a)
    {
    }
}
```

Specify `type='row'` when single row result is expected to return.

```
class FooRow
{
    /**
     * @Query(id="ticket_item_by_id", type="row")
     */
    public function onGet(string $id) : ResourceObject
    {
    }
}
```

If there is no SELECT result, it returns `404 Not Found`.

Convert URI to Web request object
---------------------------------

[](#convert-uri-to-web-request-object)

With `WebQueryModule`, it converts the URI bound in the configuration into an invocation object for web access and injects it. In the following example, an invocation object of `$createTodo` which makes` POST` request to `https://httpbin.org/todo` is injected as `$createTodo`.

```
use Ray\Di\AbstractModule;
use Ray\Query\SqlQueryModule;

class AppModule extends AbstractModule
{
    protected function configure()
    {
        // WebQueryModuleインストール
        $webQueryConfig = [
            'todo_post' => ['POST', 'https://httpbin.org/todo'],
            'todo_get' => ['GET', 'https://httpbin.org/todo']
        ];
        $guzzleConfig = [];
        $this->install(new WebQueryModule($webQueryConfig, $guzzleConfig));
    }
}
```

The usage code is the same as for `SqlQueryModule`.

```
/**
 * @Named("createTodo=todo_post, todo=todo_get")
 */
public function __construct(
    callable $createTodo,
    callable $todo
){
    $this->createTodo = $createTodo;
    $this->todo = $todo;
}
```

```
// POST
($this->createTodo)([
    'id' => $uuid,
    'title' => $title
]);

// GET
($this->todo)(['id' => $uuid]);
```

The usage code of `@Query` does not change either.

Bind to PHP class
-----------------

[](#bind-to-php-class)

If other dependencies are needed, we bind to PHP class and use dependency as a service.

```
class CreateTodo implements QueryInterface
{
    private $pdo;
    private $builder;

    public function __construct(PdoInterface $pdo, QueryBuilderInferface $builder)
    {
        $this->pdo = $pdo;
        $this->builder = $builder;
    }

    public function __invoke(array $query)
    {
        // Query execution using $pdo and $builder
        return $result;
    }
}
```

Bind to `callable`.

```
$this->bind('')->annotatedWith('cretate_todo')->to(CreateTodo::class); // callableはインターフェイスなし
```

The usage codes are the same. The usage code of `@Query` does not change either.

ISO8601 DateTime Module
-----------------------

[](#iso8601-datetime-module)

Convert the specified column name value to the [ISO8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. In PHP, it is a format defined by constants of [DateTime::ATOM](https://www.php.net/manual/en/class.datetime.php#datetime.constants.atom). Install date column names as an array and pass it as an argument to `Iso8601FormatModule`.

```
$this->install(new Iso8601FormatModule(['created_at', 'updated_at']));
```

SQL file name log
-----------------

[](#sql-file-name-log)

The SQL file name can be appended to the SQL statement as a comment. This is useful for query logging.

```
use Ray\Query\SqlFileName;
use Ray\Query\SqlQueryModule;

$this->install(new SqlQueryModule(__DIR__ . '/Fake/sql', null, new SqlFileName()));
```

Execute SQL

```
/* todo_item_by_id.sql */ SELECT * FROM todo WHERE id = :id
```

Demo
----

[](#demo)

```
php demo/run.php

```

BEAR.Sunday example
-------------------

[](#bearsunday-example)

- [Koriym.Ticketsan](https://github.com/koriym/Koriym.TicketSan/blob/master/src/Resource/App/Ticket.php)

###  Health Score

56

—

FairBetter than 97% of packages

Maintenance74

Regular maintenance activity

Popularity42

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 96.5% 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 ~158 days

Recently: every ~352 days

Total

19

Last Release

123d ago

Major Versions

0.11.0 → 1.x-dev2026-03-03

PHP version history (4 changes)0.1.0PHP &gt;=7.1.0

0.5.2PHP &gt;=7.2.0

0.6.0PHP ^7.3 || ^8.0

0.11.0PHP ^8.2

### 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 (248 commits)")[![KazuyaUchida](https://avatars.githubusercontent.com/u/86758002?v=4)](https://github.com/KazuyaUchida "KazuyaUchida (5 commits)")[![amashigeseiji](https://avatars.githubusercontent.com/u/1837070?v=4)](https://github.com/amashigeseiji "amashigeseiji (3 commits)")[![kseta](https://avatars.githubusercontent.com/u/1487865?v=4)](https://github.com/kseta "kseta (1 commits)")

---

Tags

repository

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3741.3M46](/packages/tencentcloud-tencentcloud-sdk-php)[ray/media-query

PHP interface-based SQL framework

11254.8k4](/packages/ray-media-query)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

273.0k](/packages/eslazarev-wildberries-sdk)[bear/package

BEAR.Sunday application framework package

31566.2k27](/packages/bear-package)

PHPackages © 2026

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