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(yesterday)04↑2900%[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 todayCompare

[ 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 today

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

40

—

FairBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity5

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

1d 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

[driftingly/rector-laravel

Rector upgrades rules for Laravel Framework

1.2k14.2M669](/packages/driftingly-rector-laravel)[ssch/typo3-rector

Instant fixes for your TYPO3 PHP code by using Rector.

2603.0M382](/packages/ssch-typo3-rector)[theofidry/alice-data-fixtures

Nelmio alice extension to persist the loaded fixtures.

32329.4M88](/packages/theofidry-alice-data-fixtures)[rector/rector-src

Instant Upgrade and Automated Refactoring of any PHP code

136400.8k14](/packages/rector-rector-src)[sylius/grid-bundle

Amazing grids with support of filters and custom fields integrated into Symfony.

1338.7M56](/packages/sylius-grid-bundle)[ahmed-bhs/doctrine-doctor

Runtime analysis tool for Doctrine ORM integrated into Symfony Web Profiler. Unlike static linters, it analyzes actual query execution at runtime to detect performance bottlenecks, security vulnerabilities, and best practice violations during development with real execution context and data.

939.0k](/packages/ahmed-bhs-doctrine-doctor)

PHPackages © 2026

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