purekid / mongodm
MongoDB ORM that includes support for references,embed and multilevel inheritance.
Installs: 25 518
Dependents: 1
Suggesters: 0
Security: 0
Stars: 200
Watchers: 23
Forks: 47
Open Issues: 19
Requires
- alcaeus/mongo-php-adapter: 1.0.9
Requires (Dev)
- chriskite/phactory: dev-master
This package is auto-updated.
Last update: 2024-12-11 18:41:05 UTC
README
- Introduction
- Features
- Requirements
- Installation
- Setup Database
- Basic Usage - CRUD
- Relationship - Reference
- Relationship - Embed
- Collection
- Inheritance
- Other methods
- Model Hooks
- Special Thanks
Introduction
Mongodm is a MongoDB ORM that includes support for references,embed and even multilevel inheritance.
Features
- ORM
- Simple and flexible
- Support for embed
- Support for references (lazy loaded)
- Support for multilevel inheritance
- Support for local collection operations
Requirements
- PHP 5.3 or greater (Tested for 5.5,5.6,7.0,7.1)
- Mongodb 1.3 or greater
- PHP Mongo extension
Installation
1. Setup in composer.json:
{ "require": { "purekid/mongodm": "dev-master" } }
2. Install by composer:
$ php composer.phar update
Setup Database
Database config file (By default it locates at /vendor/purekid/mongodm/config.php)
return array( 'default' => array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'default', // 'username' => '', // 'password' => '', ) ), 'production' => array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'production', 'options' => array('replicaSet' => 'rs0') ) ) );
Authentication
Authentication information is passed in via the options array. If you do not specifiy authSource, then the PHP Mongo Driver will choose the "admin" database.
$config = array( 'connection' => array(
'hostnames' => '<host>:<port>',
'database' => '<databasename>',
'options' => [ "connectTimeoutMS" => 500 , "username" => "admin", "password" => "<password>", "authSource" => "admin"] )
);
Setup database in application
1.You can set up configuration using the MongoDB::setConfigBlock
method.
\Purekid\Mongodm\MongoDB::setConfigBlock('default', array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'default', 'options' => array() ) )); // \Purekid\Mongodm\MongoDB::setConfigBlock('auth', array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'authDB', 'options' => array() ) ));
2.Or you can duplicate a config file into your project, then define a global constanct 'MONGODM_CONFIG' with it's location.
//in a global initialization place define('MONGODM_CONFIG',__DIR__."/../config/mongodm.php");
Choose config section with APPLICATION_ENV
Which config section Mongodm use ? Mongodm choose 'default' section by default.
You have two ways to specify section :
1.'$config' attribute in Model , you can find this attribute in example below.
2.With environment constanct 'APPLICATION_ENV' ,this constanct can be set by webserver,your code or shell environment. In this case,you should set $config='default' or don't declare $config in your own model class.
Create a model and enjoy it
use Purekid\Mongodm\Model; class User extends Model { static $collection = "user"; /** use specific config section **/ public static $config = 'testing'; /** specific definition for attributes, not necessary! **/ protected static $attrs = array( // 1 to 1 reference 'book_fav' => array('model'=>'Purekid\Mongodm\Test\Model\Book','type'=> Model::DATA_TYPE_REFERENCE), // 1 to many references 'books' => array('model'=>'Purekid\Mongodm\Test\Model\Book','type'=> Model::DATA_TYPE_REFERENCES), // you can define default value for attribute 'age' => array('default'=>16,'type'=> Model::DATA_TYPE_INTEGER), 'money' => array('default'=>20.0,'type'=> Model::DATA_TYPE_DOUBLE), 'hobbies' => array('default'=>array('love'),'type'=> Model::DATA_TYPE_ARRAY), 'born_time' => array('type'=> Model::DATA_TYPE_TIMESTAMP), 'family'=>array('type'=> Model::DATA_TYPE_OBJECT), 'pet_fav' => array('model'=>'Purekid\Mongodm\Test\Model\Pet','type'=> Model::DATA_TYPE_EMBED), 'pets' => array('model'=>'Purekid\Mongodm\Test\Model\Pet','type'=> Model::DATA_TYPE_EMBEDS), ); public function setFirstName($name) { $name = ucfirst(strtolower($name)); $this->__setter('firstName', $name); } public function getLastName($name) { $name = $this->__getter('name'); return strtoupper($name); } }
Types supported for model attributes
[ 'mixed', // mixed type 'string', 'reference', // 1 : 1 reference 'references', // 1 : many references 'embed', 'embeds', 'integer', 'int', // alias of 'integer' 'double', // float 'timestamp', // store as MongoTimestamp in Mongodb 'date', // store as DateTime 'boolean', // true or false 'array', 'object' ]; const DATA_TYPE_ARRAY = 'array'; const DATA_TYPE_BOOL = 'bool'; const DATA_TYPE_BOOLEAN = 'boolean'; const DATA_TYPE_DATE = 'date'; const DATA_TYPE_DBL = 'dbl'; const DATA_TYPE_DOUBLE = 'double'; const DATA_TYPE_FLT = 'flt'; const DATA_TYPE_FLOAT = 'float'; const DATA_TYPE_EMBED = 'embed'; const DATA_TYPE_EMBEDS = 'embeds'; const DATA_TYPE_INT = 'int'; const DATA_TYPE_INTEGER = 'integer'; const DATA_TYPE_MIXED = 'mixed'; const DATA_TYPE_REFERENCE = 'reference'; const DATA_TYPE_REFERENCES = 'references'; const DATA_TYPE_STR = 'str'; const DATA_TYPE_STRING = 'string'; const DATA_TYPE_TIMESTAMP = 'timestamp'; const DATA_TYPE_OBJ = 'obj'; const DATA_TYPE_OBJECT = 'object';
If you put a object instance into a Model attribute and this attribute is undefined in $attrs of Model class,the data of attribute will be omitted when Model saving.
$object = new \stdClass(); $object->name = 'ooobject'; $user = new User(); $user->name = 'michael'; $user->myobject = $object; // this attribute will be omitted when saving to DB $user->save();
Model CRUD
Create
$user = new User(); $user->name = "Michael"; $user->age = 18; $user->save();
Create with initial value
$user = new User( array('name'=>"John") ); $user->age = 20; $user->save();
Create using set method
$user->setLastName('Jones'); // Alias of $user->lastName = 'Jones'; $user->setFirstName('John'); // Implements setFirstName() method
Set and get values
You can set/get values via variable $user->name = "John"
or by method $user->getName()
.
Set using variable or method
// no "set" method exists $user->lastName = 'Jones'; $user->setLastName('Jones'); // "set" method exists implements setFirstName() $user->firstName = 'jOhn'; // "John" $user->setFirstName('jOhn'); // "John"
Get using variable or method
// "get" method exists implements getLastName() print $user->lastName; // "JONES" print $user->getLastName(); // "JONES" // no "get" method print $user->firstName; // "John" print $user->setFirstName('John'); // "John"
Update
$user->age = 19;
Update attributes by array
$user->update( array('age'=>18,'hobbies'=>array('music','game') ) ); $user->save();
Unset attributes
$user->unset('age'); $user->unset( array('age','hobbies') ); //or unset($user->age);
Retrieve single record
$user = User::one( array('name'=>"michael" ) );
retrieve one record by MongoId
$id = "517c850641da6da0ab000004"; $id = new \MongoId('517c850641da6da0ab000004'); //another way $user = User::id( $id );
Retrieve records
Retrieve records that name is 'Michael' and acount of owned books equals 2
$params = array( 'name'=>'Michael','books'=>array('$size'=>2) ); $users = User::find($params); // $users is instance of Collection echo $users->count();
Retrieve all records
$users = User::all();
Count records
$count = User::count(array('age'=>16));
Delete record
$user = User::one(); $user->delete();
Relationship - Reference
Lazyload a 1:1 relationship record
$book = new Book(); $book->name = "My Love"; $book->price = 15; $book->save(); // !!!remember you must save book before!!! $user->book_fav = $book; $user->save(); // now you can do this $user = User::one( array('name'=>"michael" ) ); echo $user->book_fav->name;
Lazyload 1:many relationship records
$user = User::one(); $id = $user->getId(); $book1 = new Book(); $book1->name = "book1"; $book1->save(); $book2 = new Book(); $book2->name = "book2"; $book2->save(); $user->books = array($book1,$book2); //also you can $user->books = Collection::make(array($book1,$book2)); $user->save(); //somewhere , load these books $user = User::id($id); $books = $user->books; // $books is a instance of Collection
Relationship - Embed
Single Embed
$pet = new Pet(); $pet->name = "putty"; $user->pet_fav = $pet; $user->save(); // now you can do this $user = User::one( array('name'=>"michael" ) ); echo $user->pet_fav->name;
Embeds
$user = User::one(); $id = $user->getId(); $pet_dog = new Pet(); $pet_dog->name = "puppy"; $pet_dog->save(); $pet_cat = new Pet(); $pet_cat->name = "kitty"; $pet_cat->save(); $user->pets = array($pet_cat,$pet_dog); //also you can $user->pets = Collection::make(array($pet_cat,$pet_dog)); $user->save(); $user = User::id($id); $pets = $user->pets;
Collection
$users is instance of Collection
$users = User::find( array( 'name'=>'Michael','books'=>array('$size'=>2) ) ); $users_other = User::find( array( 'name'=>'John','books'=>array('$size'=>2) ) );
Save
$users->save() ; // foreach($users as $user) { $user->save(); }
Delete
$users->delete() ; // foreach($users as $user) { $user->delete(); }
Count
$users->count(); $users->isEmpty();
Iteration
foreach($users as $user) { } // OR use Closure $users->each(function($user){ })
Sort
//sort by age desc $users->sortBy(function($user){ return $user->age; }); //sort by name asc $users->sortBy(function($user){ return $user->name; } , true); //reverse collection items $users->reverse();
Slice and Take
$users->slice(0,1); $users->take(2);
Map
$func = function($user){ if( $user->age >= 18 ){ $user->is_adult = true; } return $user; }; $users->map($func)->save();
Filter
$func = function($user){ if( $user->age >= 18 ){ return true; } } $adults = $users->filter($func); // $adults is a new collection
Determine a record exists in the collection by object instance
$john = User::one(array("name"=>"John")); $users->has($john)
Determine a record exists in the collection by numeric index
$users->has(0)
Determine a record exists in the collection by MongoID
$users->has('518c6a242d12d3db0c000007')
Get a record by numeric index
$users->get(0)
Get a record by MongoID
$users->get('518c6a242d12d3db0c000007')
Remove a record by numeric index
$users->remove(0)
Remove a record by MongoID
$users->remove('518c6a242d12d3db0c000007')
Add a single record to collection
$bob = new User( array("name"=>"Bob")); $bob->save(); $users->add($bob);
Add records to collection
$bob = new User( array("name"=>"Bob")); $bob->save(); $lisa = new User( array("name"=>"Lisa")); $lisa->save(); $users->add( array($bob,$lisa) );
Merge two collection
$users->add($users_other); // the collection $users_other appends to end of $users
Export data to a array
$users->toArray();
Inheritance
Define multilevel inheritable models:
use Purekid\Mongodm\Model; namespace Demo; class Human extends Model{ static $collection = "human"; protected static $attrs = array( 'name' => array('default'=>'anonym','type'=>'string'), 'age' => array('type'=>'integer'), 'gender' => array('type'=>'string'), 'dad' => array('type'=>'reference','model'=>'Demo\Human'), 'mum' => array('type'=>'reference','model'=>'Demo\Human'), 'friends' => array('type'=>'references','model'=>'Demo\Human'), ) } class Student extends Human{ protected static $attrs = array( 'grade' => array('type'=>'string'), 'classmates' => array('type'=>'references','model'=>'Demo\Student'), ) }
Use:
$bob = new Student( array('name'=>'Bob','age'=> 17 ,'gender'=>'male' ) ); $bob->save(); $john = new Student( array('name'=>'John','age'=> 16 ,'gender'=>'male' ) ); $john->save(); $lily = new Student( array('name'=>'Lily','age'=> 16 ,'gender'=>'female' ) ); $lily->save(); $lisa = new Human( array('name'=>'Lisa','age'=>41 ,'gender'=>'female' ) ); $lisa->save(); $david = new Human( array('name'=>'David','age'=>42 ,'gender'=>'male') ); $david->save(); $bob->dad = $david; $bob->mum = $lisa; $bob->classmates = array( $john, $lily ); $bob->save();
Retrieve and check value:
$bob = Student::one( array("name"=>"Bob") ); echo $bob->dad->name; // David $classmates = $bob->classmates; echo $classmates->count(); // 2 var_dump($classmates->get(0)); // john
Retrieve subclass
Retrieve all Human records , queries without '_type' because of it's a toplevel class.
$humans = Human::all();
Retrieve all Student records , queries with { "_type":"Student" } because of it's a subclass.
$students = Student::all();
Retrieve subclass without _type
To retrieve a record without the _type
criteria (i.e. { "_type":"Student" }
) set:
class Student extends \Purekid\Mongodm\Model { protected static $useType = false; protected static $collection = 'Student'; }
Make sure to set a collection otherwise you will get results with every _type
.
Other static methods in Model
User::drop() // Drop collection User::ensureIndex() // Add index for collection
Model Hooks
The following hooks are available:
__init()
Executed after the constructor has finished
__preInsert()
Executed before saving a new record
__postInsert()
Executed after saving a new record
__preUpdate()
Executed before saving an existing record
__postUpdate()
Executed after saving an existing record
__preSave()
Executed before saving a record
__postSave()
Executed after saving a record
__preDelete()
Executed before deleting a record
__postDelete()
Executed after deleting a record