PHP 8.1+ 连 MongoDB 必须安装官方 mongodb 扩展,使用 MongoDB\Client 并在连接字符串中添加 ?retryWrites=true;find() 返回游标需调用 toArray() 或 foreach 遍历;插入时 _id 必须为 ObjectId 实例。

PHP 8.1+ 连 MongoDB 必须装 mongodb 扩展,不是 mongo
老教程常提的 mongo 扩展早在 2018 年就废弃了,PHP 7.4+ 完全不兼容。现在唯一支持的扩展是 mongodb(由 MongoDB 官方维护),它提供 MongoDB\Driver\Manager 和 MongoDB\Client 两类接口。
安装方式取决于你的环境:
- Linux(pecl):
pecl install mongodb,然后在php.ini加extension=mongodb -
macOS(Homebrew + PHP):
brew install php-mongodb(对应你用的 PHP 版本,如php81-mongodb) - Windows:去 pecl.php.net 下载对应线程安全(TS)/非 TS、PHP 版本、VC 编译器版本的
php_mongodb.dll,放进ext/目录并启用
装完运行 php -m | grep mongodb 或 phpinfo() 确认扩展已加载。没这步,后面所有代码都会报 Class 'MongoDB\Client' not found。
MongoDB\Client 初始化时连接字符串不能漏 /?retryWrites=true
这是现代 MongoDB 驱动默认要求的写入重试机制,不加会导致连接成功但写操作失败(尤其在副本集或 Atlas 上)。标准连接字符串长这样:
立即学习“PHP免费学习笔记(深入)”;
$client = new MongoDB\Client('mongodb://localhost:27017/?retryWrites=true');
常见漏配点:
- 本地单机没认证:用
mongodb://localhost:27017即可,但建议显式加上?retryWrites=true - 带用户名密码:写成
mongodb://myuser:mypass@localhost:27017/mydb?retryWrites=true,注意密码里如果有特殊字符(如/、@),必须 URL 编码 - 连接 MongoDB Atlas:完整 URI 通常带
?ssl=true&tls=true&retryWrites=true&w=majority,少任意一个参数都可能连不上或写失败
查数据别直接用 find() 返回游标,记得 toArray() 或遍历
find() 返回的是 MongoDB\Driver\Cursor 对象,不是数组。直接 print_r($cursor) 只能看到对象结构,看不到实际文档。
正确做法:
- 要一次性取全部结果:
$cursor->toArray()—— 适合小数据量,比如查用户列表 - 要逐条处理避免内存爆炸:
foreach ($cursor as $doc) { ... }—— 游标自动流式读取,不缓存全部结果 - 想限制条数:
$collection->find([], ['limit' => 10]),而不是在 PHP 层用array_slice()
错误示例:$result = $collection->find(['status' => 'active']); var_dump($result); → 输出是 object(MongoDB\Driver\Cursor)#5,什么文档都看不到。
插入文档时 _id 字段类型必须是 MongoDB\BSON\ObjectId,不能是字符串
如果你手动指定 _id,比如 ['_id' => 'abc123', 'name' => 'test'],驱动不会报错,但这个 _id 会被当普通字符串存进去,失去 ObjectId 的时间戳、机器标识等语义,且后续用 ObjectId('abc123') 查询会失败(因为类型不匹配)。
正确写法:
- 让数据库自动生成:
$collection->insertOne(['name' => 'test'])→ 返回结果含$result->getInsertedId()是ObjectId实例 - 手动指定 ObjectId:
$collection->insertOne(['_id' => new MongoDB\BSON\ObjectId('65a1b2c3d4e5f67890123456'), 'name' => 'test']) - 从 URL 或表单接收 ID 字符串时,先校验再转:
if (MongoDB\BSON\ObjectId::isValid($idStr)) { $oid = new MongoDB\BSON\ObjectId($idStr); }
ObjectId 校验和转换这步容易跳过,导致查询静默失败或索引失效,尤其是从 REST API 接收 ID 参数时。











