webman需手动集成mongodb扩展与mongodb/mongodb库,禁用热重载以防连接泄漏;须用selectdatabase()显式指定库名,client实例应单例复用并避免协程不安全操作。

Webman 默认不内置 MongoDB 支持,必须手动集成 PHP 的 mongodb 扩展 + 官方高阶库 mongodb/mongodb,再配合 Webman 的生命周期管理方式使用;直接照搬 Laravel 或原生 PHP 的写法容易在长连接、协程或热重载场景下出错。
确认已启用 PHP 的 mongodb 扩展(不是 mongo)
Webman 运行在 PHP 上,所有数据库操作都依赖底层扩展。如果看到 Class 'MongoDB\Driver\Manager' not found 或 Extension 'mongo' is not loaded,说明装错了。
- 运行
php -m | grep mongodb,必须输出mongodb(注意没有o结尾) - 旧的
mongo扩展已废弃,PHP 7.0+ 完全不兼容,pecl install mongo是错误操作 - Ubuntu/Debian:用
sudo apt install php-mongodb,检查php.ini中有无extension=mongodb.so - Windows:下载对应 PHP 版本(TS/NTS、VC16/VC17)、线程安全标识的
php_mongodb.dll,放进ext/并在php.ini加extension=php_mongodb.dll - 装完务必重启
php-fpm或 Webman 进程(php start.php stop && php start.php start)
用 Composer 安装 mongodb/mongodb 并避免自动实例化
mongodb/mongodb 是官方维护的高阶封装库,提供 MongoDB\Client 和集合操作 API;但它本身不替代扩展,只是语法糖。Webman 是常驻内存框架,new MongoDB\Client() 不能写在每次请求里。
- 执行
composer require mongodb/mongodb,确保生成了vendor/autoload.php - 不要在控制器方法里每次 new
Client—— 它内部会新建Manager实例,连接池无法复用,可能耗尽 socket - 推荐在
config/bootstrap.php或自定义服务提供者中初始化一次,并绑定到容器:
// config/bootstrap.php
use MongoDB\Client;
$container->bind('mongodb.client', function () {
return new Client('mongodb://127.0.0.1:27017', [
'connectTimeoutMS' => 5000,
'socketTimeoutMS' => 30000,
]);
});
- 然后在控制器中通过
$this->container->get('mongodb.client')获取复用实例
Webman 中执行查询必须显式指定库名和集合名
PHP 的 MongoDB 驱动不保留当前数据库上下文,use mydb 这类 shell 习惯在代码里完全无效。漏写库名会直接抛出 MongoDB\Driver\Exception\InvalidArgumentException。
- 正确写法:
$collection = $client->selectDatabase('myapp')->selectCollection('users'); - 错误写法:
$client->myapp->users(虽然语法能过,但实际行为不可靠,尤其在开启 strict mode 时) - 集合名不能含空格、点号(
.)、美元符($);数据库名不能以system.开头 - 若 MongoDB 启用了认证,连接串中需带
authSource=admin,但selectDatabase('myapp')仍要写真实库名,authSource不等于操作库
注意 Webman 协程环境下的连接行为
Webman 支持 Swoole 协程模式,而 mongodb 扩展默认是同步阻塞的。虽然新版驱动已支持异步回调,但 mongodb/mongodb 库目前仍是同步封装,且 Client 实例非线程/协程安全。
- 不要把
Client实例存进全局变量或静态属性,协程切换后可能被污染 - 如需高并发读写,应限制单个
Client实例的并发请求数,或改用Manager+ 原生命令(MongoDB\Driver\Command)精细控制 - 连接串中加
maxPoolSize=100可缓解连接数瓶颈,但无法解决同步阻塞本质问题 - 真正需要协程友好方案时,得换用
ext-swoole+ 自研驱动,或等待mongodb/mongodb官方对Co\Channel的适配
最易被忽略的是:Webman 热重载(start.php reload)不会自动释放 Client 持有的连接资源,频繁 reload 可能导致 Too many open files;生产环境务必禁用热重载,改用进程平滑重启。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











