MongoDB PHP 扩展

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)        |                       |                  |
+------------------+                       +------------------+
  • Extensionmongodb(C 实现,低级 API)
  • Librarymongodb/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()
批量操作insertManybulkWrite
投影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未安装 Librarycomposer require mongodb/mongodb
extension mongodb not loaded未安装 PECLpecl 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";

十四、学习资源


你想实现什么?

场景我可以提供
Laravel + 事务完整模型 + 迁移
高并发日志系统批量写入 + GridFS
文件上传下载GridFS 完整封装
微服务连接池配置优化
迁移 MySQL → MongoDB数据转换脚本

请告诉我:

  1. 使用框架(Laravel?Symfony?原生?)
  2. PHP 版本
  3. 业务模型(用户、订单、日志?)
  4. 性能要求(QPS?文件大小?)

我可以为你生成 可运行的完整代码 + 部署脚本

文章已创建 2371

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部