PHP-Bson库早已被弃用,正确路径是安装ext-mongodb扩展(非Composer包)并搭配mongodb/mongodb客户端库;BSON编解码由扩展内置提供,Binary等类型直接映射MongoDB原生格式。

PHP-Bson 库早已被弃用,Composer 安装 mongodb/mongodb 或直接使用官方 ext-mongodb 扩展才是正确路径 —— 它不提供独立的“PHP-Bson”包,所谓“安装 PHP-Bson”本质是混淆了扩展、驱动和客户端库的关系。
为什么找不到 php-bson 的 Composer 包?
因为 php-bson 从来就不是 Composer 可安装的纯 PHP 库。它是 ext-mongodb 扩展内部使用的底层 BSON 编解码实现,随扩展一起编译进 PHP 进程,不暴露为独立命名空间或类。你在 Packagist 上搜 php-bson,结果为空或指向过时的 fork(如 alcaeus/mongo-php-adapter),这些都不应再使用。
常见错误现象:
- 执行
composer require php-bson报错 “Could not find package php-bson” - 误装
mongodb/mongodb后调用Bson::encode()失败,提示类未找到 —— 因为该库不提供Bson工具类,它只封装高级 CRUD 操作
真正需要安装的是 ext-mongodb 扩展,不是 Composer 包
所有 BSON 序列化/反序列化能力(比如处理 ObjectId、UTCDateTime、二进制字段 Binary)都由 ext-mongodb 提供,并在 PHP 运行时自动生效。Composer 只负责安装高级客户端库 mongodb/mongodb,它依赖这个扩展。
立即学习“PHP免费学习笔记(深入)”;
实操步骤:
- Linux/macOS:用
pecl install mongodb,然后确保extension=mongodb.so写入php.ini - Windows:下载对应 PHP 版本的
php_mongodb.dll(从 pecl.php.net),放入ext/目录并启用 - 验证是否成功:
php -m | grep mongodb或var_dump(extension_loaded('mongodb'));
没装扩展,即使 composer require mongodb/mongodb 成功,运行时也会报致命错误:Class 'MongoDB\Driver\Manager' not found。
如何用原生 BSON 类型操作二进制数据?
扩展自带的 MongoDB\BSON\Binary 是处理二进制字段的正确方式,不是靠“PHP-Bson 库”。它直接映射 MongoDB 的 BinData 类型,支持子类型(如 0x00 通用、0x05 二进制数据)。
示例(存取 PNG 图片二进制):
<?php
use MongoDB\BSON\Binary;
// 将图片读为二进制,并标记为子类型 0x00(Generic)
$imageData = file_get_contents('/path/to/photo.png');
$binary = new Binary($imageData, 0x00);
// 插入到文档
$document = ['name' => 'avatar', 'data' => $binary];
$manager->executeCommand('db', new \MongoDB\Driver\Command([
'insert' => 'files',
'documents' => [$document]
]));
// 查询后还原
$result = $manager->executeQuery('db.files', new \MongoDB\Driver\Query(['name' => 'avatar']));
foreach ($result as $doc) {
if ($doc->data instanceof Binary) {
file_put_contents('/output.png', $doc->data->getData());
}
}
注意点:
-
Binary::getData()返回原始string,不是 base64;别用json_encode()直接序列化,会丢失类型 - 子类型选错(比如误用
0x02表示带长度前缀的旧格式)会导致 MongoDB 拒绝写入或驱动解析失败 - 若需 JSON 交互,用
MongoDB\BSON\fromPHP()+toPHP()转换,而非手动处理Binary
最容易被忽略的是:BSON 二进制字段的语义完全由子类型决定,而子类型必须与应用层约定一致 —— 驱动不会校验你传的 0x05 是否真对应 UUID,它只原样存取。



















