PHPackages                             rohitsodhia/phpdm - 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. rohitsodhia/phpdm

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

rohitsodhia/phpdm
=================

A ORM/ODM with models decoupled from the database

126

Since Nov 17Compare

[ Source](https://github.com/rohitsodhia/phpDM)[ Packagist](https://packagist.org/packages/rohitsodhia/phpdm)[ RSS](/packages/rohitsodhia-phpdm/feed)WikiDiscussions Synced 2w ago

READMEChangelogDependenciesVersions (3)Used By (0)

phpDM
=====

[](#phpdm)

phpDM is a model-first ORM/ODM. Currently supporting MySQL and MongoDB out of the box, it draws heavily from [Laravel](https://laravel.com/)'s Eloquent.

Unlike Eloquent most other ORMs/ODMs, phpDM starts with creating a model class representing a table and it's fields. Definitions are attached to each field, and every time a model is retrieved or saved, data is validated against those types. This means it's focused around your code, and allows you to switch databases with ease. You're not organizing for MySQL columns or Mongo fields, you're setting up PHP data, and phpDM interfaces with your database appropriately.

Basic usage
-----------

[](#basic-usage)

This project currently supports MySQL and MongoDB.

First, create a connection with the `ConnectionManager`.

MySQL:

```
\phpDM\Connections\ConnectionManager::addConnection(
	[
		'type' => 'mysql',
		'hostname' => 'localhost',
		'database' => 'yourdb',
		'username' => 'username',
		'password' => 'password'
	]
);
```

MongoDB:

```
\phpDM\Connections\ConnectionManager::addConnection(
	[
		'type' => 'mysql',
		'database' => 'yourdb',
	]
);
```

The `addConnection` method also takes a second optional parameter, `name`, through which you can name your connection, in case you'd like to directly reference the connection later on (such as using multiple databases of the same type).

Next, create a model class which extends off the appropriate Model base.

- MySQL =&gt; `MysqlModel`
- MongoDB =&gt; `MongoModel`

The minimum necessary field to retrieve data is `$fields`, which will define the fields to populate your model and what type they must be.

```
class User extends \phpDM\Models\MysqlModel
{

	protected static $fields = [
		'userID' => 'int',
		'username' => 'string',
		'password' => 'string',
		'joinDate' => 'timestamp'
	];

}
```

The following field types are available:

- `int`/`integer`
- `float`
- `bool`/`boolean`
- `str`/`string`
- `timestamp` - uses Carbon to extend DateTime
- `array()` - accepts an array of the type within the parenthesis, ex. `array(string)`
- `object:\Models\User` - accepts a class (with namespace) after the colon, to be used as an embedded object. If you're looking to embed objects that are only being used to model that embedded data, you should use the `GenericModel` class. If you intend on using the class independently, the class **must** be a phpDM Model of the same type as the model embedding it. In MySQL, this is converted to JSON on save.

While not strictly necessary, its important to define  primary key:

```
static protected $primaryKey = 'id';
```

By default, phpDB will search for the plural, snake case version of your model's class name as it's table. It requires following PSR-1 class naming conventions. For example, a model `UserRole` will use the table `user_roles`. If you'd like to use a different table, add the `$table` field.

```
protected static $table = 'user_admin_roles';
```

If you prefer to use camel case, you can pass an array with the key of `options` when adding a connection, with a `case` key with the value of 'camel'. phpDM will now use a pluralized version of your model's class name, with a lower-cased first letter.

```
'options' => ['case' => 'camel']
```

MongoDB models can also use `$collection`.

Special types
-------------

[](#special-types)

### Generic embedded object

[](#generic-embedded-object)

If you'd like to embed an object but don't need a full model for it, you can use the verbose type format:

```
protected static $fields = [
    'user' => [
        'type' => 'object',
        'fields' => [
            'userId' => 'int',
            'username' => 'str'
        ]
    ]
];
```

The inner `fields` element is populated the same as the static `$fields` property. You can have objects embedded within objects.

If you'd prefer to keep the object separate or create an array of objects, you can create a model extending from `GenericModel`. It functions the same as a model created through the verbose format shown above.

### Special timestamps

[](#special-timestamps)

There are 3 special timestamps included

- `createdTimestamp` - This field is auto-populated with the current timestamp when a model is created.
- `updatedTimestamp` - This field is auto-populated when the current timestamp when a model is updated
- `deletedTimestamp` - This field is used for soft deletes and is auto-populated with the current timestamp when a model is deleted

Retriving a single record
-------------------------

[](#retriving-a-single-record)

The `find` method will retrieve a single record of a model, using the defined primary key.

```
User::find(1)
```

This will retrieve the values where the primary key is equal to `1` and populate and return a `User` object.

Retriving multiple records
--------------------------

[](#retriving-multiple-records)

To get back multiple results, use the `get` method.

```
User::get()
```

This will return populated `User` objects of all entries in the `users` table.

Conditions
----------

[](#conditions)

You can add conditions with the `where`, `orWhere`, or `whereIn` methods.

The `where` and `orWhere` methods can take either 2 parameters:

```
where('username', 'rohit')
```

which checks where the values are equivilent, or you may put a comparitor in the second parameter:

```
where('votes`, '>=', 30)
```

The `where` and `orWhere` methods will also accept a function to create prioritized conditions (such as using parenthesis in MySQL):

```
where(function ($query) {
	return $query->where('role', null)->orWhere('active', 0);
});
```

The `whereIn` method takes 2 parameters, a field and an array of values:

```
whereIn('username', ['rohit', 'rsodhia'])
```

Chain your conditions with `get` to retrieve values.

Any query builder methods started staticly off a model return a query builder instance, and thus are chained directly thereon:

```
User::where('username', 'rohit')->orWhere('active', '!=', 0)->get()
```

Sorting
-------

[](#sorting)

To add sorting, simply chain the `sort` function onto the Query Builder. The first parameter is the field to sort on, the second is the direction to sort on (`asc` for ascending or `desc` for descending). The default direction is ascending.

```
sort('registeredOn', 'desc');
```

To sort on multiple fields, chain multile sort functions together.

Limiting
--------

[](#limiting)

To retrieve a limited number of rows, you can use the `limit` method, simply passing it an integer greater than zero. You can also skip entries using `skip`, passing it an integer greater than zero.

You can do both together using `paginate`. Paginate takes two values, first the number of entries you want returned, second the page number, starting with 1.

```
paginate(20, 1)
```

will retrieve entries 0-19.

```
paginate(20, 2)
```

will retrieve entries 20-39.

Saving data
-----------

[](#saving-data)

Whether creating a new database entry or updating an existing row, use the `save` method. Called on an instance of a model, it will check for any data that has been changed and save that data to the database. If there is no primary key, it will attempt to insert a new entry; if there is a primary key, it will attempt to update an entry. If the databse allows it, it will return the number of affected rows on success, or `false` on failure.

```
$user = new User();
$user->username = 'rohit';
$user->save();
```

This will insert a new entry with the `username` 'rohit'.

```
$user = User::find(1);
$user->email = 'test@test.com';
$user->save();
```

As this will retrieve the entry with the id '1', it will update the email and update the database.

In MySQL, values of type `array` or `object` will be converted to json for storage.

Deleting
--------

[](#deleting)

To delete a query, simply call `remove` on a model.

```
User::where('userId', 4)->remove()
```

If the model has a `deletedTimestamp` field, the field will be updated to the current time and the retrival functions (`first`, `find`, and `get`) won't retrieve the model(s). If there is no `deletedTimestamp` field, it will be removed from the database.

Empty query
-----------

[](#empty-query)

In case you want to start a model query but don't yet have a method to chain, you can call `query`.

```
$queryBuilder = User::query();
```

This can be chained to as any other query builder method later.

###  Health Score

21

—

LowBetter than 17% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

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://avatars.githubusercontent.com/u/2379558?v=4)[Rohit Sodhia](/maintainers/rohitsodhia)[@rohitsodhia](https://github.com/rohitsodhia)

### Embed Badge

![Health badge](/badges/rohitsodhia-phpdm/health.svg)

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

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.8k117.8M121](/packages/jdorn-sql-formatter)[backup-manager/backup-manager

A framework agnostic database backup manager with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more with drivers for popular frameworks.

1.7k1.6M11](/packages/backup-manager-backup-manager)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M88](/packages/propel-propel1)[insolita/yii2-migration-generator

Set of gii tools for generating files for migration by schema of table , phpdoc or table data

108508.0k5](/packages/insolita-yii2-migration-generator)[xpdo/xpdo

A PDO-based Object/Relational Bridge Library

7088.4k4](/packages/xpdo-xpdo)[coryrose/livewire-tables

An extension for Livewire that allows you to effortlessly scaffold datatables with optional pagination, search, and sort.

8941.5k](/packages/coryrose-livewire-tables)

PHPackages © 2026

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