千家信息网

PHP MongoDB drive1.2版本连接该怎么处理以及PHP MongoDB drive1.3版本怎么处理

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,PHP MongoDB drive1.2版本连接该怎么处理以及PHP MongoDB drive1.3版本怎么处理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的
千家信息网最后更新 2026年10月31日PHP MongoDB drive1.2版本连接该怎么处理以及PHP MongoDB drive1.3版本怎么处理

PHP MongoDB drive1.2版本连接该怎么处理以及PHP MongoDB drive1.3版本怎么处理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

  1.3版本的PHPMongoDBdriver重写了连接处理库,和以前版本相比,在持久连接和连接池方面,都有了重大的变化。

  PHPMongoDBdrive1.2版本连接怎么处理

  1.2版本的驱动引入了连接池,在执行任何查询时,都会从连接池中请求一个连接,完成之后再归还给连接池。这里的完成是指持有该连接的变量离开了它的作用域,下面是一个示例。

  最简单的版本:

  $m=newMongoClient();//←从连接池请求连接

  $c=$m->demo->test;

  $c->insert(array('test'=>'yes'));

  >

  ←$m离开作用域,连接归还给连接池

  在函数中:

  functiondoQuery()

  {

  $m=newMongoClient();//←从连接池请求连接

  $c=$m->demo->test;

  $c->insert(array('test'=>'yes'));

  }//←$m离开作用域,连接归还给连接池

  >

  在某些情况下,系统可能会产生大量的连接,比如在ORMs/ODMs的某个复杂结构中引用连接对象,如下例子:

  for($i=0;$i<5;$i++)>

  PHPMongoDBdrive1.3版本怎么处理

  在1.3版本中,连接管理做了很大改动。每个worker进程(线程、PHP-FPM或Apacheworker)中,驱动把连接管理和Mongo*对象分离,降低驱动的复杂度。下面以单个节点的MongoDB实例来说明驱动如何处理连接。

  当一个worker进程启动,MongoDB驱动会为之初始化连接管理器管理连接,并且默认没有连接。

  在第一个请求调用newMongoClient();时,驱动创建一个新连接,并且以一个哈希值标识这个连接。这个哈希值包括以下参数:主机名、端口,进程ID和可选的replicaset名,假如是密码验证的连接,则还包括数据库名、用户名和密码的哈希值(对于密码验证的连接,我们后面再详细讨论)。调用MongoClient::getConnections()方法,可以查看连接对应的哈希值:

  $m=newMongoClient('mongodb://whisky:27017/');

  var_dump($m->getConnections()[0]['hash']);

  >

  输出:

  string(22)"whisky:27017;-;X;22835″

  输出中的"-"表示该连接不属于某个replicaset,"X"是没有用户名、数据库和密码时的占位符,22835是当前进程的进程ID。

  然后该连接会在连接管理器中注册:

  在需要连接的任何时候,包括插入、删除、更新、查找或执行命令,驱动都会向管理器请求一个合适的连接来执行。请求连接时会用到newMongoClient()的参数和当前进程的ID。每个worker进程/线程,连接管理器都会有一个连接列表,而每个PHPworker同一时刻,只会运行一个请求,因此和每个MongoDB之间只需要一个连接,不断重用,直到PHPworker终止或显式调用MongoClient::close()关闭连接。

  Replicasets

  在存在复制集的环境中,情形有点不一样。newMongoClient()的连接字符串中,需要指定多个hosts,并标示当前正在实用复制集:

  $m=newMongoClient("mongodb://whisky:13000,whisky:13001/replicaSet=seta");

  其中的replicaSet参数不能省略,否则驱动会认为你是准备连接三个不同的mongos进程。

  在实例化时,驱动会检查复制集的拓扑结构。下面例子的输出,显示在调用newMongoClient()之后,复制集中所有可见的数据节点都会在管理器中注册一个连接:

  $m=newMongoClient('mongodb://whisky:13001/replicaSet=seta');

  foreach($m->getConnections()as$c)

  {

  echo$c['hash'],"\n";

  }

  >

  输出:

  whisky:13001;seta;X;32315whisky:13000;seta;X;32315

  虽然连接字符串中没有whisky:13000节点,但是管理器中已经注册了两个连接:

  管理器不仅包含连接的哈希值和TCP/IPsocket,还保存哪个节点是主节点,以及每个节点的"距离"。下面的脚本显示了这些额外的信息;

  $m=newMongoClient('mongodb://whisky:13001/replicaSet=seta');

  foreach($m->getConnections()as$c)

  {

  echo$c['hash'],":\n",

  "-{$c['connection']['connection_type_desc']},",

  "{$c['connection']['ping_ms']}ms\n";

  }

  >

  输出:

  whisky:13001;seta;X;5776:-SECONDARY,1mswhisky:13000;seta;X;5776:-PRIMARY,0ms

  驱动把操作分为两种类型:写操作,包括插入、更新、删除和命令;读操作,包括find和findOne。默认情况下,假如没有设置读偏好参数,管理器会一直返回主节点的连接。读偏好参数可以通过setSlaveOkay()设置,也可以在连接字符串中设置:

  $m=newMongoClient("mongodb://whisky:13000,whisky:13001/replicaSet=seta&readPreference=secondaryPreferred");

  加上这些参数后,连接字符串变得特别长,因此PHP驱动允许将选项放在数组中,作为第二个参数传入:

  $options=array(

  'replicaSet'=>'seta',

  'readPreference'=>'secondaryPreferred',

  );

  $m=newMongoClient("mongodb://whisky:13000,whisky:13001/",$options);

  对于每个操作,驱动向管理器请求获取一个合适的连接。对于写操作,会一直返回主节点的连接;对于读操作,假如辅助节点可用且"距离"不远的话,则会返回该辅助节点的连接。

  验证的连接

  假如MongoDB启用验证功能,那么连接的哈希值会包含验证相关的哈希值。这样不同脚本,使用不同的用户名、密码连接同一个MongoDB上的不同的数据库时,能够相互区分,而不会误用连接。下面示例使用admin用户名连接admin数据库,然后观察hash值的变化:

  $m=newMongoClient('mongodb://admin:admin@whisky:27017/admin');

  var_dump($m->getConnections()[0]['hash']);

  >

  输出:

  string(64)"whisky:27017;-;admin/admin/bda5cc70cd5c23f7ffa1fda978ecbD30;8697″

  以前示例中的"X"部分已经替换为一个包含数据库名admin、用户名admin和哈希值bda5cc70cd5c23f7ffa1fda978ecbd30,该哈希值是根据用户名、数据库名和密码哈希值计算得来。

  为了验证能够正确工作,需要在连接字符串中包含数据库名,否则会默认为admin。

  在建立连接后要使用数据库,需要先选择该数据库,如:

  $collection=$m->demoDb->collection;$collection->findOne();

  假如选择的数据库是连接字符串中指定的数据库,或者连接字符串中的数据库是admin,那么一切都会正常运行。否则,驱动会创建一个新的连接,从而防止验证被绕过,如下所示:

  $m=newMongoClient('mongodb://user:user@whisky:27017/test');

  $db=$m->test2;

  $collection=$db->collection;

  var_dump($collection->findOne());

  >

  输出:

  Fatalerror:Uncaughtexception'MongoCursorException'withmessage'whisky:27017:unauthorizeddb:test2ns:test2.collectionlocktype:0client:127.0.0.1′in…/mongo-connect-5.php.txt:6

  因为我们的连接并没有执行test2数据库的授权验证,因而失败。假如我们执行验证,就会正常运行:

  $m=newMongoClient('mongodb://user:user@whisky:27017/test');

  $db=$m->test2;

  $db->authenticate('user2','user2');

  $collection=$db->collection;

  $collection->findOne();

  foreach($m->getConnections()as$c)

  {

  echo$c['hash'],"\n";

  }

  >

  输出:

  whisky:27017;-;test/user/602b672e2fdcda7b58a042aeeb034376;26983whisky:27017;-;test2/user2/984b6b4fd6c33f49b73f026f8b47c0de;26983

  现在管理器中有两个已验证的连接:

  顺便提一句,假如你打开了E_DEPRECATED级别的错误提示,则会看到:

  Deprecated:FunctionMongoDB::authenticate()isdeprecatedin…/mongo-connect-6.php.txtonline5

  驱动建议通过创建两个MongoClient对象完成该类任务:

  $mTest1=newMongoClient('mongodb://user:user@whisky:27017/test',array('connect'=>false));

  $mTest2=newMongoClient('mongodb://user2:user2@whisky:27017/test2',array('connect'=>false));

  $mTest1->test->test->findOne();

  $mTest2->test2->test->findOne();

  foreach($mTest2->getConnections()as$c)

  {

  echo$c['hash'],"\n";

  }

  >

  单个MongoDB服务器能支持的并发连接相当有限,假如使用PHP-FPM的话,每个worker进程有自己独立的连接池,那么很容易达到连接数的上限。因此,在生产环境中,不管有没有使用复制集,都要部署mongos,然后PHP-FPM连接mongos,这样可以减少mongod的连接数,并且PHP-FPM和mongos之间可以使用短连接(即每个请求结束时都显式调用close函数关闭MongoDB连接)。

关于PHP MongoDB drive1.2版本连接该怎么处理以及PHP MongoDB drive1.3版本怎么处理问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

数据 数据库 管理 驱动 版本 节点 哈希 验证 进程 输出 处理 参数 字符 字符串 密码 用户 用户名 不同 两个 作用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技股互联网 鸠鸠互联网科技 互联网科技与金融科技 九亚互联网科技 致聘互联网科技 唐信互联网科技 大连 济南和联互联网科技有限公司 银川新华互联网科技学校地址 深圳市运趣互联网科技有限公司 农村开互联网科技讲堂 互联网科技博主是什么意思 北京华百购互联网科技有限公司 承德科技产业互联网发展 科技互联网大厂 浙江互联网科技研学营 互联网科技革命什么开始 上海科技产业互联网平台 从那以后互联网科技有限公司 互联网风格科技公司名称 瑞安市蟠桃会互联网科技有限公司 中资互联网科技 极限挑战互联网科技 亿人帮互联网科技 中国的互联网科技企业的崛起 深圳育鹏互联网科技有限公司招聘 互联网金融科技展 工业互联网展湾科技股份有限公司 中天科技中国工业互联网 安徽零酒互联网科技有限公司 承德科技产业互联网平台
0