MongoDB PHP 扩展全攻略(2025 最新版)
MongoDB 官方推荐的 PHP 驱动是 MongoDB PHP Library + Extension,由 PECL 扩展(C 实现)和 PHP Library(用户空间)组成,适用于 Laravel、Symfony、ThinkPHP、原生 PHP 等所有场景。
一、架构图
+------------------+ PECL Extension +------------------+
| PHP 用户代码 | <---> mongodb.so <---> | MongoDB Server |
| (Library) | | |
+------------------+ +------------------+
- Extension:
mongodb(C 实现,低级 API) - Library:
mongodb/mongodb(Composer 包,用户友好 API)
二、安装方式(推荐 Composer + PECL)
1. 安装 PECL 扩展(必须)
# CentOS/RHEL
sudo yum install php-pecl-mongodb
# Ubuntu/Debian
sudo apt install php-mongodb
# 或使用 pecl(推荐)
sudo pecl install mongodb
验证安装:
php -m | grep mongodb
# 输出:mongodb
PHP 版本支持:
PHP 版本 扩展版本 8.1+ ≥ 1.17.0 7.4 ≥ 1.12.0
2. 安装 PHP Library(Composer)
composer require mongodb/mongodb
最新版本:
^1.19.0(2025 年)
三、连接 MongoDB
1. 基础连接
<?php
require 'vendor/autoload.php';
use MongoDB\Client;
// 连接本地
$client = new Client("mongodb://localhost:27017");
// 连接副本集 + 认证
$client = new Client(
"mongodb://user:pass@host1:27017,host2:27017,host3:27017/mydb?
replicaSet=rs0&authSource=admin"
);
echo "连接成功!\n";
2. 连接池配置(生产推荐)
$client = new Client(
"mongodb://localhost:27017",
[
'maxConnections' => 50,
'minConnections' => 10,
'connectTimeoutMS' => 10000,
'socketTimeoutMS' => 30000,
]
);
四、CRUD 操作
1. 插入
$collection = $client->mydb->users;
// 单条插入
$result = $collection->insertOne([
'name' => 'Alice',
'age' => 25,
'tags' => ['php', 'mongodb'],
'created_at' => new MongoDB\BSON\UTCDateTime()
]);
echo "插入ID: " . $result->getInsertedId() . "\n";
// 批量插入
$collection->insertMany([
['name' => 'Bob', 'age' => 30],
['name' => 'Charlie', 'age' => 35]
]);
2. 查询
// 查找单个
$user = $collection->findOne(['name' => 'Alice']);
print_r($user);
// 条件查询
$filter = [
'age' => ['$gte' => 25, '$lte' => 40]
];
$options = [
'sort' => ['age' => -1],
'limit' => 10,
'skip' => 20
];
foreach ($collection->find($filter, $options) as $user) {
echo $user->name . " (age: {$user->age})\n";
}
3. 更新
// 更新单个
$collection->updateOne(
['name' => 'Alice'],
['$set' => ['age' => 26], '$push' => ['tags' => 'laravel']]
);
// 替换文档
$collection->replaceOne(
['_id' => $id],
['name' => 'Alice', 'status' => 'active', 'updated_at' => new MongoDB\BSON\UTCDateTime()]
);
4. 删除
$collection->deleteOne(['name' => 'Bob']);
$collection->deleteMany(['age' => ['$lt' => 18]]);
五、POJO 支持(数组 <-> 对象)
class User {
public string $name;
public int $age;
public array $tags;
public DateTime $created_at;
}
// 插入
$user = new User();
$user->name = 'Alice';
$user->age = 25;
$user->tags = ['php'];
$user->created_at = new DateTime();
$collection->insertOne($user);
// 查询自动映射
$result = $collection->findOne(['name' => 'Alice']);
$user = $result; // 自动转为 stdClass
注意:默认返回
stdClass,需手动映射或使用框架(如 Laravel Eloquent)
六、聚合(Aggregation)
$pipeline = [
['$match' => ['age' => ['$gte' => 25]]],
['$group' => [
'_id' => '$name',
'total' => ['$sum' => 1],
'avgAge' => ['$avg' => '$age']
]],
['$sort' => ['total' => -1]]
];
foreach ($collection->aggregate($pipeline) as $doc) {
echo "Name: {$doc->_id}, Count: {$doc->total}\n";
}
七、事务(ACID)
$session = $client->startSession();
try {
$session->startTransaction();
$collection->insertOne(['name' => 'Tx1'], ['session' => $session]);
$collection->updateOne(
['name' => 'Alice'],
['$inc' => ['balance' => -100]],
['session' => $session]
);
$session->commitTransaction();
echo "事务成功\n";
} catch (Exception $e) {
$session->abortTransaction();
echo "事务回滚: " . $e->getMessage() . "\n";
} finally {
$session->endSession();
}
要求:MongoDB ≥ 4.0 + 副本集/分片
八、Laravel 集成(推荐)
1. 安装 jenssegers/mongodb
composer require jenssegers/mongodb
2. 配置 config/database.php
'connections' => [
'mongodb' => [
'driver' => 'mongodb',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 27017),
'database' => env('DB_DATABASE', 'mydb'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'options' => [
'database' => 'admin' // authSource
]
],
],
3. Eloquent 模型
use Jenssegers\Mongodb\Eloquent\Model;
class User extends Model {
protected $connection = 'mongodb';
protected $collection = 'users';
protected $fillable = ['name', 'age', 'tags'];
}
// 使用
User::create(['name' => 'Alice', 'age' => 25]);
$user = User::where('age', '>', 20)->get();
九、性能优化
| 优化点 | 建议 |
|---|---|
| 连接池 | 设置 maxConnections |
| 索引 | 使用 createIndex() |
| 批量操作 | insertMany、bulkWrite |
| 投影 | find($filter, ['projection' => ['name' => 1]]) |
| 避免 N+1 | 使用聚合或 $lookup |
| 日志 | 启用 mongodb.debug 查看 SQL |
// 批量写入
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['name' => 'A']);
$bulk->insert(['name' => 'B']);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$manager->executeBulkWrite('mydb.users', $bulk);
十、调试与日志
// 启用调试(开发环境)
ini_set('mongodb.debug', 'stderr');
// 查看最后一条命令
$client->getManager()->getLastCommand();
十一、常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
Class 'MongoDB\Client' not found | 未安装 Library | composer require mongodb/mongodb |
extension mongodb not loaded | 未安装 PECL | pecl install mongodb |
Authentication failed | 认证库错误 | 加 ?authSource=admin |
Transaction numbers are only allowed on a replica set | 非副本集 | 部署副本集 |
Document too large | > 16MB | 分片存储或 GridFS |
十二、GridFS(大文件存储)
$bucket = $client->selectGridFSBucket();
// 上传
$stream = $bucket->openUploadStream('photo.jpg');
fwrite($stream, file_get_contents('/path/to/photo.jpg'));
fclose($stream);
// 下载
$stream = $bucket->openDownloadStream($fileId);
fpassthru($stream);
十三、完整示例(原生 PHP)
<?php
require 'vendor/autoload.php';
$client = new MongoDB\Client("mongodb://localhost:27017");
$collection = $client->demo->users;
// 插入
$collection->insertOne([
'name' => 'PHP User',
'email' => 'php@example.com',
'created_at' => new MongoDB\BSON\UTCDateTime()
]);
// 查询
$user = $collection->findOne(['name' => 'PHP User']);
echo "Hello, {$user->name}!\n";
十四、学习资源
- 官方文档:MongoDB PHP Library
- PECL 扩展:pecl.php.net/package/mongodb
- Laravel 集成:jenssegers/mongodb
- 示例项目:GitHub – mongodb/mongo-php-driver
你想实现什么?
| 场景 | 我可以提供 |
|---|---|
| Laravel + 事务 | 完整模型 + 迁移 |
| 高并发日志系统 | 批量写入 + GridFS |
| 文件上传下载 | GridFS 完整封装 |
| 微服务连接池 | 配置优化 |
| 迁移 MySQL → MongoDB | 数据转换脚本 |
请告诉我:
- 使用框架(Laravel?Symfony?原生?)
- PHP 版本
- 业务模型(用户、订单、日志?)
- 性能要求(QPS?文件大小?)
我可以为你生成 可运行的完整代码 + 部署脚本!