Analogue ORM : Data Mapper ORM for Laravel/PHP

Overview

(this project is looking for a new maintainer)

Analogue ORM

Latest Stable Version Latest Unstable Version License Build Status StyleCI

Analogue is a flexible, easy-to-use ORM for PHP. It is a transposition of the Eloquent ORM that ships with Laravel framework using a Data Mapper pattern instead of the original Active Record approach. it overcomes some of Eloquent's architectural limitations by using a strict separation of concerns; for example, you can use Value Objects or Single-table-inheritance, which are hard/impossible to implement correctly using the native ORM.

As a Laravel package, it integrates flawlessly inside the framework, and provides a more powerfull peristance layer, allowing to build enterprise-grade applications while retaining a simple and enjoyable development experience.

Installation

composer require analogue/orm

See Configuration for more information.

Concept

The concept is simple; your model layer is defined using 2 classes : one Entity, which can be any PHP class or extends the base Analogue\ORM\Entity class which provides magic getters and setters, and one EntityMap which defines relationships, castings, table name, database column names.

Take this simple domain model :

use Analogue\ORM\Entity;
use Illuminate\Support\Collection;

class Blog extends Entity
{
    public function __construct()
    {
        $this->posts = new Collection;
    }

    public function addPost(Post $post)
    {
        $this->posts->push($post);
    }
}

class Post extends Entity
{
 
}

We can instruct Analogue how these objects are related using these classes :

use Analogue\ORM\EntityMap;

class BlogMap extends EntityMap
{
    public function posts(Blog $blog)
    {
        return $this->hasMany($blog, Post::class);
    }
}

class PostMap extends EntityMap
{
    public function blog(Post $post)
    {
        return $this->belongsTo($post, Blog::class);
    }
}

Now we can create related instance of or object and persist them to the database :

$blog = new Blog;
$blog->title = "My first blog";

$post = new Post; 
$post->title->"My first post";

$blog->addPost($post);

// Only the blog instance need to explicitely stored; Analogue takes care of synchronizing
// related objects behinds the scene. 

mapper(Blog::class)->store($blog);

Once our objects are persisted into the database, we can query them using the fluent query builder :

$blog = mapper(Blog::class)->first();

echo $blog->posts->first()->title; // 'My first post'

Documentation

Check the Documentation for more details.

Features

  • Framework agnostic
  • Lazy loading
  • Eager Loading
  • Timestamps
  • Soft Deletes
  • Value Objects
  • Polymorphic Relationships
  • Dynamic Relationships
  • Single table inheritance
  • Cast entities to Array / Json
  • Flexible event system
  • Native multiple database connections support
  • Extendable via custom database drivers / plugins

Changelog

Version 5.6

  • Laravel 5.6 support
  • Bring back ability to map DB columns that name are not equals to the name of the attribute.
  • Add ability to map DB snake case columns to camel case properties on entities.

Version 5.5

  • Laravel 5.5 support
  • Pushed miminum requirements to PHP7
  • Complete support of Plain PHP objects via reflection based hydration/dehydration
  • Improved Lazy-loading proxies.
  • New, more flexible Value Object implementation, that can now be defined as embedsOne(), embedsMany() relationships
  • Embedded value object can now be stored as a mysql JSON field
  • Analogue entities can now be instantiated using laravel's IoC Container or any PSR-11 compatible container.
  • Added MongoDB driver.
  • Package auto discovery (L5.5)

Version 5.4

  • Illuminate 5.4 Compatibility.
  • Add Ability to map DB columns that name are not equals to the name of the attribute.

Version 5.3

  • Illuminate 5.3 Compatibility.
  • Now fully support Single Table Inheritance.

Version 5.1

  • Illuminate 5.1 + 5.2 Compatibility.

Version 5.0

  • Analogue version now mirrors illuminate version.

Version 2.1.3

  • Mutator feature in base Entity class.
  • Ability to add entities to a proxy collection without lazyloading it.

Version 2.1

  • Package is now framework agnostic.
  • Now support any plain object that implements Mappable interface.
  • Introducing a MappableTrait for quick implementation.
  • Queries can now be run directly on the mapper Object.
  • Store/Delete methods now accept a array and collections as argument.
  • EntityMap are now autodected when in the same namespace as the entity.
  • Base Entity class Supports hidden attributes.
  • Many workflow related improvements.

