martynbiz / php-mongo
PHP 的 MongoDB ODM。
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: 4.8.*
This package is not auto-updated.
Last update: 2024-09-14 18:20:41 UTC
README
使用 composer 安装
$ composer require martynbiz/php-mongo
入门
创建连接
\MartynBiz\Mongo\Connection::getInstance()->init(array( 'db' => 'mydb', 'username' => 'myuser', 'password' => '89dD7HH7di!89', 'classmap' => array( 'users' => '\\App\\Model\\User', ), ));
创建模型
通过扩展 Mongo 类创建模型,确保定义 $collection 和 $whitelist
<?php use MartynBiz\Mongo; class User extends Mongo { // required - collection this model refers to protected static $collection = 'users'; // required - define on the fields that can be saved protected static $whitelist = array( 'name', 'email', 'username', 'password', ); }
创建多个连接
如果只使用单个数据库,这并不必要。但是,如果您需要连接到多个数据库,请给每个连接一个唯一的名称
Connection::getInstance('conn1')->init(array( ... )); // also, checking if an instance exists if (! Connection::hasInstance('conn2')) { Connection::getInstance('conn2')->init(array( ... )); }
另外,请记住在模型中声明哪个 $conn
<?php use MartynBiz\Mongo; class User extends mongo { // optional - if using multiple connections/databases protected static $conn = 'conn1'; . . . }
查询
通过 mongo 查询查找
// statically $users = User::find(array( 'status' => 1, )); // dynamically $col = new User(); $users = $col->find(array( 'status' => 1, ));
通过 mongo 查询查找一个
// statically $user = User::findOne(array( 'email' => 'info@examle.com', )); // dynamically $col = new User(); $user = $col->findOne(array( 'email' => 'info@examle.com', ));
通过对象查找
模型实例也可以传递,find 方法会将其内部转换为 DBRef(例如 'friend' => $friend 将与 'friend' => $friend->getDBRef() 相同)
$friend = User::findOne(array( //... )); $user = User::find(array( 'friend' => $friend, ));
获取和设置值
// setting // on instantiation -- will be filtered against $whitelist $article = new Article(array( 'title' => 'My title', )); $author = User::findOne(array( //... )); // single value properties -- no param filtering $article->status = 2; $article->author = $author; // AND/OR set() method, with Mongo instance -- suited for unit testing, no param filtering $user = User::findOne(array( //... )); $article->set('author', $author); // set value as query result (will be stored as an array of dbrefs) $tags = Tag::find(array( //... )); $article->tags = $tags; // lastly, params can be passed with save() -- will be filtered against $whitelist $article->save(array( 'content' => $text, ))
// getting $article = Article::findOne(array( //... )); // single value properties -- no param filtering echo $article->status; echo $article->author->name; echo $article->tags[0]->name; echo $article->get('author');
插入
save 方法用于模型类的实例化对象。它可以在分配属性值之后调用,或者通过传递名称/值作为参数。注意:当传递名称/值时,值将被白名单化
$user->name = 'Jim'; $user->save();
$user->save(array( 'name' => 'Jim', ));
create 方法不需要实例,但它将接受名称\值并在其中插入到集合中。它将返回创建的文档的实例。注意:当传递名称/值时,值将被白名单化
// statically $user = User::create(array( 'name' => 'Jim', )); // dynamically (e.g. service locator pattern, or DI) $col = new User(); $user = $col->create(array( 'name' => 'Jim', ));
工厂方法实际上不插入,但会生成具有值的实例。然后可以使用它的 save 方法对其进行修改和插入
// statically $user = User::factory(array( 'name' => 'Jim', )); // dynamically $col = new User(); $user = $col->factory(array( 'name' => 'Jim', )); $user->save();
虽然看起来有多种方法,但它确实提供了保持代码整洁和测试时模拟方法的灵活性。
推送
注意:push with $each 是这里的默认行为,尽管这可以通过 options 数组中的 'each' => false 覆盖
// push one object, will convert to DBRef $user->push(array( 'friends' => $friend, )); // push multi object, will convert to DBRef $user->push(array( 'friends' => array( $friend, $friend2, ), )); // push MongoIterator object (from find() call) $user->push(array( 'friends' => $friends, )); // push multiple properties at once $user->push(array( 'friends' => $friends, 'enemies' => $enemies, )); // push without $each setting, will push the whole array as a single element $user->push(array( 'friends' => array( $friend, $friend2, ), ), array('each' => false));
删除
一个实例可以使用 delete 方法从数据库中删除自己
$user->delete();
要使用查询从集合中删除多个文档,请使用 remove 方法
User::remove(array( 'type' => 'boring', ), $options);
转换为数组
$user->toArray(3); // convert nested 3 deep to array (optional)
验证
在保存到数据库之前,会调用 validate 方法。如果它返回 false,则数据将不会保存。
class User extends mongo { . . . public function validate() { $this->resetErrors(); if (empty($this->data['name'])) { $this->setError('Name is missing.'); } return empty( $this->getErrors() ); // true if none } }
以下示例使用 martynbiz/php-validator 库。
<?php use MartynBiz\Validator; class User extends mongo { . . . public function validate() { $this->resetErrors(); $validator = new Validator($this->data); $validator->check('name') ->isNotEmpty('Name is missing'); $validator->check('email') ->isNotEmpty('Email address is missing') ->isEmail('Invalid email address'); $message = 'Password must contain upper and lower case characters, and have more than 8 characters'; $validator->check('password') ->isNotEmpty($message) ->hasLowerCase($message) ->hasUpperCase($message) ->hasNumber($message) ->isMinimumLength($message, 8); // update the model's errors with the validators $this->setError( $validator->getErrors() ); return empty($this->getErrors()); } }
自定义 Getter/ Setter
要自动在获取时转换值,您可以定义自定义方法来自动转换属性的值。这可能在对字符串进行格式化时很有用,例如将日期格式化为人类可读格式。
<?php use MartynBiz\Mongo; class User extends Mongo { . . . public function getCreatedAt($value) { return date('Y-M-d h:i:s', $this->data['created_at']->sec); } public function setPassword($value) { return password_hash($value, PASSWORD_BCRYPT); } }
TODO
- 支持点符号语法?find(array('model.name' => 'Martyn')), set/get(array(model.name' => 'Martyn'))