reference/mongodb/architecture.xml
077667aa60c2eaee4fbb704824e265d3ad6120b3
...
...
@@ -10,94 +10,60 @@
10
10
<title>Architecture Overview</title>
11
11

12
12
<para>
13
-
This section explains how all the different parts of the driver fit
14
-
together. From the different language runtimes, through the extension and
15
-
to the PHP libraries on top. This new architecture has replaced the old
16
-
<code>mongo</code> extension. We refer to the new one
17
-
as the <code>mongodb</code> extension.
13
+
This article explains how all the different components of the PHP driver fit
14
+
together, from base system libraries, through the extension, and to the PHP
15
+
libraries on top.
18
16
</para>
19
17

20
18
<para>
21
19
<mediaobject>
22
-
<alt>Architecture Diagram</alt>
20
+
<alt>
21
+
PHP Driver Architecture Diagram. The lowest level of the driver is our
22
+
system libraries: libmongoc, libbson, and libmongocrypt. The middle level
23
+
is the MongoDB PHP C extension. The upper level is PHP userland and
24
+
includes the MongoDB PHP library and higher-level packages such as
25
+
framework integrations and applications.
26
+
</alt>
23
27
<imageobject>
24
-
<imagedata fileref="en/reference/mongodb/images/driver_arch.png"/>
28
+
<imagedata fileref="en/reference/mongodb/images/driver_arch.svg" width="625" depth="450" format="SVG" />
25
29
</imageobject>
26
30
</mediaobject>
27
31
</para>
28
32

29
33
<para>
30
-
At the top of this stack sits a pure
31
-
<link xlink:href="&url.mongodb.library;">PHP library</link>, which we will
32
-
distribute as a Composer package. This library will provide an API similar
33
-
to what users have come to expect from the old mongo driver (e.g. CRUD methods,
34
-
database and collection objects, command helpers) and we expect it to be a
35
-
common dependency for most applications built with MongoDB. This library
36
-
will also implement common
37
-
<link xlink:href="&url.mongodb.specs;">specifications</link>, in the
38
-
interest of improving API consistency across all of the
39
-
<link xlink:href="&url.mongodb.drivers;">drivers</link> maintained by
40
-
MongoDB (and hopefully some community drivers, too).
34
+
At the top of this stack sits a
35
+
<link xlink:href="&url.mongodb.library;">PHP library</link>,
36
+
which is distributed as a
37
+
<link xlink:href="https://packagist.org/packages/mongodb/mongodb">Composer package</link>.
38
+
This library provides an API consistent with other MongoDB
39
+
<link xlink:href="&url.mongodb.drivers;">drivers</link>
40
+
and implements various cross-driver
41
+
<link xlink:href="&url.mongodb.specs;">specifications</link>.
42
+
While the extension can be used directly, the library has minimal overhead and
43
+
should be a common dependency for most applications built with MongoDB.
41
44
</para>
42
45

43
46
<para>
44
-
Sitting below that library we have the lower level driver.
45
-
This extension will effectively form the glue between PHP and our
46
-
system libraries (<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> and
47
-
<link xlink:href="&url.mongodb.libbson;">libbson</link>). This extension
48
-
will expose an identical public API for the most essential and
49
-
performance-sensitive functionality:
47
+
Sitting below that library is a PHP extension, which is distributed through
48
+
<link xlink:href="&url.pecl.package;mongodb">PECL</link>.
49
+
The extension forms the glue between PHP and our system libraries
50
+
(<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link>,
51
+
<link xlink:href="&url.mongodb.libbson;">libbson</link>, and
52
+
<link xlink:href="&url.mongodb.libmongocrypt;">libmongocrypt</link>).
53
+
Its public API provides only the most essential functionality:
50
54

51
55
<simplelist>
52
56
<member>Connection management</member>
53
57
<member>BSON encoding and decoding</member>
54
58
<member>Object document serialization (to support ODM libraries)</member>
55
-
<member>Executing commands and write operations</member>
56
-
<member>Handling queries and cursors</member>
59
+
<member>Executing commands, queries, and write operations</member>
60
+
<member>Handling cursors for command and query results</member>
57
61
</simplelist>
58
62
</para>
59
63