Version 2.0

  • Laravel 5 Support.

Documentation

Check the wiki for full documentation.

Licence

This package is licensed under the MIT License.

Comments
  • [feature request] make mass-assignment possible and easy

    [feature request] make mass-assignment possible and easy

    In your example in the REAME.md you show how pretty code can look when you can just do something like $gallery = new Gallery('Trip to India') and $photo = new Photo($file).

    However, I notice in daily life with Laravel I rarely use that. I much more often use form-data to populate new entities and I really liked that with Eloquent I could mass-assign that like so: $user = new User($request->all()). And because I had set a $fillable property on User I knew that I wouldn't populate non-existing attributes or special attributes. And even all the right mutators would be called.

    I think that use-case is much more likely in daily life. What do you think?

    And I took it even one step further. I made my own base-eloquent-model in which I had my own constructor like so:

    public function __construct(Request $request)
    {
        parent::construct($request->input(class_basename($this)));
    }
    

    This way, in my controllers I could do something like:

    public function store(CreateUserRequest $request, User $user, Person $person)
    {
        $person->save();
        $user->associate($person);
        $user->save();
    }
    

    Because just by type-hinting all that stuff I knew that the data had been validated and correctly mass-assigned to the respective models. That is just so freaking convenient, can we please build something similar into Analogue?

    In case you're wondering, this is basically what my form would look like:

    <form>
        <input name="Person[name]" type="text">
        <input name="Person[infix]" type="text">
        <input name="Person[surname]" type="text">
    
        <input name="User[email]" type="email">
        <input name="User[password]" type="password">
        <input name="User[password_confirmation]" type="password">
    </form>
    
    opened by Evertt 15
  • Error in EntityCache if identity is VO

    Error in EntityCache if identity is VO

    I have error with cache if using VO for identity property (PK):

    2) UserRepositoryCest: Save
     Test  tests\integration\Infrastructure\UserRepositoryCest.php:save
    
      [PHPUnit_Framework_Exception] array_key_exists(): The first argument should be either a string or an integer
    
    Scenario Steps:
    
     1. $I->takeContainer() at tests\integration\Infrastructure\UserRepositoryCest.php:30
    
    #1  Codeception\Subscriber\ErrorHandler->errorHandler
    #2  \vendor\analogue\orm\src\System\EntityCache.php:95
    #3  \vendor\analogue\orm\src\System\Aggregate.php:1010
    #4  \vendor\analogue\orm\src\Commands\Store.php:39
    #5  \vendor\analogue\orm\src\System\Mapper.php:171
    #6  \vendor\analogue\orm\src\System\Mapper.php:132
    #7  \Infrastructure\Repository\AnalogueUserRepository.php:164
    #8  \tests\integration\Infrastructure\UserRepositoryCest.php:71
    #9  Infrastructure\UserRepositoryCest->save
    
    /**
         * Check if a record for this id exists.
         *
         * @param  string  $id
         * @return boolean
         */
        public function has($id)
        {
            return array_key_exists($id, $this->cache);
        }
    
    opened by Sufir 14
  • BelongsToMany results don't load with a modified $primaryKey on either EntityMap

    BelongsToMany results don't load with a modified $primaryKey on either EntityMap

    As discussed in #171.

    With a simple User and Group mapping, many-to-many relationships load an empty result set if either map has a modified $primaryKey.

    That is:

    $users = $userMap->with('groups')->get(); means no users will have groups, and vice versa.

    In my case, the GroupMap has a $primaryKey of 'groupid'. If I rename the column in the database schema to id, and remove the custom $primaryKey from the map, everything works as expected.

    I'm using a custom connection for this, but this happens with or without the custom connection; I've tested both. However, as a result I noticed that the ID was bound as null when the query is run, and digging a little deeper it looked like the proxy object that represented the parent of the relationship had no attributes.

    opened by hexus 13
  • Allow mappers to save subclass entities.

    Allow mappers to save subclass entities.

    The STI implementation that we worked on a couple of months ago is still unusable for me without this PR; I have it implemented on the 5.1.* branch of my fork (I use it for an app I've been building at work and this solution works nicely), but we're upgrading the app to Laravel 5.3 and I need to use the 5.3-dev branch branch and this never got merged into the original PR. We talked about this in the conversation for the previous PR: https://github.com/analogueorm/analogue/pull/131#issuecomment-245150719. Please consider merging this in, for the reason discussed in that comment thread. Also, if you want help writing tests for this feature (or anything else that I can help with) just let me know. I'm in Laravel slack as tabennett. Thank you for your time and work you put into this project.

    opened by tabennett 13
  • 5.3 dev

    5.3 dev

    I've taken a stab at implementing #101. This is probably going to need some cleanup, but I've tried to following the concepts that you laid out (namely, using higher level ResultBuilder that builds out an array of entities by calling each the appropriate ResultBuilder for each record). To implement table inheritance, all you have to do is define some meta values on the base mapper class. As example, we could define the following configuration on a base Vehicle mapper:

    /**
         * @var string
         */
        protected $inheritanceType = "single_table";
    
        /**
         * @var string
         */
        protected $discriminatorColumn = "type";
    
        /**
         * @var array
         */
        protected $discriminatorColumnMap = [
            "vehicle" => "App\Entities\Vehicle",
            "car"     => "App\Entities\Car",
            "truck"   => "App\Entities\Truck"
        ];
    

    This follows the same inheritance mapping configuration as used by Doctrine. I did this for the following reasons:

    1. People that have used Doctrine before and are familiar with this configuration will be able to get up and running quicker.
    2. This opens the door for us to implement class table inheritance later on (which would be very nice to have but is beyond the scope of this PR).

    The only major issue I have with this is that I wasn't able to figure out how to get an instance of the Manager class without using Laravel's IOC container (which might not be the most ideal way to do that and feels a bit weird to be doing). Please let me know what you think.

    opened by tabennett 13
  • BelongsToMany results missing from eager-loaded nested relations

    BelongsToMany results missing from eager-loaded nested relations

    @devsi and I have started using this library and it's truly fantastic.

    However, we've encountered an issue with the BelongsToMany relation when it's eagerly loaded as a nested relation. I imagine this might be an issue with the version of Eloquent you forked, after some investigation, but I can't be certain.

    It would be nice to know whether this is actually a bug, or whether we're doing something wrong.


    Here are the relations in our system:

    • Quizzes many to many Questions
    • Questions one to many Options

    We have one Quiz, with three Questions, each having a number of Options.

    If we eagerly load Options with their parent Questions, as well as the Quizzes of those Questions like so:

    $options = $optionMapper->with('question.quizzes')->get();
    

    It ends up that only the last pivot for Quizzes is actually taken into account, seemingly because all of these will be the same Quiz (ID 1).

    Here's the result set with eager loading:

    https://pastebin.com/0FC1Vb88

    Here, only the last loaded Quiz pivot is included.

    Here's the correct result set with lazy loading, or if we only eager load questions (with('question')):

    https://pastebin.com/sGBM01qY

    Here, all the pivots are loaded properly without eager loading.


    If need be, I can make these result sets much simpler and even provide the queries run, but I thought I'd just outline it for time being to see if you knew about this.

    I traced to the BelongsToMany::match() method having a dictionary with a single item, instead of three.

    When System\Query::loadRelation() is run for this relationship, the $results collection indeed only contains the last pivot, but if I run the corresponding SQL result manually on my database, the results include all three.

    Cheers!

    opened by hexus 12
  • (Feature Request) Table Inheritance

    (Feature Request) Table Inheritance

    Hey, I was wondering if there is (currently) a way to implement table inheritance (single, join, etc) with Analogue, and if not, maybe we could hash out some ideas here. From looking at some of the underlying system classes, I would assume that this is not going to be trivial to implement. If there's anything I can do to help, please let me know. I think having a nice and clean way to do STI with Analogue would help a lot of people or are transitioning from AR to DM in their Laravel based apps and could really strengthen support for this project.

    enhancement 
    opened by tabennett 12
  • Illuminate 5.1 packages

    Illuminate 5.1 packages

    Is it possible to use Laravel/Lumen 5.1 LTS i.e. the Illuminate 5.1 packages? For now 5.0.* is defined as the only compatible version in composer.json.

    opened by thasmo 11
  • Analogue Presenter Repository

    Analogue Presenter Repository

    I've created a Presenter class (ala Jeffrey Way's Presenter class): https://github.com/smallhadroncollider/analogue-presenter

    If you would like to, I'd be happy for it to be added to the Analogue GitHub organisation, then it can use the Analogue namespace. Let me know if you'd be happy to do that and I'll setup a transfer request. If not I'll just do it under my own namespace instead.

    opened by smallhadroncollider 10
  • Add support for Postgres sequences

    Add support for Postgres sequences

    Okay, let me explain why is this really MUST be implemented.

    As you may know Postgres uses sequences to generate auto-incremented id's, that's more reliable method to implement auto-increments than MySQL's one. This gives us more control over lastInsertedId command.

    Why you really need to implement this feature? Because of the way how Postgres executes commands, sometimes there is something else saving in paraller of other row and that gives a collision (from our perspective), more known as race condition, in that situation when we call lastInsertedId w/o defining from which sequence we want it we will get id of a wrong row in wrong table or get just NULL because row saved in parallel has no primary key.

    So in conclusion: sequence feature will eliminate race conditions.

    Here is a quote from a php's manual for PDO::lastInsertId:

    Returns the ID of the last inserted row, or the last value from a sequence object, depending on the underlying driver. For example, PDO_PGSQL requires you to specify the name of a sequence object for the name parameter.

    Laravel already supports it

    opened by thers 8
  • updating an entity

    updating an entity

    to illustrate the problem i have two tests...

         /**
         * @test
         */
        public function it_creates_a_user()
        {
            $userMapper = \Analogue::mapper(User::class);
            $user = new User(new Identity('first name', 'last name'));
            $userMapper->store($user);
            $user = $userMapper->find(1);
            $userMapper->store($user);
        }
    
        /**
         * @test
         */
        public function it_updates_a_user()
        {
            $userMapper = \Analogue::mapper(User::class);
            $user = $userMapper->find(1);
            $userMapper->store($user);
        }
    
    

    first one is ok, second one (record with id 1 exists in database ) fails with the message:

    Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: first_name (SQL: update "users" set "first_name" = first name, "last_name" = last name where "id" = 1)

    opened by mitjarobic 8
  • Can't install Analogue on Laravel 6

    Can't install Analogue on Laravel 6

    I can't install Analogue on fresh installation of Laravel 6 This is my composer.json

     "require": {
            "php": "^7.2",
            "fideloper/proxy": "^4.0",
            "laravel/framework": "^6.0",
            "laravel/tinker": "^1.0"
        }, 
    

    and this is the error produced when trying composer require analogue/orm:6.*

    ./composer.json has been updated
    
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - Conclusion: don't install analogue/orm v6.0.1
        - Conclusion: don't install analogue/orm v6.0.0
        - Conclusion: remove laravel/framework v6.18.6
        - Installation request for analogue/orm 6.* -> satisfiable by analogue/orm[6.0.x-dev, v6.0.0, v6.0.1].
        - Conclusion: don't install laravel/framework v6.18.6
        - analogue/orm 6.0.x-dev requires illuminate/database 6.0.* -> satisfiable by laravel/framework[v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4], illuminate/database[v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4].
        - Can only install one of: laravel/framework[v6.0.0, v6.18.6].
        - Can only install one of: laravel/framework[v6.0.1, v6.18.6].
        - Can only install one of: laravel/framework[v6.0.2, v6.18.6].
        - Can only install one of: laravel/framework[v6.0.3, v6.18.6].
        - Can only install one of: laravel/framework[v6.0.4, v6.18.6].
        - don't install illuminate/database v6.0.0|don't install laravel/framework v6.18.6
        - don't install illuminate/database v6.0.1|don't install laravel/framework v6.18.6
        - don't install illuminate/database v6.0.2|don't install laravel/framework v6.18.6
        - don't install illuminate/database v6.0.3|don't install laravel/framework v6.18.6
        - don't install illuminate/database v6.0.4|don't install laravel/framework v6.18.6
        - Installation request for laravel/framework (locked at v6.18.6, required as ^6.0) -> satisfiable by laravel/framework[v6.18.6].
    
    
    Installation failed, reverting ./composer.json to its original content. 
    
    enhancement help wanted question 
    opened by IbrahimFathy19 16
  • Automatically eager load not working

    Automatically eager load not working

    Hello, just trying to use eager load: Mapper:

    class RoleMap extends EntityMap
    {
        public $timestamps = true;
        protected $with = ['roleStrings'];
    
        public function roleStrings(Role $role)
        {
            return $this->hasMany($role, RoleString::class);
        }
    } 
    

    If I trying this:

    return mapper(Role::class)->find($id);
    

    Relations not loading automatically.

    But if I trying this:

    return mapper(Role::class)->with(['roleStrings'])->find($id);
    

    OR

    return mapper(Role::class, RoleMap::class)->find($id);
    

    All relations was loaded well.

    So I'm just want to know there a bug or I doing something wrong?

    opened by defektrain 1
  • 5.5 entities with generated proxies are unable to serialize due to a closure

    5.5 entities with generated proxies are unable to serialize due to a closure

    I was working on upgrading to 5.5 and ran into some issues with the serialization. To be exact I upgraded analogue/orm from 5.4.0 to 5.5.18.

    Basically in 5.5 the EntityProxy was replaced with a new ProxyFactory and when creating the generated class there is a closure inside. PHP is unable to serialize closures and fails with an exception:

    Serialization of 'Closure' is not allowed
    

    I ran into this when passing in my User entity to Notification::send(...) or when calling $user->notify(...). My User entity is still using the 5.4 base class and implements Notifiable. The serialization issue happened when the Queue tried to serialize the job (which contains the notifiable user).

    I tried to work around this by implementing the Serializable interface and calling $this->toArray() and such but was not able to cover all the cases. Also upon a fresh boot Analogue ORM would throw an exception due to not being able to serialize() the dummy entity. Removing my overrides restored the original behavior.

    I hacked a workaround by manually unsetting any proxied entites or collections but this isn't maintainable. I can probably separate User from Notifiable and create another class to deal with this but it all worked in 5.4 without issue.

    My questions are:

    • Is it intended for the new proxy behavior to not serialize?
    • Any workarounds or fixes possible here?
    • If no workarounds or fixes: do you know what is the correct way to deal with serialization issues like this?

    I would greatly appreciate any insight into this problem. Maybe I'm just doing something wrong but since this all worked in 5.4 it feels like a regression.

    enhancement 
    opened by michaelsadlon 2
  • Documentation Request

    Documentation Request

    I'll just describe here the most obscure points

    • Since 5.5 Repository was marked as deprecated, what is alternative - full custom realizations with mapper injection, or something else?
    • Accordingly https://github.com/analogueorm/analogue/issues/142 there is ability to map entity attributes to column names - what about similar behavior for properties?
    • Example for transactions
    • Example for incremental/decremental operations ( with queries like UPDATE table SET "foo"="foo"+1)
    • Pros and cons for embedded objects instead of classic valueObjects via getters and setters
      // ...
      public function setStatus(StatusObject $status){
           $this->status = $status->getValue();
           $this->code = $status->getCode();
      }
      public function getStatus():StatusObject{
           return new StatusObject($this->status, $this->code);
      }
    

    Of course, embedded objects are resolved automatically, but in some cases they can bring overhead?

    enhancement 
    opened by Insolita 3
  • Translations base on analogue Orm

    Translations base on analogue Orm

    Hello, Great job with this package. It works great with my projects. Is there a package that makes translations of models? I need somethig like dimsav/laravel-translatable.

    question 
    opened by DinoTD 3
