您尚未登录,请登录后浏览更多内容! 登录 | 立即注册

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 16998|回复: 0
打印 上一主题 下一主题

[php学习资料] 升级PHP7操作MongoDB

[复制链接]
跳转到指定楼层
楼主
发表于 2019-3-19 14:24:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用 PHP+MongoDB 的用户很多,因为 MongoDB 对非结构化数据的存储很方便。在 PHP5 及以前,官方提供了两个扩展,Mongo 和 MongoDB,其中 Mongo 是对以 MongoClient 等几个核心类为基础的类群进行操作,封装得很方便,所以基本上都会选择 Mongo 扩展。
详情请见官方手册:http://php.net/manual/zh/book...
但是随着 PHP5 升级到 PHP7,官方不再支持 Mongo 扩展,只支持 MongoDB,而 PHP7 的性能提升巨大,让人无法割舍,所以怎么把 Mongo 替换成 MongoDB 成为了一个亟待解决的问题。MongoDB 引入了命名空间,但是功能封装非常差,如果非要用原生的扩展,几乎意味着写原生的 Mongo 语句。这种想法很违背 ORM 简化 DB IO 操作带来的语法问题而专注逻辑优化的思路。
详情也可参见官方手册:http://php.net/manual/zh/set....
在这种情况之下,MongoDB 官方忍不住了,为了方便使用,增加市场占有率,推出了基于MongoDB 扩展的库:https://github.com/mongodb/mo...
该库的详细文档见:https://docs.mongodb.com/php-...
MongoDB 驱动
如果使用原驱动的话,大致语法如下:
  1. <?php
    5 h3 b/ C! b" Y' A

  2. " K3 P8 J  ]: p) q- C( o. V
  3. use MongoDB\Driver\Manager;' A6 n+ k% I0 u/ r3 h( s
  4. use MongoDB\Driver\BulkWrite;
    2 h; h/ L" j% H$ K+ ~" s
  5. use MongoDB\Driver\WriteConcern;
    7 c/ F. L9 Q$ a& G! ?2 r
  6. use MongoDB\Driver\Query;
    8 G! j2 s- `* C. b  p/ Z; r
  7. use MongoDB\Driver\Command;$ o* h/ Y5 @! d' C- B

  8. ; X2 U- L$ S: \% w) N' U! P  K
  9. class MongoDb {; T& M; U- Y" @/ J) y3 e" r2 e
  10. 3 z5 y& j! I; @7 E% E
  11.     protected $mongodb;
    6 p4 D. E$ R% p
  12.     protected $database;# }7 O2 |6 `: a
  13.     protected $collection;6 [% C  v' ^; l5 P" v
  14.     protected $bulk;
    4 \& v% l( H$ @1 v
  15.     protected $writeConcern;, N6 ^& y. D( V0 v5 G) S: K
  16.     protected $defaultConfig( p! V0 h+ @8 m% A
  17.         = [+ W3 j3 \6 C: E5 Z7 G8 A
  18.             'hostname' => 'localhost',- x! D; j4 `& `
  19.             'port' => '27017',- |: H: Z) U( B
  20.             'username' => '',
    ! Y# u6 v: s' F: i4 C6 c- }
  21.             'password' => '',
    ! d) d4 O/ @' u" }1 L+ h* b8 A
  22.             'database' => 'test'0 E6 {/ [: S# |, }& Q
  23.         ];
    + n/ y! l( |3 y5 a# `% j

  24. 8 T5 V9 C7 y. [1 p! a' @) `$ I
  25.     public function __construct($config) {+ b( u* l/ _3 j! g, N
  26.         $config = array_merge($this->defaultConfig, $config);9 m: z: w4 @9 P+ c# M
  27.         $mongoServer = "mongodb://";1 b; e  m$ m9 f; n1 v3 I4 K
  28.         if ($config['username']) {1 K. U  |# s, B% S
  29.             $mongoServer .= $config['username'] . ':' . $config['password'] . '@';2 N$ r1 u2 `* i. `/ G
  30.         }
    " d5 u) }- }9 u- [5 K; E$ n
  31.         $mongoServer .= $config['hostname'];8 w/ X5 h, _( r* H; g4 a$ I; ^/ {
  32.         if ($config['port']) {
    / ]+ ]7 @- c# k' k7 N! Q8 x
  33.             $mongoServer .= ':' . $config['port'];( l$ ~4 O* {/ g
  34.         }
    : w/ b' w; f8 W% D: M
  35.         $mongoServer .= '/' . $config['database'];
    : a. M% g' q+ G. I

  36. 0 _& c1 l: a' y& X# {
  37.         $this->mongodb = new Manager($mongoServer);
    + s4 A# m6 P; o5 [4 `9 p
  38.         $this->database = $config['database'];
    / I5 l( S, e2 {' P
  39.         $this->collection = $config['collection'];5 X4 O7 S3 m; C  D2 ~
  40.         $this->bulk = new BulkWrite();
    * y9 x3 A, U3 Y+ T2 _9 z2 h1 @% P
  41.         $this->writeConcern = new WriteConcern(WriteConcern::MAJORITY, 100);6 n; x5 y' q* d9 }2 l% I+ |
  42.     }
    2 b% h+ }$ p: T# N  d  W

  43. 8 T! `1 d' l1 p
  44.     public function query($where = [], $option = []) {
    4 z# l' I2 J. v. Z
  45.         $query = new Query($where, $option);  Q" p1 z# u0 u" u( h6 _/ o
  46.         $result = $this->mongodb->executeQuery("$this->database.$this->collection", $query);5 n1 h/ D: f7 ?2 N
  47. " T/ {0 q! `5 @# M. w1 M1 A
  48.         return json_encode($result);
    * T* a. d7 C( m; i# k
  49.     }
    ; G! ^* z" w$ f+ O7 q

  50. 5 Q6 B3 N; E. M" L7 B* L
  51.     public function count($where = []) {$ ^8 F4 r, \4 g8 q1 \' l
  52.         $command = new Command(['count' => $this->collection, 'query' => $where]);
    9 o! Y% r) L/ r* I  Q1 N6 F
  53.         $result = $this->mongodb->executeCommand($this->database, $command);8 r% v4 F# T1 Q2 R
  54.         $res = $result->toArray();. f: ^$ Z4 t1 p4 \" s8 G3 k
  55.         $count = 0;, f, Z9 _# W( d1 N. m
  56.         if ($res) {5 p1 U( L6 L8 `
  57.             $count = $res[0]->n;8 z' F  p( Q5 @5 O- \3 V
  58.         }
    7 M7 o9 q2 W; B" B
  59. * U5 x2 k- g8 G* v; p
  60.         return $count;
    - S2 \: N3 R2 T9 }
  61.     }% i# ^) _- b5 k

  62. 3 ^7 G* t0 a- S0 B
  63.     public function update($where = [], $update = [], $upsert = false) {
    & B" h$ b) Y2 h: o8 Y4 L) S2 Q
  64.         $this->bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
    4 X4 b$ a* \" W" Q6 d6 d
  65.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    $ F$ i- N% B. g( j
  66. : B7 w; ~3 O" ]" _0 G& y5 }
  67.         return $result->getModifiedCount();
    6 D  n$ U/ B. E& M2 g! I+ H9 Z
  68.     }4 _0 w( R% O9 }% J# r

  69. ) W$ C/ ~) J) K3 v6 m1 B
  70.     public function insert($data = []) {! i! l: D7 S6 S
  71.         $this->bulk->insert($data);) v, h2 T5 ~+ N( |# A% [
  72.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);" ^3 c0 H- q) M! U) K: \& [

  73. ) m& @; J- C/ i: S  J- u+ t
  74.         return $result->getInsertedCount();) u" C2 }2 {/ ?$ {6 Z) F1 }
  75.     }
    " c, v% t) \/ U( @5 b
  76.   |% V8 Y4 O( i9 w# ^! n, X, H
  77.     public function delete($where = [], $limit = 1) {
    , r! F+ d9 D# F6 y( _- J2 W# m
  78.         $this->bulk->delete($where, ['limit' => $limit]);, L2 {1 N8 W7 n* p9 g* M
  79.         $result = $this->mongodb->executeBulkWrite("$this->database.$this->collection", $this->bulk, $this->writeConcern);
    # O! n7 ^. r5 {6 r, O( I1 \4 J

  80. , r* w* w/ H7 n# B. j7 V, a
  81.         return $result->getDeletedCount();
    1 W1 a' |# Y% ?5 y8 w/ B
  82.     }
    2 t9 `8 G2 `, u6 t4 \
  83. }
复制代码
这样的语法和之前差异太大,改动不方便,换 PHP MongoDB
MongoDB 库1.连接
  • 5 q$ O- G0 R6 ]6 O: e
  1. new MongoClient();
复制代码
  • ! V; T5 S: k7 X0 u: W8 ~
  1. new MongoDB\Client();
复制代码
2.新增
  • 2 L- d' Z  E* ~% T& L) P; S& I
  1. $collention->insert($array, $options);
复制代码

  • . ]; B( h5 z6 Q: m+ M
  1. $resultOne = $collention->insertOne($array, $options);//单
    : ]4 a5 Q. x& w4 R( C
  2. $lastId = $resultOne->getInsertedId();: ?6 B" O$ t( N1 ]
  3. $resultMany = $collention->insertMany($array, $options);//多
    ' k' y' t6 \, X4 F# Q) k- q
  4. $count = $resultMany->getInsertedCount();
复制代码
3.修改
  • & U- M( B- q/ F! m! z3 m6 Y
  1. $collention->update($condition, [+ ^2 ]; I  ?/ a  J. f
  2.     '$set' => $values. H; E$ B& a, p& I
  3. ,[
    : {( i, [' h; D" u& ~
  4.     'multiple' => true//多条,单条false% G# S) R8 h( d7 c4 R" ]* A/ P0 I
  5. ]);
复制代码
  • : T$ i& D* ]6 T% F3 c7 t, B- k" N5 x
  1. $collection->updateOne(
    2 x9 o# W3 W/ h- F7 C* c
  2.     ['state' => 'ny'],
    * x- P8 k0 L  s% s8 x
  3.     ['$set' => ['country' => 'us']]
    0 K1 S  i0 ~# s3 w/ w1 R  D& V; C6 r
  4. );
    ! ]' R& p, Z$ @8 e
  5. $updateResult = $collection->updateMany(
    ( T7 V" B; ]' M5 E/ |  j8 C
  6.     ['state' => 'ny'],
    # ~* e# ]/ w$ \. e$ U% y6 ]
  7.     ['$set' => ['country' => 'us']]3 p2 i: U. O6 H5 `# z
  8. );; A& \& {* V4 P: A
  9. $count = $updateResult->getModifiedCount();
复制代码
4.查询

  • 4 P9 Z% z6 z$ K" O* Y% v
  1. $cursor = $collection->find($condition, [
    . _( h! b. x4 G
  2.     'name' => true//指定字段8 @1 z% R8 v" ^7 s' T6 b# b
  3. ]);2 z2 T, F' N% i3 N/ ~, N; e
  4. $cursor->skip(5);- ?2 R: Q9 s8 D! C. D: T
  5. $cursor->limit(5);
    6 R* _% @1 F- L1 P1 @- b2 `
  6. $cursor->sort([7 ~9 Y- o0 P. g' w) j
  7.     'time' => -1/ ^6 v) I( c' P0 e1 Q6 z
  8. ]);
复制代码
  • ) ]# I  c* f6 w# K
  1. $cursor = $collection->find($condition, [8 w! ]; _+ P  ^0 `
  2.     'skip' => 5,, ^) N  Q7 ]1 L+ a9 s
  3.     'limit' => 5,
    3 n, l4 H/ `0 V9 t4 y) i2 d) H1 `
  4.     'sort' => [
    1 k0 j1 X; u( o4 A  h
  5.         'time' => -1& A2 W2 u( e' d" A
  6.     ],//排序
    % R7 L7 l. _7 r& O) }+ N- I
  7.     'projection' => [, r5 }2 J$ _3 W0 ~! @6 P
  8.         'name' => 1//指定字段
    % K1 q( N3 l2 x) A5 n0 S
  9.     ]
    8 o" D1 y! @  _2 @* c6 J
  10. ]);
复制代码
5.删除
  • % Y* J# U4 N5 ?* z; Y8 _! l
  1. $collention->remove($condition, [" p0 C3 w% q( Q3 }7 R" k/ T
  2.     'justOne' => false//删单条! b3 L' i6 S2 e2 ?7 U
  3. ]);5 q7 K3 R* o8 p! d
  4. $collention->remove([]);//删所有
复制代码

  • % o4 L: [; q/ ^
  1. $result = $collention->deleteOne($condition, $options);- x9 H2 |. u/ |. ~, v0 A9 J$ d9 w
  2. $collention->deleteMany($condition, $options);+ ~; Y1 P: n1 D3 @0 c, g9 |

  3. 5 u+ O: e, z* e( [& I0 J$ n8 O
  4. $result->getDeletedCount();
复制代码
补充
有些人可能习惯以类似 MySQL 的自增 ID 来处理数据,以前可能使用 findAndModify() 方法来查询并修改:
  1. $collention->findAndModify([
    " G$ v, Z7 [6 J$ i
  2.     '_id' => $tableName//我在自增表中用其它的表名作主键! g- j) n% b3 N/ b
  3. ], [
    7 f. u' X9 `3 m2 V2 ?9 `
  4.     '$inc' => ['id' => 1]//自增
    : w: ]- L4 S9 ~, ^+ n4 s% B
  5. ], [6 l7 F. ?5 O8 U+ @" |. _2 X
  6.     '_id' => 08 A, M, Z3 P3 l% Z5 @
  7. ], [$ ^' B8 S- I! z' n  V( w' P
  8.     'new' => 1//返回修改后的结果,默认是修改前的
    2 w* x/ a( G& V% T, w7 {
  9. ]);
复制代码
现在使用 MongoDB 库的话需要修改为:
  1. $collention->findOneAndUpdate([" a/ E5 h6 r. u& s
  2.     '_id' => $tableName
    0 |# r1 L5 w% r9 @' M( }' e3 |9 U# e
  3. ], [
    ! z" b, j1 o! N7 S& R9 b
  4.     '$inc' => ['id' => 1]+ a( y# G/ V0 P) \- k% Z" O5 {  z
  5. ], [
    0 J, s" c  I3 g! A1 c* P/ U
  6.     'projection' => ['id' => 1],
    $ C) E" X3 A7 V$ v+ k+ M
  7.     'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
    / ^% t/ X( c/ g+ a; H/ H/ B& I
  8. ]);
复制代码
, K" }  Y  ?0 W& K, [1 s, t  h$ t

& N( {- f+ z3 W
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2026-8-4 08:12 , Processed in 0.072987 second(s), 19 queries .

Copyright © 2001-2026 Powered by cncml! X3.2. Theme By cncml!