60
64
<para>
61
-
By decoupling the driver internals and a high-level API into an extension and
62
-
PHP libraries, respectively, we hope to reduce our maintainence burden and
63
-
allow for faster iteration on new features. As a welcome side effect, this
64
-
also makes it easier for anyone to contribute to the driver. Additionally,
65
-
an identical public API will make it that much easier to port an
66
-
application across PHP runtimes, whether the application uses the low-level
67
-
driver directly or a higher-level PHP library.
68
-
</para>
69
-
<para>
70
-
<link xlink:href="&url.mongodb.docs.gridfs;">GridFS</link> is a great example
71
-
of why we chose this direction.
72
-
Although we implemented GridFS in C for our old mongo driver, it is actually
73
-
quite a high-level specification. Its API is just an abstraction for
74
-
accessing two collections: files (i.e. metadata) and chunks (i.e. blocks of
75
-
data). Likewise, all of the syntactic sugar found in the old mongo driver,
76
-
such as processing uploaded files or exposing GridFS files as PHP streams,
77
-
can be implemented in pure PHP. Provided we have performant methods for
78
-
reading from and writing to GridFS' collections – and thanks to our low
79
-
level extensions, we will – shifting this API to PHP is win-win.
80
-
</para>
81
-
<para>
82
-
Earlier I mentioned that we expect the PHP library to be a common
83
-
dependency for <emphasis>most</emphasis> applications, but not
84
-
<emphasis>all</emphasis>. Some users may prefer to stick to the no-frills
85
-
API offered by the extensions, or create their own high-level abstraction
86
-
(akin to <link xlink:href="&url.mongodb.doctrine;">Doctrine MongoDB</link> for
87
-
the old mongo driver). Future libraries could include a PHP library geared
88
-
for MongoDB administration, which provides an API for various user
89
-
management and ops commands. The next major version of
90
-
<link xlink:href="&url.mongodb.doctrine-odm;">Doctrine MongoDB ODM</link> will
91
-
likely also sit directly atop the extensions.
92
-
</para>
93
-
<para>
94
-
While we will continue to maintain and support the old mongo driver and its
95
-
users for the foreseeable future, we invite everyone to use the
96
-
next-generation driver and consider it for any new projects going forward.
97
-
You can find all of the essential components across GitHub and JIRA:
98
-

99
65
<table>
100
-
<title>Driver Source Code and JIRA Locations</title>
66
+
<title>Driver Source Code and JIRA Projects</title>
101
67
<tgroup cols="3">
102
68
<thead>
103
69
<row>
...
...
@@ -113,7 +79,7 @@
113
79
<entry><link xlink:href="&url.mongodb.jira.phplib;">PHPLIB</link></entry>
114
80
</row>
115
81
<row>
116
-
<entry>PHP 5 and PHP 7 Driver (phongo)</entry>
82
+
<entry>PHP Extension</entry>
117
83
<entry><link xlink:href="&url.mongodb.github.phpc;">mongodb/mongo-php-driver</link></entry>
118
84
<entry><link xlink:href="&url.mongodb.jira.phpc;">PHPC</link></entry>
119
85
</row>
...
...
@@ -121,13 +87,6 @@
121
87
</tgroup>
122
88
</table>
123
89
</para>
124
-

125
-
<para>
126
-
The existing <link xlink:href="&url.mongodb.jira;">PHP</link> project in JIRA
127
-
will remain open for reporting bugs against the old mongo driver, but we
128
-
would ask that you use the new projects above for anything pertaining to
129
-
our next-generation drivers.
130
-
</para>
131
90
</article>
132
91

133
92
<article xml:id="mongodb.connection-handling">
...
...
@@ -153,7 +112,8 @@
153
112
options). The driver will attempt to find a previously persisted
154
113
<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> client object for
155
114
that hash. If an existing client cannot be found for the hash, a new client
156
-
will be created (and persisted for future use).
115
+
will be created and persisted for future use. This behavior can be disabled
116
+
via the <literal>"disableClientPersistence"</literal> driver option.
157
117
</para>
158
118