Releases(v6.2.0)
Owner
Analogue ORM
An intuitive Data Mapper ORM for PHP & Laravel
Analogue ORM
Doctrine Object Relational Mapper (ORM)

3.0.x 2.9.x 2.8.x Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence for PHP objects. It sits on top o

Doctrine 9.5k Jan 2, 2023
A data mapper implementation for your persistence model in PHP.

Atlas.Orm Atlas is a data mapper implementation for persistence models (not domain models). As such, Atlas uses the term "record" to indicate that its

null 427 Dec 30, 2022
[READ-ONLY] A flexible, lightweight and powerful Object-Relational Mapper for PHP, implemented using the DataMapper pattern. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP ORM The CakePHP ORM provides a powerful and flexible way to work with relational databases. Using a datamapper pattern the ORM allows you to m

CakePHP 146 Sep 28, 2022
A lightweight nearly-zero-configuration object-relational mapper and fluent query builder for PHP5.

Idiorm http://j4mie.github.com/idiormandparis/ Feature/API complete Idiorm is now considered to be feature complete as of version 1.5.0. Whilst it wil

Jamie Matthews 2k Dec 27, 2022
Convention-based Object-Relational Mapper

Corma Corma is a high-performance, convention-based ORM based on Doctrine DBAL. Corma is great because: No complex and difficult to verify annotations

