PHPackages                             potfur/stash - 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. potfur/stash

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

potfur/stash
============

Stash: Mongo ODM

1.0.0-alpha(10y ago)601MITPHPPHP &gt;=5.5.9|~7.0

Since Aug 23Pushed 10y agoCompare

[ Source](https://github.com/potfur/stash)[ Packagist](https://packagist.org/packages/potfur/stash)[ RSS](/packages/potfur-stash/feed)WikiDiscussions dev Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

Stash - MongoDB ODM
===================

[](#stash---mongodb-odm)

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/68babd8e7b2daba3cf7b536d87722ce3410d23b9816a77509c96926875462f16/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f706f746675722f73746173682f6261646765732f7175616c6974792d73636f72652e706e673f623d646576)](https://scrutinizer-ci.com/g/potfur/stash/?branch=dev)[![Code Coverage](https://camo.githubusercontent.com/eb3d569645dffa517407b458ed42ae9fc63c2666ea551a71372363f8914318bc/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f706f746675722f73746173682f6261646765732f636f7665726167652e706e673f623d646576)](https://scrutinizer-ci.com/g/potfur/stash/?branch=dev)[![Build Status](https://camo.githubusercontent.com/1fe9e9fa32f5863f7a2ac18ad247e70205bdb7bc97af79296e0c58e75211bdb9/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f706f746675722f73746173682f6261646765732f6275696c642e706e673f623d646576)](https://scrutinizer-ci.com/g/potfur/stash/build-status/dev)[![License](https://camo.githubusercontent.com/5f447a4858b2f35fe0643fc3b03159b00310f76bfb3c92f28fa9e7839c910f3c/68747470733a2f2f706f7365722e707567782e6f72672f706f746675722f73746173682f6c6963656e73652e737667)](https://packagist.org/packages/potfur/stash)

**Stash** is an object-document mapper for MongoDB written in PHP. It adds a fully transparent persistence layer while still preserving MongoDB's ease of use and way of handling data.

This means that MongoDB can be used almost in the exact same way as it would be used with arrays. The small, but important, difference here is that instead of returning plain arrays, **Stash** will return objects (entities). And of course, **Stash** not only returns entities, but it also stores them.

Example
-------

[](#example)

Model definitions:

```
$models = new \Stash\ModelCollection();
$models->register(
    new \Stash\Model\Model(
        '\Order',
        [
            new \Stash\Converter\Type\Id(),
            new \Stash\Converter\Type\Document('customer'),
            new \Stash\Converter\Type\ArrayOf('items', Fields::TYPE_DOCUMENT)
        ]
    ),
    'order'
);

$models->register(
    new \Stash\Model\
        '\OrderItem',
        [
            new \Stash\Converter\Type\Scalar('name', Fields::TYPE_STRING),
            new \Stash\Converter\Type\Scalar('amount', Fields::TYPE_INTEGER),
            new \Stash\Converter\Type\Scalar('cost', Fields::TYPE_INTEGER)
        ]
    )
);

$models->register(
    new \Stash\Model\
        '\Voucher',
        [
            new \Stash\Converter\Type\Scalar('name', Fields::TYPE_STRING),
            new \Stash\Converter\Type\Scalar('cost', Fields::TYPE_INTEGER)
        ]
    )
);

$models->register(
    new \Stash\Model\
        '\Customer',
        [
            new \Stash\Converter\Type\Scalar('name', Fields::TYPE_STRING),
            new \Stash\Converter\Type\Document('address')
        ]
    )
);

$models->register(
    new \Stash\Model\
        '\CustomerAddress',
        [
            new \Stash\Converter\Type\Scalar('address', Fields::TYPE_STRING),
            new \Stash\Converter\Type\Scalar('city', Fields::TYPE_STRING),
            new \Stash\Converter\Type\Scalar('zip', Fields::TYPE_STRING)
        ]
    )
);
```

Database connection:

```
$types = [
    new \Stash\Converter\Type\IdType(),
    new \Stash\Converter\Type\BooleanType(),
    new \Stash\Converter\Type\IntegerType(),
    new \Stash\Converter\Type\DecimalType(),
    new \Stash\Converter\Type\StringType(),
    new \Stash\Converter\Type\DateType(),
    new \Stash\Converter\Type\ArrayType(),
    new \Stash\Converter\Type\DocumentType()
];

$proxyAdapter = new \Stash\ProxyAdapter(new \ProxyManager\Factory\LazyLoadingValueHolderFactory());
$converter = new \Stash\Converter\Converter($types);
$referencer = new \Stash\ReferenceResolver($models);
$documentConverter = new \Stash\DocumentConverter($converter, $referencer, $models, $proxyAdapter);
$eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();

$connection = new \Stash\Connection(new \MongoClient(), $documentConverter, $eventDispatcher);
$connection->selectDB('test');
```

Entity creation and storage:

```
class Order
{
    private $id;
    private $customer;
    private $items;

    public function __construct($customer, $items)
    {
        $this->customer = $customer;
        $this->items = $items;
    }
}

class OrderItem
{
    private $name;
    private $amount;
    private $cost;

    public function __construct($name, $amount, $cost)
    {
        $this->name = $name;
        $this->amount = $amount;
        $this->cost = $cost;
    }
}

class Voucher
{
    private $name;
    private $discount;

    public function __construct($name, $discount)
    {
        $this->name = $name;
        $this->discount = $discount;
    }
}

class Customer
{
    private $name;
    private $address;

    public function __construct($name, CustomerAddress $address)
    {
        $this->$name = $name;
        $this->address = $address;
    }
}

class CustomerAddress
{
    private $address;
    private $city;
    private $zip;

    public function __construct($address, $city, $zip)
    {
        $this->address = $address;
        $this->city = $city;
        $this->zip = $zip;
    }
}

$order = new Order(
    new Customer('Joe Doe', new CustomerAddress('Mongo alley', 'Somewhere', '12345')),
    [
        new OrderItem('Foos', 10, 1000),
        new Voucher('Voucher', 250)
    ]
);

$connection->getCollection('order')->save($order);
```

And this is the stored MongoDB's semi-JSON representation. When saving objects (entities), **Stash** adds the `_class` field, where it stores the class name

```
{
  "_id" : ObjectId("55746f4f87dee7bc0b000033"),
  "_class" : "Order",
  "customer" : {
    "_class" : "Customer",
    "address" : {
      "_class" : "CustomerAddress",
      "address" : "Mongo alley",
      "city" : "Somewhere",
      "zip" : "12345"
    }
  },
  "items" : [
    {
      "_class" : "OrderItem",
      "name" : "Foos",
      "amount" : 10,
      "cost" : 1000
    },
    {
      "_class" : "Voucher",
      "name" : "Voucher",
      "discount" : 250
    }
  ]
}

```

Event subscription
------------------

[](#event-subscription)

*Stash* uses [Symfonys Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html) for dispatching events.

- `find.after` triggered after reading document from database and converting it to entity instance
- `persist.before` is triggered before converting entity to array document
- `persist.after` after document was saved (and updated with new `_id` if needed)
- `remove.before` triggered before entity is removed from database

Each event is represented with `Event` entity, similar to Symfony's `Event` but with two methods `getPayload` and `setPayload` to manage subject entity.

```
$subscriber = new \Fake\EventSubscriber(
    [
        \Stash\Events::FIND_AFTER,
        \Stash\Events::PERSIST_BEFORE,
        \Stash\Events::PERSIST_AFTER,
        \Stash\Events::REMOVE_BEFORE
    ]
);
$eventDispatcher->addSubscriber($subscriber);
```

Configuring proxy
-----------------

[](#configuring-proxy)

By default, all required proxy classes are generated at runtime. Generation uses a lot of reflection and it may cause poor performance. To prevent this, proxy generator needs to be configured to reuse generated proxies.

```
$config = new \ProxyManager\Configuration();
$config->setProxiesTargetDir(__DIR__ . '/generated/proxy/);
spl_autoload_register($config->getProxyAutoloader());

$proxyAdapter = new \Stash\ProxyAdapter($config);
```

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.5% 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

Unknown

Total

1

Last Release

3922d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8addaf28c1a25afd6006377779228ee980528e4ca23793a4ab8bc426dda5018b?d=identicon)[potfur](/maintainers/potfur)

---

Top Contributors

[![potfur](https://avatars.githubusercontent.com/u/1244857?v=4)](https://github.com/potfur "potfur (21 commits)")[![marcotroisi](https://avatars.githubusercontent.com/u/429760?v=4)](https://github.com/marcotroisi "marcotroisi (1 commits)")

---

Tags

persistencedatabaseodmdocumentmongo

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/potfur-stash/health.svg)

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

###  Alternatives

[doctrine/doctrine-bundle

Symfony DoctrineBundle

4.8k241.3M3.3k](/packages/doctrine-doctrine-bundle)[doctrine/persistence

The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.

4.1k286.5M762](/packages/doctrine-persistence)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[doctrine/phpcr-bundle

Symfony DoctrinePHPCRBundle

1602.6M41](/packages/doctrine-phpcr-bundle)[dunglas/doctrine-json-odm

An object document mapper for Doctrine ORM using JSON types of modern RDBMS.

6285.0M10](/packages/dunglas-doctrine-json-odm)

PHPackages © 2026

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