PHPackages                             webware/webware-resultset - 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. webware/webware-resultset

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

webware/webware-resultset
=========================

Result set system for Webware

0.1.0(1mo ago)04↓50%[1 PRs](https://github.com/webinertia/webware-resultset/pulls)BSD-3-ClausePHPPHP ~8.3.0 || ~8.4.1 || ~8.5.0CI passing

Since Jun 26Pushed 1mo agoCompare

[ Source](https://github.com/webinertia/webware-resultset)[ Packagist](https://packagist.org/packages/webware/webware-resultset)[ RSS](/packages/webware-webware-resultset/feed)WikiDiscussions 0.1.x Synced 2w ago

READMEChangelog (1)Dependencies (4)Versions (3)Used By (0)

webware-resultset
=================

[](#webware-resultset)

[![PHP Version](https://camo.githubusercontent.com/66045fdfea301acd9f0eda4131d6f3ebb65f32c028844d1c453a4605d05357f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d7e382e342532302537432537432532307e382e352d626c7565)](https://www.php.net/)[![Mago](https://camo.githubusercontent.com/75882bfde446730982e38410cc22526722cb5fa90e0342a0542637968fd0ee01/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61676f2d7374726963742d627269676874677265656e)](mago.toml)[![License](https://camo.githubusercontent.com/e32287373926ec416e0928698ca4471080dc41437461969806bcfe2df245e480/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4253442d2d332d2d436c617573652d677265656e)](LICENSE)

A ResultSet implementation for [PhpDb](https://github.com/php-db/phpdb) that delegates row object creation to the prototype's `withRowData()` method.

Overview
--------

[](#overview)

`webware-resultset` extends PhpDb's ResultSet system with a prototype-driven row population strategy. The standard `HydratingResultSet` **clones** the row prototype and calls `exchangeArray()` on each clone — the ResultSet controls object creation. `WithRowDataResultSet` instead calls `withRowData(array $data)` on the prototype, and the **prototype controls** how each row object is created and populated.

The prototype acts as a factory: it receives raw row data and returns a populated row object. The ResultSet never clones the prototype — the prototype implementation decides the creation strategy (`new static()`, a factory method, etc.).

This pattern is useful when:

- Row classes need to control their own instantiation (constructor injection, validation, transformation).
- You want a single `withRowData()` method to handle both hydration and creation, rather than a separate clone step.
- Your row objects have constructor dependencies that can't be satisfied by cloning.

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

[](#installation)

```
composer require webware/webware-resultset
```

Requirements
------------

[](#requirements)

- [php-db/phpdb](https://github.com/php-db/phpdb) ^0.6.0 (dev dependency — provides the base `AbstractResultSet`)

Components
----------

[](#components)

### `WithRowDataPrototypeInterface`

[](#withrowdataprototypeinterface)

```
namespace Webware\ResultSet;

use PhpDb\ResultSet\RowPrototypeInterface;

interface WithRowDataPrototypeInterface extends RowPrototypeInterface
{
    /**
     * @param array $withRowData
     */
    public function withRowData(array $withRowData): static;
}
```

Extends PhpDb's `RowPrototypeInterface` and adds a `withRowData()` method. Row prototype classes must implement this interface to be used with `WithRowDataResultSet`.

The `withRowData()` method receives raw row data as an associative array and returns a populated row object (`static`). The prototype acts as a factory — it is not mutated by the ResultSet. The implementation decides how row objects are created: via `new static()`, a clone, or any other strategy.

### `WithRowDataResultSet`

[](#withrowdataresultset)

```
final class WithRowDataResultSet extends AbstractResultSet
```

A concrete, `final` ResultSet that overrides three methods from `AbstractResultSet`:

MethodBehavior`current(): ?WithRowDataPrototypeInterface`Calls `parent::current()`. If the result is an array, passes it to `getRowPrototype()->withRowData($data)` and returns the row object produced by the prototype. Returns `null` otherwise.`setRowPrototype(...)`Accepts only `WithRowDataPrototypeInterface` instances. Throws `InvalidArgumentException` if given a plain `ArrayObject` or `RowPrototypeInterface`.`getRowPrototype()`Returns the prototype with narrowed type `WithRowDataPrototypeInterface` (instead of `?object`).All other ResultSet behavior — initialization, buffering, iteration, counting, `toArray()` — is inherited unchanged from `AbstractResultSet`.

Usage
-----

[](#usage)

### 1. Create a row prototype

[](#1-create-a-row-prototype)

```
use Webware\ResultSet\WithRowDataPrototypeInterface;

final class UserRow implements WithRowDataPrototypeInterface
{
    public function __construct(
        public readonly int $id = 0,
        public readonly string $name = '',
        public readonly string $email = '',
    ) {}

    public function withRowData(array $withRowData): static
    {
        return new self(
            id:    (int) ($withRowData['id'] ?? 0),
            name:  (string) ($withRowData['name'] ?? ''),
            email: (string) ($withRowData['email'] ?? ''),
        );
    }

    public function exchangeArray(array $array): array
    {
        return $this->withRowData($array)->toArray();
    }

    /** @return array */
    public function toArray(): array
    {
        return [
            'id'    => $this->id,
            'name'  => $this->name,
            'email' => $this->email,
        ];
    }
}
```

### 2. Use the ResultSet

[](#2-use-the-resultset)

```
use Webware\ResultSet\WithRowDataResultSet;

$resultSet = new WithRowDataResultSet(new UserRow());

// Initialize with query results (array of rows)
$resultSet->initialize([
    ['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
    ['id' => 2, 'name' => 'Bob',   'email' => 'bob@example.com'],
]);

foreach ($resultSet as $user) {
    echo $user->name; // Alice, then Bob
    // $user is a new UserRow instance each iteration, created by withRowData()
}
```

### 3. Changing the row prototype at runtime

[](#3-changing-the-row-prototype-at-runtime)

```
$resultSet->setRowPrototype(new AdminRow());

// Throws InvalidArgumentException — plain RowPrototypeInterface is rejected:
$resultSet->setRowPrototype(new ArrayObject());
```

Development
-----------

[](#development)

```
# Install dependencies
composer install

# Run all checks (coding standard, static analysis, tests)
composer check-all

# Individual checks
composer cs-check       # PHP-CS-Fixer
composer sa             # PHPStan static analysis
composer test           # PHPUnit
composer test-coverage  # PHPUnit with coverage report
```

License
-------

[](#license)

BSD 3-Clause License. See [LICENSE](LICENSE) for details.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance90

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

2

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4d6eed33e61a99f1147789696252f4523130b5035a19eb07e034a7407fd44548?d=identicon)[tyrsson](/maintainers/tyrsson)

---

Top Contributors

[![tyrsson](https://avatars.githubusercontent.com/u/1237487?v=4)](https://github.com/tyrsson "tyrsson (21 commits)")

---

Tags

phpdbwebwareresultSet

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/webware-webware-resultset/health.svg)

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

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k6.0M772](/packages/sylius-sylius)[infection/infection

Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.

2.2k30.0M2.8k](/packages/infection-infection)[ssch/typo3-rector

Instant fixes for your TYPO3 PHP code by using Rector.

2613.3M487](/packages/ssch-typo3-rector)[driftingly/rector-laravel

Rector upgrades rules for Laravel Framework

1.3k16.7M899](/packages/driftingly-rector-laravel)[rector/rector-src

Instant Upgrade and Automated Refactoring of any PHP code

136411.0k14](/packages/rector-rector-src)[phparkitect/phparkitect

Enforce architectural constraints in your PHP applications

9244.5M32](/packages/phparkitect-phparkitect)

PHPackages © 2026

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