Michael O'Connell 30 Dec 20, 2022
Baum is an implementation of the Nested Set pattern for Laravel's Eloquent ORM.

Baum Baum is an implementation of the Nested Set pattern for Laravel 5's Eloquent ORM. For Laravel 4.2.x compatibility, check the 1.0.x branch branch

Estanislau Trepat 2.2k Jan 3, 2023
A drop-in Doctrine ORM 2 implementation for Laravel 5+ and Lumen

Laravel Doctrine ORM A drop-in Doctrine ORM 2 implementation for Laravel 5+ $scientist = new Scientist( 'Albert', 'Einstein' ); $scientist->a

Laravel Doctrine 777 Dec 17, 2022
Propel2 is an open-source high-performance Object-Relational Mapping (ORM) for modern PHP

Propel2 Propel2 is an open-source Object-Relational Mapping (ORM) for PHP. Requirements Propel uses the following Symfony Components: Config Console F

Propel 1.2k Dec 27, 2022
PHP DataMapper, ORM

Cycle ORM Cycle is PHP DataMapper, ORM and Data Modelling engine designed to safely work in classic and daemonized PHP applications (like RoadRunner).

Cycle ORM 1.1k Jan 8, 2023
Ouzo Framework - PHP MVC ORM

Ouzo is a PHP MVC framework with built-in ORM and util libraries. PHP 8.0 or later is required. We believe in clean code and simplicity. We value unit

