mongodb\bson\tophp()用于将原始bson二进制字节解码为php数组或对象,而fromphp()已废弃,应改用mongodb\bson\document::fromphp();直接json_decode()无效,因bson非json格式。

PHP怎么用mongodb扩展读取BSON文档
PHP本身不原生支持BSON,必须依赖mongodb扩展(不是已废弃的mongo扩展)。读取BSON数据本质是把二进制BSON解码为PHP数组或对象,关键在MongoDB\BSON\fromPHP()和toPHP()的配合使用。
常见错误是直接用json_decode()处理BSON二进制流,结果得到空或乱码——BSON不是JSON,不能当字符串解析。
- 确保已安装
mongodb扩展(v1.12+推荐),运行php -m | grep mongodb确认 - 从MongoDB驱动获取的文档(如
$collection->findOne()返回值)默认就是PHP数组,无需手动解码 - 若你拿到的是原始BSON字节(比如从文件或网络读取的
string),用MongoDB\BSON\toPHP($bsonBytes)转成数组 - 注意时区:BSON中的
UTCDateTime会转为MongoDB\BSON\UTCDateTime对象,不是DateTime,需调用toDateTime()才能用
PHP写入BSON数据要绕过JSON中间层
很多人习惯先json_encode()再存,这会丢失BSON特有类型(如ObjectId、Binary、Decimal128),导致查出来字段类型错乱。正确做法是构造带BSON类的PHP结构,再用fromPHP()编码。
典型场景:插入一条含自定义ObjectId和二进制头像的数据。
- 不要写
['_id' => '507f1f77bcf86cd799439011'],而要写['_id' => new MongoDB\BSON\ObjectId('507f1f77bcf86cd799439011')] - 二进制图片用
new MongoDB\BSON\Binary($rawData, MongoDB\BSON\Binary::TYPE_GENERIC) - 插入前可选调用
MongoDB\BSON\fromPHP($data)验证结构是否合法,但非必需——驱动会在写入时自动编码 - 避免用
serialize()或json_encode()做预处理,它们会破坏BSON类型语义
MongoDB\BSON\parseJson()和toJSON()的陷阱
这两个函数看似方便,实际是“伪JSON互转”:它们只处理BSON到JSON字符串的格式映射,并不等价于通用JSON编解码。例如parseJson('{ "_id": { "$oid": \"...\" } }')能识别Mongo Shell风格的扩展语法,但普通json_decode()不能。
- 仅当输入是Mongo Shell导出格式(含
$oid、$date等)时才用parseJson() -
toJSON()输出的是扩展JSON(EJSON),含类型标记,不能直接被前端JSON.parse()消费,需加JSON_UNESCAPED_UNICODE等选项控制格式 - 生产环境建议避开
parseJson(),优先用原生PHP数组+BSON类构造,更可控 - 调试时可用
echo MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($data))看EJSON结构,但别把它当序列化手段
从文件读写BSON要注意字节完整性
BSON是二进制格式,文件读写必须用fopen(..., 'rb')和fwrite(),任何文本模式(如'r')或file_get_contents()未指定FILE_BINARY都可能被PHP自动转换换行符,导致BSON校验失败。
- 读BSON文件:
$bytes = file_get_contents($path, false, null, 0, $size);并确保$size准确(BSON头部4字节是文档长度) - 写BSON文件前,先用
MongoDB\BSON\fromPHP($data)得到string,再file_put_contents($path, $bsonBytes, LOCK_EX) - 不要用
mb_convert_encoding()或iconv()处理BSON字节流——它不是文本 - 如果BSON来自HTTP body,检查
Content-Type是否为application/bson,并确认$HTTP_RAW_POST_DATA或php://input读取方式正确
最易被忽略的是BSON文档长度头(前4字节小端整数)必须与实际内容长度一致,否则toPHP()会直接抛Unexpected data异常,而不是静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











