我正在从mongodb数据库中阅读一个文档,并用php将其传递到客户端。
这个文档包含一个数组属性,问题是客户端接收到的是一个对象,它的属性名为0
,1
等等,而不是一个标准的数组。
这是原始数据:
{
"_id" : ObjectId("573b47a1f99a8a1f9a6278a5"),
"persons" : [
{
"name" : "Moshe",
},
{
"name" : "E",
}, ...
]
}
字符串
根据要求,我附上var_export:
array (
0 =>
MongoDB\Model\BSONDocument::__set_state(array(
'_id' =>
MongoDB\BSON\ObjectID::__set_state(array(
)),
'persons' =>
MongoDB\Model\BSONArray::__set_state(array(
0 =>
MongoDB\Model\BSONDocument::__set_state(array(
'name' => 'Moshe',
)),
1 =>
MongoDB\Model\BSONDocument::__set_state(array(
'name' => 'E',
)),
)),
)),
)
型
var_dump:
array(1) {
[0]=>
object(MongoDB\Model\BSONDocument)#40 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["_id"]=>
object(MongoDB\BSON\ObjectID)#11 (1) {
["oid"]=>
string(24) "573b47a1f99a8d1f986278a5"
}
["persons"]=>
object(MongoDB\Model\BSONArray)#34 (1) {
["storage":"ArrayObject":private]=>
array(2) {
[0]=>
object(MongoDB\Model\BSONDocument)#10 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["name"]=>
string(5) "Moshe"
}
}
[1]=>
object(MongoDB\Model\BSONDocument)#12 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["name"]=>
string(1) "E"
}
}
}
}
}
}
}
型
以下是PHP代码(全部):
function select(){
$conn = new MongoDB\Client("mongodb://localhost:27017");
$db = $conn->mydb;
$cursor = $db->entries_meta_data->find();
return current($cursor->toArray());
}
型
然后我用json_encode将对象传递给客户端,如下所示:
echo json_encode(select());
型
在客户端显示的结果是:
{
"_id" : ObjectId("573b47a1f99a8a1f9a6278a5"),
"persons" : {
"0" : {
"name" : "Moshe",
},
"1" : {
"name" : "E",
}, ...
}
}
型
**编辑:**LordNeo实际上解决了这个问题。在阅读他的答案后,我将“选择”函数中的最后一行改为:
return json_decode(json_encode(current($cursor->toArray()),true);
型
它看起来很可怕,但它工作。
我很乐意听到更好的解决方案。
6条答案
按热度按时间pwuypxnk1#
原因是new MongoDB driver处理MongoDB文档到PHP类型的转换不同于the old driver。
好消息是,你可以通过指定一个所谓的“类型Map”来获得旧的行为。
文档有点隐藏,但你可以在in the github repository of the driver或在线文档中阅读。
TL;DR是你传递一个数组,
字符串
作为MongoDB\Client的构造函数的第三个参数(“driverOptions”),或者为每个查询单独调用MongoDB\Driver\Cursor::setTypeMap()。
在您的示例中,调用
型
在
$db->entries_meta_data->find()
之后应该可以。6yoyoihd2#
MongoDB驱动程序提供了一个
MongoDB\BSON\toJSON()
函数,它可以正确地将数据转换为JSON。因为它需要一个字符串作为输入,所以你首先需要在文档上调用MongoDB\BSON\fromPHP()
。因为看起来你只是想获取第一个找到的元素,所以你可以使用findOne()
方法而不是find()
,这使得获取输出非常容易:字符串
如果你想输出多个条目,它会变得有点复杂。一种(公认的黑客)输出数组的方法如下所示:
型
另一种方法是调整
json_encode()
调用BSONArray类时的输出。为此,您需要调整setting up the MongoDB driver位于'vendor/mongodb/mongodb/src/Model'文件夹中时获得的BSONArray.php文件,并添加JsonSerializable
接口和jsonSerialize()
方法,使其看起来像这样:型
xlpyo6sf3#
使用json_decode时,可以使用可选的“true”参数,它将关联到一个数组
字符串
http://php.net/manual/en/function.json-decode.php
然后你可以使用array_shift剥离索引:
型
http://php.net/manual/en/function.array-shift.php的
JSON在没有显式设置时添加数字索引,因此您可能应该向客户端发送一个数组,而不是再次解码->删除索引->编码->删除索引。
或者在客户端收到索引后删除索引。
ghg1uchk4#
是否有从0到n的所有索引或者它们中的任何一个缺失?这可能是原因。如果你想将它转换回数组,你可能会使用
字符串
然后
型
去掉索引
我仍然很确定缺少了一些值,但是在你的例子中看不到。
hfwmuf9z5#
mthierer几乎有正确的解决方案。
在示例化客户端时,您需要将typeMap放在驱动程序选项(第三个参数)中。
var driver_options ={'typeMap'=>{'root':'array ',' document':'array',' array':'array']}; var client = new MongoDB\Client(conn,options,driver_options);
这比在每次游标示例化之后都这样做要好。
bvn4nwqk6#
对于任何需要使用Laravel雄辩和聚合的人,您可以将第二个参数
$option
传递给聚合方法字符串
查看https://www.mongodb.com/docs/php-library/current/reference/method/MongoDBCollection-aggregate/#definition