159
119
<para>
...
...
@@ -203,7 +163,7 @@ foreach ($managers as $manager) {
203
163

204
164
<para>
205
165
If the same worker executes the script again in a second request, the three
206
-
clients will be re-used and no new connections should be made. Depending on
166
+
clients will be re-used and no new connections will be made. Depending on
207
167
how long ago the previous request was served, the driver may need to issue
208
168
additional <literal>hello</literal> commands to update its view of the
209
169
topologies.
...
...
@@ -441,21 +401,21 @@ class AnotherClass1 implements MongoDB\BSON\Serializable {
441
401
public $foo = 42;
442
402
protected $prot = "wine";
443
403
private $fpr = "cheese";
444
-
function bsonSerialize() {
404
+
function bsonSerialize(): array {
445
405
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
446
406
}
447
407
} // => { "foo" : 42, "prot" : "wine" }
448
408

449
409
class AnotherClass2 implements MongoDB\BSON\Serializable {
450
410
public $foo = 42;
451
-
function bsonSerialize() {
411
+
function bsonSerialize(): self {
452
412
return $this;
453
413
}
454
414
} // => MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")
455
415

456
416
class AnotherClass3 implements MongoDB\BSON\Serializable {
457
417
private $elements = [ 'foo', 'bar' ];
458
-
function bsonSerialize() {
418
+
function bsonSerialize(): array {
459
419
return $this->elements;
460
420
}
461
421
} // => { "0" : "foo", "1" : "bar" }
...
...
@@ -463,11 +423,11 @@ class AnotherClass3 implements MongoDB\BSON\Serializable {
463
423
class ContainerClass implements MongoDB\BSON\Serializable {
464
424
public $things = AnotherClass4 implements MongoDB\BSON\Serializable {
465
425
private $elements = [ 0 => 'foo', 2 => 'bar' ];
466
-
function bsonSerialize() {
426
+
function bsonSerialize(): array {
467
427
return $this->elements;
468
428
}
469
429
}
470
-
function bsonSerialize() {
430
+
function bsonSerialize(): array {
471
431
return [ 'things' => $this->things ];
472
432
}
473
433
} // => { "things" : { "0" : "foo", "2" : "bar" } }
...
...
@@ -475,11 +435,11 @@ class ContainerClass implements MongoDB\BSON\Serializable {
475
435
class ContainerClass implements MongoDB\BSON\Serializable {
476
436
public $things = AnotherClass5 implements MongoDB\BSON\Serializable {
477
437
private $elements = [ 0 => 'foo', 2 => 'bar' ];
478
-
function bsonSerialize() {
438
+
function bsonSerialize(): array {
479
439
return array_values($this->elements);
480
440
}
481
441
}
482
-
function bsonSerialize() {
442
+
function bsonSerialize(): array {
483
443
return [ 'things' => $this->things ];
484
444
}
485
445
} // => { "things" : [ "foo", "bar" ] }
...
...
@@ -487,11 +447,11 @@ class ContainerClass implements MongoDB\BSON\Serializable {
487
447
class ContainerClass implements MongoDB\BSON\Serializable {
488
448
public $things = AnotherClass6 implements MongoDB\BSON\Serializable {
489
449
private $elements = [ 'foo', 'bar' ];
490
-
function bsonSerialize() {
450
+
function bsonSerialize(): array {
491
451
return (object) $this->elements;
492
452
}
493
453
}
494
-
function bsonSerialize() {
454
+
function bsonSerialize(): array {
495
455
return [ 'things' => $this->things ];
496
456
}
497
457
} // => { "things" : { "0" : "foo", "1" : "bar" } }
...
...
@@ -500,7 +460,7 @@ class UpperClass implements MongoDB\BSON\Persistable {
500
460
public $foo = 42;
501
461
protected $prot = "wine";
502
462
private $fpr = "cheese";
503
-
function bsonSerialize() {
463
+
function bsonSerialize(): array {
504
464
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
505
465
}
506
466
} // => { "foo" : 42, "prot" : "wine", "__pclass" : { "$type" : "80", "$binary" : "VXBwZXJDbGFzcw==" } }
...
...
@@ -678,6 +638,24 @@ class UpperClass implements MongoDB\BSON\Persistable {
678
638
</varlistentry>
679
639

680
640
<varlistentry>
641
+
<term><literal>"bson"</literal></term>
642
+
<listitem>
643
+
<para>
644
+
Turns a BSON array into a <classname>MongoDB\BSON\PackedArray</classname>
645
+
and a BSON document into a <classname>MongoDB\BSON\Document</classname>,
646
+
regardless of whether the BSON document has a <property>__pclass</property>
647
+
property <footnoteref linkend="mongodb.pclass"/>.
648
+
</para>
649
+
<note>
650
+
<simpara>
651
+
The <literal>bson</literal> value is only available for the three root
652
+
types, not in the field specific mappings.
653
+
</simpara>
654
+
</note>
655
+
</listitem>
656
+
</varlistentry>
657
+

658
+
<varlistentry>
681
659
<term>any other string</term>
682
660
<listitem>
683
661
<para>
...
...
@@ -722,7 +700,9 @@ class UpperClass implements MongoDB\BSON\Persistable {
722
700
<methodname>MongoDB\Driver\Cursor::setTypeMap</methodname> method on a
723
701
<classname>MongoDB\Driver\Cursor</classname> object, or the
724
702
<literal>$typeMap</literal> argument of
725
-
<function>MongoDB\BSON\toPHP</function>. Each of the three
703
+
<function>MongoDB\BSON\toPHP</function>,
704
+
<methodname>MongoDB\BSON\Document::toPHP</methodname>, and
705
+
<methodname>MongoDB\BSON\PackedArray::toPHP</methodname>. Each of the three
726
706
classes (<emphasis>root</emphasis>, <emphasis>document</emphasis>, and
727
707
<emphasis>array</emphasis>) can be individually set, in addition to the
728
708
field specific types.
...
...
@@ -784,7 +764,7 @@ class UpperClass implements MongoDB\BSON\Persistable {
784
764
The <methodname>MongoDB\BSON\Unserializable::bsonUnserialize</methodname>
785
765
method of YourClass, OurClass, TheirClass iterate over the array and set
786
766
the properties without modifications. It <emphasis>also</emphasis> sets
787
-
the <literal>$unserialized</literal> property to <literal>true</literal>:
767
+
the <literal>$unserialized</literal> property to &true;:
788
768

789
769
<programlisting role="php">
790
770
<![CDATA[
791
771