自从我升级到 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() 调用崩溃并显示以下消息:
严重:MongoException:MongoCursor 对象未被其构造函数正确初始化(未捕获的异常)...
我做错了什么吗?谢谢你的帮助!
这可能与 1.6.0 中引入的关于使用 hasNext()
和 getNext()
迭代的错误有关:PHP-1382。此后,修复程序已合并到v1.6
分支中,应于本周晚些时候作为 1.6.1 发布。
也就是说,关于hasNext()
的错误实际上是在迭代时会丢失结果集中的最后一个文档。如果我针对 1.6.0 运行您的原始脚本,则数组包含一个 null
值作为其最后一个元素。修复完成后,数组将按预期包含所有文档。我无法重现您在任一版本中看到的异常。
该异常实际上是从对 C 数据结构的内部检查中引发的,以确保游标对象与 MongoClient 和套接字连接正确关联。请参阅此文件中的MONGO_CHECK_INITIALIZED()
宏调用。大多数游标方法都检查MongoClient是否关联,但hasNext()
的独特之处在于它还检查套接字对象(我相信其他方法只是假设带有MongoClient的游标也有套接字)。如果该异常对您来说确实是可重现的,并且您愿意对扩展进行一些调试,那么我很想知道两个检查中的哪一个抛出了错误。
作为旁注,在构造MongoClient时,您还应该指定"replicaSet"
选项。这应具有副本集名称,这可确保驱动程序可以正确忽略与不是预期副本集成员的主机的连接。
我刚刚遇到了同样的问题;我重构了我的代码以改用光标迭代器,即:
foreach( $cursor as $doc ) {
$documents[] = $doc;
}
我正在寻找如何实现可尾游标的代码示例并找到了这个问题。 以下代码是您在有上限的 mongodb 集合上提供的可尾游标(通过 $cursor 变量)的简单示例。
$cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}