phalcon3.0.2整合mongo

php mongo 扩展说明

php的mongo扩展有两个,一个是过期的mongo,一个是新的mongodb,我们这里使用旧版的mongo扩展,理由:我们偏向使用phalcon提供的mongo接口,而我们的phalcon版本比较旧,底层依赖的是mongo扩展。(如果想要使用新的mongodb扩展,可以不使用phalcon提供的接口,直接使用composer引入第三方的mongodb库来操作)

注意问题

  1. 连接mongodb的时候,注意使用以下方式连接:
$dsn = 'mongodb://' . $user . ':' . $password . '@' . $host . ':' . $port . '/' . $dbname;

$result = new \MongoClient($dsn);
$mongo = $result->selectDB($dbname); // 注意这里一定要使用selectDB方法指定数据库

注意点:我们使用的用户授权的test数据库的,所以dsn里面一定要指定数据库($dbname为test),不然会默认选中admin数据库,导致授权失败;另外,即使在dsn里面指定了数据库,代码层面上也要使用selectDB再次指定一次,不然会导致代码中查询数据的时候找不到collection,原因可以看phalcon的以下源码:

let mongoCollection = connection->selectCollection(source);

if typeof mongoCollection != "object" {
   throw new Exception("Couldn't select mongo collection");
}

解释一下:因为源码里面用connection->selectCollection(source),这样写的前提是要先使用selectDB方法的,参考以下:http://php.net/manual/en/mongoclient.selectcollection.php

<?php
$m = new MongoClient();

$c1 = $m->selectCollection("foo", "bar.baz");
// which is equivalent to
$c2 = $m->selectDB("foo")->selectCollection("bar.baz");

// $c1 and $c2 now represent the same collection
?>
  1. 查询mongo的时候,查询条件的数据类型一定要严格按照mongo里面的数据类型,比如下面的atid,mongo里面用的是整型,所以条件里面也一定要转成整型:
$resource = self::findFirst(
    [
        'conditions' => [
            'atid' => intval($atid)
        ],
        'fields' => $field
    ]
);
  1. 如果用了mongo的复制集(Replica Set),查询从库的时候需要在代码层面上指定slaveOkay=true:
public function initialize()
{
    $this->setConnectionService('mongo_mamaquan');
    \MongoCursor::$slaveOkay = true;
}