php 7.4+ 必须使用 mongodb 扩展和 mongodb\client,禁用已废弃的 mongo/mongoclient;需确认扩展加载、uri 含 retrywrites=true、密码 url 编码、find() 返回 cursor 需 toarray() 或 foreach 遍历、查 objectid 必须实例化。

别学“MongoClient”或“Mongo”类——它们早被废弃,PHP 7.4+ 直接报错。现在唯一能用、官方维护的只有 mongodb 扩展 + MongoDB\Client,所有老教程里带 Mongo 或 MongoClient 的代码,复制粘贴就挂。
确认 mongodb 扩展已装好,否则后面全是 Class not found
没装扩展,MongoDB\Client 就是个不存在的类。别跳过这步:
- 运行
php -m | grep mongodb,有输出才算加载成功 - 没输出?Linux/macOS 用
pecl install mongodb,Windows 去 pecl.php.net/package/mongodb 下对应 PHP 版本 + TS/NTS 的php_mongodb.dll,放进ext/并在php.ini加extension=php_mongodb.dll - 装完重启 Web 服务(Apache/Nginx)或 CLI 环境,再跑
php -r "var_dump(extension_loaded('mongodb'));",必须返回bool(true)
连接字符串漏 ?retryWrites=true,写操作会静默失败
不是连不上,是连上了但 insertOne()、updateOne() 看似执行了,实际没生效——尤其在 MongoDB Atlas 或副本集上。根本原因是驱动默认要求写入重试机制,不显式开启就拒绝写。
- 本地单机也建议统一加:
mongodb://localhost:27017/?retryWrites=true - 带认证的 URI 要 URL 编码密码:
mongodb://user:%40pass%2Fword@localhost:27017/mydb?retryWrites=true(@→%40,/→%2F) - Atlas 连接必须含
?ssl=true&tls=true&retryWrites=true&w=majority,少一个参数都可能卡在写入阶段
find() 返回的是 Cursor,不是数组,直接 var_dump 就懵
$cursor = $collection->find([]); 这行代码本身不查数据,也不报错,但 var_dump($cursor) 只能看到对象结构,文档内容根本出不来。
- 要一次性取全部(小数据量):
$cursor->toArray() - 要流式处理(推荐,防内存溢出):
foreach ($cursor as $doc) { echo $doc['name']; } - 想限制条数,用选项:
$collection->find([], ['limit' => 5]),别在 PHP 层用array_slice() - 查单条用
findOne(),它直接返回数组或null,不用转
_id 字段不是字符串,ObjectId 必须实例化才能查
插入时如果没传 _id,驱动自动生成 MongoDB\BSON\ObjectId;但你用字符串去查,比如 findOne(['_id' => '60a1b2c3d4e5f67890123456']),永远查不到。
- 查前先 new:
findOne(['_id' => new MongoDB\BSON\ObjectId('60a1b2c3d4e5f67890123456')]) - 插入时想指定
_id,也得用 ObjectId 实例:insertOne(['_id' => new MongoDB\BSON\ObjectId(), 'name' => 'Alice']) - 从文档里取出来的
_id是 ObjectId 对象,不是字符串,打印要用(string)$doc['_id']
最常踩的坑不在语法,而在类型隐式转换和驱动行为差异:ObjectId 不等于字符串、Cursor 不等于数组、retryWrites 不是可选项——这些点一旦忽略,调试时间远超写代码时间。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











