MongoPHP-MongoCursor异常与MongoDB PHP驱动程序v1.6
自从我将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)MongoPHP-MongoCursor异常与MongoDB PHP驱动程序v1.6,php,mongodb,cursor,Php,Mongodb,Cursor,自从我将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\u最近的]); $database=$mongoClient->selectDB($dbName)
$mongoClient=new\mongoClient($serverUrl,['readPreference'=>\mongoClient::RP\u最近的]);
$database=$mongoClient->selectDB($dbName);
$collection=$database->selectCollection($collectionName);
//count()工作正常,并在文档上返回正确的nb
echo'
count返回'$collection->count();
//find()执行时没有错误。。。
$cursor=$collection->find();
$documents=[];
//…和hasNext()崩溃,并出现以下异常
而($cursor->hasNext()){$documents[]=$cursor->getNext();}
归还$3文件;
因此,hasNext()调用会崩溃,并显示以下消息:
严重:MongoException:MongoCorsor对象的构造函数未正确初始化(未捕获异常)
我做错什么了吗?
谢谢你的帮助 这可能与1.6.0中引入的关于使用
hasNext()
和getNext()
进行迭代的bug有关。一个修复程序已经被合并到,应该在本周晚些时候作为1.6.1发布
也就是说,关于hasNext()
的错误实际上是,在迭代过程中会丢失结果集中的最后一个文档。如果我在1.6.0上运行您的原始脚本,数组将包含一个null
值作为其最后一个元素。修复到位后,数组将按预期包含所有文档。我无法复制您在两个版本中看到的异常
该异常实际上是在对C数据结构进行内部检查时引发的,以确保游标对象与MongoClient和套接字连接正确关联。请参阅中的MONGO\u CHECK\u INITIALIZED()
宏调用。大多数游标方法都会检查MongoClient是否关联,但是hasNext()
的独特之处在于它还检查套接字对象(我相信其他方法只是假设带有MongoClient的游标也有套接字)。如果这个异常对您来说确实是可复制的,并且您愿意对扩展进行一些调试,那么我很想知道这两个检查中的哪一个抛出了错误
另外,在构造MongoClient时,还应该指定
“replicaSet”
选项。这应该具有副本集名称,以确保驱动程序可以正确忽略与不是预期副本集成员的主机的连接。我刚刚遇到了相同的问题;我重构了代码,改为使用游标迭代器,即:
foreach( $cursor as $doc ) {
$documents[] = $doc;
}
我在寻找如何实现可裁剪游标的代码示例,发现了这个问题。下面的代码是一个简单的可定制游标示例(通过$cursor变量),您在一个capped mongodb集合上提供了该游标
$cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}
我有同样的problem@LeonardoDelfino:请看下面我的回答。我很想知道这对您来说是否容易复制,以及您是否愿意进一步调试它。1.6.1驱动程序现在可用:仅供参考:1.6.1使用
hasNext()
遗漏了一个边缘案例。这应该在今天发布的1.6.2中修复:请添加一些详细信息。只有代码的答案没有那么有用。请编辑我的评论以澄清。谢谢
$cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}