如何将带函数的MongoDB日期转换查询改写为PHP代码?
解决MongoDB字符串日期转日期类型的PHP语法错误问题
嘿,我看到你在把Mongo Shell里正常运行的日期转换逻辑改成PHP代码时踩了语法坑,咱们来一步步搞定它~
首先,先回顾下你的问题:你原本在Mongo Shell里用这段代码把字符串类型的created_at转成日期类型是没问题的:
db.sample_collection.find().forEach(function (tweet){ db.sample_collection.update({_id: tweet._id}, {$set: {created_at: new Date(tweet.created_at)}}); });
但转成PHP后就报了Parse error: syntax error, unexpected ')', expecting variable (T_VARIABLE)的错误,咱们先拆解下错误原因,再给出修正后的代码。
错误原因分析
你的PHP代码里有几个明显的语法和API使用问题:
- 匿名函数参数缺少$符号:PHP里变量必须以$开头,你写的
function (tweet)应该是function ($tweet)。 - 字段访问方式错误:你的数据示例是数组结构,所以要访问
_id应该用$tweet['_id'],而不是tweet->"_id"(而且这个写法本身也是错的,PHP里访问对象属性是->,但这里是数组)。 - PHP没有原生Date类:你用的
new Date()是JavaScript的写法,PHP里要处理日期得用DateTime类,还要结合MongoDB扩展的日期类型来适配。 - 变量作用域问题:匿名函数内部无法直接访问外部的
$collection变量,需要用use ($collection)来引入。
修正后的PHP代码(基于新MongoDB PHP扩展)
如果你用的是官方最新的mongodb/mongodb扩展(推荐),可以用下面的代码:
$collection->find()->forEach(function ($tweet) use ($collection) { // 解析你的特定日期格式为DateTime对象 $dateTime = DateTime::createFromFormat('D M d H:i:s O Y', $tweet['created_at']); // 转换为MongoDB兼容的UTCDateTime对象(注意要转成毫秒级时间戳) $utcDate = new MongoDB\BSON\UTCDateTime($dateTime->getTimestamp() * 1000); // 使用updateOne方法(比旧的update更规范) $collection->updateOne( ['_id' => $tweet['_id']], ['$set' => ['created_at' => $utcDate]] ); });
关键细节说明
- 日期格式解析:
DateTime::createFromFormat的第一个参数'D M d H:i:s O Y'是完全匹配你数据里Wed Jan 24 15:25:20 +0000 2018这个格式的,确保能正确解析。 - UTCDateTime的使用:MongoDB存储日期时用的是UTC毫秒时间戳,所以我们把DateTime的时间戳乘以1000后传给UTCDateTime。
- updateOne替代update:新扩展里
updateOne语义更清晰,专门用来更新单条文档,避免意外更新多条数据。
如果你用的是旧版MongoDB扩展(mongo/mongo)
如果你的项目还在使用旧的mongo扩展(不推荐,已停止维护),代码可以改成这样:
$collection->find()->forEach(function ($tweet) use ($collection) { $dateTime = DateTime::createFromFormat('D M d H:i:s O Y', $tweet['created_at']); $mongoDate = new MongoDate($dateTime->getTimestamp()); $collection->update( ['_id' => $tweet['_id']], ['$set' => ['created_at' => $mongoDate]] ); });
内容的提问来源于stack exchange,提问作者codex
相关产品推荐
相关产品推荐