Ouzo 69 Dec 27, 2022
Simple Enum cast for Eloquent ORM using myclabs/php-enum.

Enum cast for Eloquent Simple Enum cast for Eloquent ORM using myclabs/php-enum. Requirements PHP 7.3 or higher Laravel 8.0 or higher Installation You

Orkhan Ahmadov 5 Apr 21, 2022
The Enobrev\ORM library is a small framework of classes meant to be used for simply mapping a mysql database to PHP classes, and for creating simply SQL statements using those classes.

The Enobrev\ORM library is a small framework of classes meant to be used for simply mapping a mysql database to PHP classes, and for creating simply SQL statements using those classes.

Mark Armendariz 0 Jan 7, 2022
ATK Data - Data Access Framework for high-latency databases (Cloud SQL/NoSQL).

ATK Data - Data Model Abstraction for Agile Toolkit Agile Toolkit is a Low Code framework written in PHP. Agile UI implement server side rendering eng

Agile Toolkit 257 Dec 29, 2022
A simple program to query mysql data and display the queried data in JSON format

A simple program to query mysql data and display the queried data in JSON format. The data displayed in JSON format will change and update as the data in your mysql database changes.

null 2 Mar 7, 2022
ORM layer that creates models, config and database on the fly

RedBeanPHP 5 RedBeanPHP is an easy to use ORM tool for PHP. Automatically creates tables and columns as you go No configuration, just fire and forget

Gabor de Mooij 2.2k Jan 9, 2023
Extensions for the Eloquent ORM

Sofa/Eloquence Easy and flexible extensions for the Eloquent ORM. Currently available extensions: Searchable query - crazy-simple fulltext search thro

Jarek Tkaczyk 1.1k Dec 20, 2022
Builds Cycle ORM schemas from OpenAPI 3 component schemas

Phanua OpenAPI 3 + Jane + Cycle ORM = ?? Phanua builds Cycle ORM schemas from OpenAPI 3 component schemas. Released under the MIT License. WARNING: Th

Matthew Turland 5 Dec 26, 2022
Extra RedBean ORM

RedBeanPHP 5 RedBeanPHP is an easy to use ORM tool for PHP. Automatically creates tables and columns as you go No configuration, just fire and forget

GingTeam Development 5 Nov 23, 2022
MongoDB ORM that includes support for references,embed and multilevel inheritance.

Introduction Features Requirements Installation Setup Database Basic Usage - CRUD Relationship - Reference Relationship - Embed Collection Inheritance

Michael Gan 202 Nov 17, 2022