PHPackages                             reflexive/model - 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. reflexive/model

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

reflexive/model
===============

Active record-thingy models, database Schemas, automagically doing stuffs, in need of optimisation

01.1k—0%PHP

Since Mar 2Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/RobinDumontChaponet/ReflexiveModel)[ Packagist](https://packagist.org/packages/reflexive/model)[ RSS](/packages/reflexive-model/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

ReflexiveModel
==============

[](#reflexivemodel)

$$ {{∀ x ∈ X : x R x}} $$

---

An attribute-driven model layer that sits on top of `reflexive/query` (and `reflexive/core`).

It combines:

- schema inference from PHP attributes
- active-record style CRUD helpers
- model hydration and identity caching
- lazy or cached result collections
- SQL schema export from the inferred metadata

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

[](#requirements)

- PHP `^8.4`
- `ext-reflection`
- `reflexive/core`
- `reflexive/query`
- `psr/simple-cache`

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

[](#installation)

```
composer require reflexive/model
```

Defining a model
----------------

[](#defining-a-model)

Models extend `Reflexive\Model\Model` and are described with PHP attributes.

```
use Reflexive\Model\Model;
use Reflexive\Model\ModelId;
use Reflexive\Model\Table;
use Reflexive\Model\Property;
use Reflexive\Model\Column;

#[Table('users')]
final class User extends Model
{
	use ModelId;

	#[Property]
	#[Column('email_address', type: 'VARCHAR(255)')]
	protected string $email;

	#[Property]
	#[Column] // using defaults from type and default value
	protected bool $active = true;
}
```

Key attributes and helpers:

- `#[Table(...)]` defines table-level metadata, inheritance rules, and super/sub-type flags.
- `#[Property(...)]` marks protected properties as managed, optionally generating getters/setters.
- `#[Column(...)]` maps a property to a database column and can declare id, type, nullability, defaults, and auto-increment.
- `#[Reference(...)]` describes object relationships.
- `ModelId` adds a conventional auto-increment `id` property.
- `ModelEnum` adapts PHP enums to the same CRUD API shape.

Generated accessors and dirty tracking
--------------------------------------

[](#generated-accessors-and-dirty-tracking)

Managed properties are accessed through `__get()`, `__set()`, and generated methods created from `#[Property]`.

By default:

- `#[Property]` creates a getter and setter
- setting a different value marks the property as modified
- read-only properties are enforced by the model layer

The write path is then used by `create()` and `update()` to decide which columns should be sent to SQL.

CRUD API
--------

[](#crud-api)

Every model gets static builders:

- `::create(Model $model)`
- `::read(...)`
- `::search(...)`
- `::update(Model $model)`
- `::delete(Model $model)`
- `::count()`

Example:

```
use Reflexive\Core\Condition;

$user = new User();
$user->setEmail('person@example.com');

User::create($user)->execute($pdo);

$loaded = User::read()->where(Condition::EQUAL('id', $user->id))->execute($pdo);

$matches = User::search()->where(Condition::EQUAL('active', true))
	->limit(50)
	->execute($pdo);
```

The read/search/count builders translate model property names into real table and column names using `Schema`.

Relationships
-------------

[](#relationships)

`#[Reference]` metadata lets the model layer turn object-level conditions into SQL joins or foreign-key predicates.

Supported cardinalities:

- `OneToOne`
- `OneToMany`
- `ManyToOne`
- `ManyToMany`

At runtime, references are hydrated into:

- a single related model (or enum)
- a lazily-backed `ModelCollection`

For many-to-many updates, `Push` builds extra insert/update/delete statements for the join table based on collection changes.

Hydration and collections
-------------------------

[](#hydration-and-collections)

`Hydrator` is responsible for turning rows into model instances and caching them by model id.

Notable behavior:

- repeated reads of the same id can reuse cached objects
- sub-types can be resolved through the internal `reflexive_subType` field
- references may be loaded lazily using PHP lazy ghosts/proxies

`ModelCollection` wraps either a `PDOStatement` or a `Reflexive\Query\Composed` query and implements:

- `Iterator`
- `ArrayAccess`
- `Countable`
- `JsonSerializable`

It can auto-execute, cache fetched objects, and track added/modified/removed keys for relationship syncing.

Schema inspection and export
----------------------------

[](#schema-inspection-and-export)

`Schema::initFromAttributes()` reflects a model class and builds the runtime mapping used by the whole package.

Useful entry points:

- `Schema::getSchema(FQCN)` to fetch the inferred schema
- `Schema::dumpSQL()` to generate SQL for all discovered models
- `Schema::exportSQL()` to print that SQL directly

The generated SQL is aimed at MySQL/MariaDB-style schemas and includes foreign-key creation statements.

Rough edges
-----------

[](#rough-edges)

- Some inheritance and reference flows are implemented, but they are opinionated and tightly coupled to the inferred schema layout.

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance58

Moderate activity, may be stable

Popularity18

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity25

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/34f6b38d1f65b58df4307dbdae9c274233181bb737b4098a817d85f19312b63a?d=identicon)[RobinDumontChaponet](/maintainers/RobinDumontChaponet)

---

Top Contributors

[![RobinDumontChaponet](https://avatars.githubusercontent.com/u/9157490?v=4)](https://github.com/RobinDumontChaponet "RobinDumontChaponet (189 commits)")

---

Tags

daodatabasemodelspdophp8work-in-progress

### Embed Badge

![Health badge](/badges/reflexive-model/health.svg)

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

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

90440.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)
