PHPackages                             csrdelft/orm - 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. csrdelft/orm

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

csrdelft/orm
============

The creatively named object-relational mapping library for csrdelft.nl

v1.9.0(6y ago)32721[13 issues](https://github.com/csrdelft/orm/issues)MITPHPPHP &gt;=7.0.27

Since Feb 7Pushed 6y ago5 watchersCompare

[ Source](https://github.com/csrdelft/orm)[ Packagist](https://packagist.org/packages/csrdelft/orm)[ Docs](https://csrdelft.github.io/orm)[ RSS](/packages/csrdelft-orm/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (10)Dependencies (5)Versions (25)Used By (0)

[![Maintainability Rating](https://camo.githubusercontent.com/1ea0adce6bf8addbe48d83a8487f359355a18f35f53d4c9389283e8caa21a0b8/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d63737264656c66745f6f726d266d65747269633d7371616c655f726174696e67)](https://sonarcloud.io/dashboard?id=csrdelft_orm)[![Coverage](https://camo.githubusercontent.com/357e0d7421dd6d0ed49e8ed5ae057418f8576c41f9e2d88fcff0b42ac0aa41f9/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d63737264656c66745f6f726d266d65747269633d636f766572616765)](https://sonarcloud.io/dashboard?id=csrdelft_orm)[![Build Status](https://camo.githubusercontent.com/5dbe09de84caa6c2787bcc98109c7d88ea01cbe9523d72305b846afac8e60827/68747470733a2f2f7472617669732d63692e6f72672f63737264656c66742f6f726d2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/csrdelft/orm)

C.S.R. Delft ORM
================

[](#csr-delft-orm)

A simple object-relational mapper for PHP. We currently use this library in production on [csrdelft.nl](https://csrdelft.nl).

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

[](#installation)

Install with composer

```
composer require csrdelft/orm

```

Before the ORM can be used the cache and database must be initialized. The memcache needs a unix socket or host and port and the database and database admin need a host, database, username and password. After this any model has access to the database.

```
CsrDelft\Orm\Configuration::load([
  'cache_path' => '/path/to/data/dir/cache.socket', // Host or unix socket
  'cache_port' => 11211, // Optional if cache_path is a host
  'db' => [
    'host' => 'localhost',
    'db' => 'myDatabase',
    'user' => 'myUser',
    'pass' => 'myPass'
  ]
]);
```

Usage
-----

[](#usage)

The ORM relies on models and entities. Models are classes which interface with the database. Entities are data classes which contain a definition for the database tables. This document will give a brief overview of the basic things you need to know in order to get started.

### Entity

[](#entity)

An entity is an object containing data, like for instance a car, person, etc.

When you want to save an entity to the database, you'll have to extend the class `PersistentEntity`. An entity must contain a few variables, which are discussed below. An entity must only contain logic about itself, not logic about other classes or about other instances of the same entity. This should be in the Model (or the controller which is not part of this library).

Entities are placed in the folder `model/entity/` and are named `EntityName.php`.

#### Variables in an entity

[](#variables-in-an-entity)

For each attribute of an entity there must be a public variable. These will be used by the model when loading from a database.

```
public $id;
public $num_wheels;
public $color;
```

##### `$table_name`

[](#table_name)

The name of the table in the database.

```
protected static $table_name = 'cars';
```

##### `$persistent_attributes`

[](#persistent_attributes)

An array of attributes of the entity, mapped to a type.

A Type is an array, with the following values.

- 0: Type from `T` (`PersistentAttributeType.enum`)
- 1: Is this variable nullable?
- 2: If 0 is `T::Enumeration`, the enum class (extends `PersistentEnum`). Else 'extra', for instance `auto_increment` or comment.

```
protected static $persistent_attributes = [
  'id' => [T::Integer, false, 'auto_increment'],
  'num_wheels' => [T::Integer],
  'color' => [T::Enumeration, false, 'ColorEnum']
];
```

##### `$primary_key`

[](#primary_key)

An array with the full primary key.

```
protected static $primary_key = ['id'];
```

##### `$computed_attributes`

[](#computed_attributes)

An array of computed attributes. This maps these attributes to a function and adds them to `jsonSerialize`

```
protected static $computed_attributes = [
  'my_val' => [T::Integer],
];

protected function getMyVal() {
  return 42;
}
```

#### Example

[](#example)

**`model/entities/Car.php`**

```
class Car extends PersistentEntity {
  public $id;
  public $num_wheels;
  public $color;

  public function carType() {
    if ($this->num_wheels == 4) {
      return "Normal car";
    } else {
      return "Weird car";
    }
  }

  protected static $table_name = 'cars';
  protected static $persistent_attributes = [
    'id' => [T::Integer, false, 'auto_increment'],
    'num_wheels' => [T::Integer],
    'color' => [T::Enumeration, false, 'ColorEnum']
  ];
  protected static $primary_key = ['id'];
}
```

### Model

[](#model)

A model has to extend the `PersistenceModel` class. A model is the owner of a specific entity. A model can be accessed everywhere with the public static `instance()` method. This should however be avoided where possible.

Models should be placed in `model/`.

#### Variables in a model

[](#variables-in-a-model)

A model has a few static variables which must be defined.

##### `ORM`

[](#orm)

The constant `ORM` defines which entity this model is the owner of. This is a string or class.

```
const ORM = 'Car';
```

```
const ORM = Car::class;
```

##### `$default_order`

[](#default_order)

This is the default value to use for the order when selecting from the database.

```
protected static $default_order = 'num_wheels DESC';
```

#### Functions in a model

[](#functions-in-a-model)

The following functions can be used on a model

### `find($criteria, $criteria_params, ...) : PersistentEntity[]`

[](#findcriteria-criteria_params---persistententity)

Find entities in the database filtered on criteria. The syntax for this should be familiar if you ever worked with PDO in PHP. The `$criteria` is the `WHERE` clause of the underlying select statement, you can put `?`'s here where variables are. The criteria params are where you fill these variables. Criteria params are automatically filtered and safe for user input.

```
CarModel::instance()->find('num_wheels = ? AND color = ?', [$normal_car_wheels, $car_color]);
```

### `count($criteria, $criteria_params) : int`

[](#countcriteria-criteria_params--int)

Count the number of entities which pass the criteria, same as `find(..)`. Creates statements like `SELECT COUNT(*) ...` which are faster than counting in PHP.

### `exists($entity) : boolean`

[](#existsentity--boolean)

Check whether or not an entity exists in the database.

### `create($entity) : string`

[](#createentity--string)

Save a new entity into the database. Returns the id of the inserted entity.

### `update($entity) : int`

[](#updateentity--int)

Store an entity in the database, replacing the entity with the same primary key.

### `delete($entity) : int`

[](#deleteentity--int)

Delete an entity from the database.

#### Example

[](#example-1)

**`model/CarModel.php`**

```
require_once 'model/entity/Car.php';

class CarModel extends PersistenceModel {
  const ORM = 'Car';

  public function findByColor($color) {
    return $this->find('color = ?', [$color]);
  }
}
```

**`index.php`**

```
require_once 'model/CarModel.php';

$model = CarModel::instance();
$cars = $model->find();
$actual_cars = $model->find('num_wheels = 4');
$yellow_cars = $model->findByColor('yellow');
```

Database update
---------------

[](#database-update)

This orm can check the models for you. To enable this feature you need to define the global constant `DB_CHECK` as `true`. After that you can check the DatabaseAdmin for any updated tables. This only checks tables which are in use and must be done after all models are used. It is also possible to enable automatically updating the database by defining the global constant `DB_MODIFY` as `true`. This will update tables according to your models. This will not try to migrate data, so be careful. `DB_MODIFY` will not drop tables. for this you will need to define `DB_DROP` as `true`.

```
if (DB_CHECK) {
    $queries = DatabaseAdmin::instance()->getQueries();
    if (!empty($queries)) {
        if (DB_MODIFY) {
            header('Content-Type: text/x-sql');
            header('Content-Disposition: attachment;filename=DB_modify_' . time() . '.sql');
            foreach ($queries as $query) {
                echo $query . ";\n";
            }
            exit;
        } else {
            var_dump($queries);
        }
    }
}
```

JSON fields
-----------

[](#json-fields)

By using T::JSON, a database field can be mapped to an array or object. On save, data is serialized to JSON and can later be deserialized. In the example the $reviews property is a JSON field.

```
$model = CarModel::instance();
$car = $model->find()[0];

$review = new CarReview();
$review->userId = '1801';
$review->reviewText = 'Very good car!';

$car->reviews = [$review];
$model->update($car);
```

To prevent remote code execution only allowed classes can be (de)deserialized. In the third element of the attribute defintion the list of allowed classes should be specified. Also null can be passed to allow all classes.

Database transactions
---------------------

[](#database-transactions)

To wrap multiple database calls in a transaction you can use `Database::transaction(Closure)`. This function wraps another function in a database transaction. Any exception thrown causes the transaction to be rolled back. If the database is in a transaction this function will just call the `Closure` without trying to create a new transaction.

```
$car = new Car();
Database::transaction(function () use ($car) {
    CarModel::instance()->create($car);
    CarWheelModel::instance()->create($car->getWheels());
});
```

Dependency Injection
--------------------

[](#dependency-injection)

You can provide your own `ContainerInterface` to `DependencyManager`, this container will be used for everything. You still need to provide the container with instances of `Database`, `DatabaseAdmin` and `OrmMemcache`.

```
$container = $kernel->getContainer();

DependencyManager::setContainer($container);

$container->set(OrmMemcache::class, new OrmMemcache($cachePath));
$container->set(Database::class, new Database($pdo));
$container->set(DatabaseAdmin::class, new DatabaseAdmin($pdo));
```

It is also possible to leverage the dependency injection provided by the orm. The orm does a very simple way of dependency injection. When a instance of a model is created is created it tries to lookup any dependencies which extend `DependencyManager` if they are found they are wired into the model and available for use. There can only be one version of a model and this is kept track of in `DependencyManager`.

### Example

[](#example-2)

```
class OwnerModel extends PersistenceModel {
  const ORM = 'Owner';

  /** @var CarModel */
  protected $carModel;

  public function __construct(CarModel $carModel) {
    $this->carModel = $carModel;
  }

  public function getCarsForOwner(Owner $owner) {
    return $this->carModel->find('owner = ?', [$owner->id]);
  }
}

class CarModel extends PersistenceModel {
  const ORM = 'Car';

  public function findByColor($color) {
    return $this->find('color = ?', [$color]);
  }
}
```

```
$owner = OwnerModel::instance()->find('id = 1');

$cars = OwnerModel::instance()->getCarsForOwner($owner);
```

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 89.1% 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 ~51 days

Recently: every ~72 days

Total

23

Last Release

2261d ago

PHP version history (4 changes)v1.0PHP &gt;=5.3.0

v1.5PHP &gt;=5.6.0

v1.7.3PHP &gt;=7.1

1.7.6PHP &gt;=7.0.27

### Community

Maintainers

![](https://www.gravatar.com/avatar/11a5c870c4f24eb721ceb7c08fd3678a65869c72f127fc88882fc0720d185df9?d=identicon)[qurben](/maintainers/qurben)

---

Top Contributors

[![qurben](https://avatars.githubusercontent.com/u/589651?v=4)](https://github.com/qurben "qurben (131 commits)")[![mathcals](https://avatars.githubusercontent.com/u/9559454?v=4)](https://github.com/mathcals "mathcals (16 commits)")

---

Tags

databaseormphp

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/csrdelft-orm/health.svg)

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

###  Alternatives

[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k46.2M405](/packages/robmorgan-phinx)[getgrav/grav

Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS

15.4k84.1k1](/packages/getgrav-grav)[kimai/kimai

Kimai - Time Tracking

4.6k7.4k1](/packages/kimai-kimai)[hyperf/database

A flexible database library.

202.8M257](/packages/hyperf-database)[samsonasik/error-hero-module

A Hero for your Laminas and Mezzio application to trap php errors &amp; exceptions

5233.4k1](/packages/samsonasik-error-hero-module)

PHPackages © 2026

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