自从我将Mongo PHP驱动程序从1.5.8升级到1.6.0后,我遇到了PHP MongoCursor的问题
以下代码适用于1.5.8版,但与版本1.6崩溃
PHP版本是5.5.21。,Apache版本是Apache / 2.4.10(Ubuntu)
$mongoClient = new \MongoClient($serverUrl, ['readPreference'=>\MongoClient::RP_NEAREST]);
$database = $mongoClient->selectDB($dbName);
$collection = $database->selectCollection($collectionName);
// count() works fine and returns the right nb on documents
echo '<br/>count returned '.$collection->count();
// find() exectues with no error...
$cursor = $collection->find();
$documents = [];
// ...and hasNext() crashes with the Excetion below
while($cursor->hasNext()){$documents[] = $cursor->getNext();}
return $documents;
所以hasNext()调用因此消息崩溃:
CRITICAL:MongoException:MongoCursor对象未被其构造函数正确初始化(未捕获的异常)......
我做错了吗? 谢谢你的帮助!
答案 0 :(得分:3)
这可能与1.6.0中引入的有关hasNext()
和getNext()
PHP-1382迭代的错误有关。修复程序已合并到v1.6
branch,应在本周晚些时候以1.6.1发布。
也就是说,关于hasNext()
的错误实际上是在迭代时会遗漏结果集中的最后一个文档。如果我针对1.6.0运行原始脚本,则该数组包含null
值作为其最后一个元素。有了修复,数组将包含所需的所有文档。我无法重现您在任何一个版本中看到的异常。
该异常实际上是从C数据结构的内部检查引发的,以确保游标对象与MongoClient和套接字连接正确关联。查看this file中的MONGO_CHECK_INITIALIZED()
次来电。大多数游标方法都检查MongoClient是否关联,但hasNext()
是唯一的,因为它还检查套接字对象(我相信其他方法只是假设一个带有MongoClient的游标也有一个套接字)。如果该异常对您来说真的可以重现,并且您愿意使用扩展进行一些调试,那么我很有兴趣知道这两个检查中的哪一个会引发错误。
作为旁注,您还应该在构造MongoClient时指定"replicaSet"
选项。这应该具有副本集名称,这可以确保驱动程序可以正确地忽略与不是预期副本集成员的主机的连接。
答案 1 :(得分:1)
我刚遇到同样的问题;我重构了我的代码以使用游标迭代器,即:
foreach( $cursor as $doc ) {
$documents[] = $doc;
}
答案 2 :(得分:1)
我正在寻找一个如何实现tailable游标的代码示例,并找到了这个问题。以下代码是您在加盖的mongodb集合上提供的tailable游标(通过$ cursor变量)的简单示例。
$cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}