【问题标题】:MongoLab: using php to PUT update using CURLMongoLab:使用 php 使用 CURL 进行 PUT 更新
【发布时间】:2012-07-20 21:29:21
【问题描述】:

我一直在尝试使用 MongoLabs api 来简化我的生活,并且在我尝试使用 php 和 curl 将更新推送到数据库之前,它大部分都在工作,无论如何都没有骰子。我的代码是这样的:

$data_string = json_encode('{"user.userEmail": "USER_EMAIL", "user.pass":"USER_PASS"}');
try { 
$ch = curl_init();

//need to create temp file to pass to curl to use PUT
$tempFile = fopen('php://temp/maxmemory:256000', 'w');
if (!$tempFile) {
    die('could not open temp memory data');
}
fwrite($tempFile, $data_string);
fseek($tempFile, 0); 

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
//curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
//curl_setopt($ch, CURLOPT_INFILE, $tempFile); // file pointer

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, DB_API_REQUEST_TIMEOUT);                                                                    
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                     
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                       
    'Content-Length: ' . strlen($data_string),
    )                                                                              
);   

$cache = curl_exec($ch);
curl_close($ch);
} catch (Exception $e) {
    return FALSE;
}

我的问题似乎出在 MongoLab 的 api 上。除了实验室告诉我我传递的数据是'无效对象{“user.firstName”:“Pablo”,“user.newsletter”:“true”}:存储在db 不能有 .在他们中。'。我尝试过传递一个文件并使用 postfields,但都没有成功。

当我在 Firefox 的海报插件上对其进行测试时,该值工作正常。如果有人对 MongoLabs 的东西有更好的理解,我会喜欢一些启发。提前致谢!

【问题讨论】:

  • 我会从字面上理解错误信息。字段名称不能带有“。”在其中,所以尝试 user_firstName、user_pass 或类似的。
  • 我明白这一点,但在后面的部分中,我能够使用相同的样本测试 api,并且它运行良好。因此,据我了解,问题不在于数据太多,而在于我如何将其传递给 api。将其分配给允许按原样阅读的正文/内容的方式有所不同。

标签: php mongodb curl mlab


【解决方案1】:

您需要删除字段名称中的点。您可以尝试使用这样的架构:

{ "user": { "userEmail": "USER_EMAIL", "pass": "USER_PASS" } }

不幸的是,MongoDB 不支持在字段名称中使用点。这是因为它的查询语言使用点作为运算符来链接嵌套字段名称。如果 MongoDB 允许在字段名称中使用点,那么如果没有某种转义机制,点查询就会变得模棱两可。

如果此文件合法:

{ "bow.ties": "uncool", "bow": { "ties": "cool" } }

这个查询会模棱两可:

{ "bow.ties": "cool" }

不清楚文档是否匹配。您是指字段“bow.ties”还是嵌套在字段“bow”的值中的字段“ties”?

这是演示这些想法的 mongo shell 会话的捕获。

% mongo
MongoDB shell version: 2.1.1
connecting to: test
> db.stuff.save({"bow.ties":"uncool"})
Wed Jul 18 11:17:59 uncaught exception: can't have . in field names [bow.ties]
> db.stuff.save({"bow":{"ties":"cool"}})
> db.stuff.find({"bow.ties":"cool"})
{ "_id" : ObjectId("5006ff3f1348197bacb458f7"), "bow" : { "ties" : "cool" } }

【讨论】:

  • 谢谢,虽然这是 MongoDB 的有效答案(我知道),但我不认为这是我在使用 MongoLabs API 时遇到的问题的答案。保持这种格式(如果可能的话)的原因是它以前通过 js 与应用程序一起工作。如果可能,我会尽量避免完全重写。
  • 你赢了 :) 我将不得不重写它。我正在和 MongoLabs 的人交谈,他们不知道 Poster 是如何使其工作的。插件中一定有魔法。 >_
  • 您可能想查看海报创建的文档。如果它实际上是在数据库中的字段名称中添加点,那么我称之为错误。危险在于其他功能或工具(例如查询、mongodump、MongoLab UI)将无法处理非法字符。但是,它实际上可能正在将点重新映射到其他字符。
【解决方案2】:

在使用了该项目的其他一些功能后,我意识到了自己的错误,并最终意识到了混乱的根源。

curl PUT 旨在将修饰符操作发送到 MongoDB。我将所有数据作为 JSON 发送,并中断解码以在 PHP 中使用,然后重新编码其中的一部分以发送回。所以收到的原始数据是这样的:

{"userEmail":"p@g.com","pass":"****", "$oid":"5555", "$set":{"user.firstName":"Pablo","user.newsletter":"true"}}

问题是我正在获取“$set”对象的值(在 php 中)并仅重新编码值 {"user.firstName":"Pablo","user.newsletter":"true"} 而没有运算符 "$set" 并发送它给出错误。在这种情况下,要发送的正确字符串应该是 {"$set":{"user.firstName":"Pablo","user.newsletter":"true"}}

虽然这是一个简单的错误,但我希望下次有人做这样的事情并得到一个无效的对象错误时,他们很幸运能够找到这个。

【讨论】:

  • 我遇到了同样的问题 - 最终的 sn-p 是什么样的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多