php-doc-en/reference/mongodb/architecture.xml
George Peter Banyard b73df01f31 English typo
Provided by sergey

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@347472 c90b9560-bf6c-de11-be94-00142212c4b1
2019-05-22 21:23:10 +00:00

942 lines
33 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<book xml:id="mongodb.architecture" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<titleabbrev>Driver Architecture and Internals</titleabbrev>
<title>Explains the driver architecture, and special features</title>
<article xml:id="mongodb.overview">
<titleabbrev>Architecture</titleabbrev>
<title>Architecture Overview</title>
<para>
This section explains how all the different parts of the driver fit
together. From the different language runtimes, through the extension and
to the PHP libraries on top. This new architecture has replaced the old
<link linkend="book.mongo">mongo</link> extension. We refer to the new one
as the <emphasis>mongodb</emphasis> extension.
</para>
<para>
<mediaobject>
<alt>Architecture Diagram</alt>
<imageobject>
<imagedata fileref="en/reference/mongodb/images/driver_arch.png"/>
</imageobject>
</mediaobject>
</para>
<para>
At the top of this stack sits a pure
<link xlink:href="&url.mongodb.library;">PHP library</link>, which we will
distribute as a Composer package. This library will provide an API similar
to what users have come to expect from the old mongo driver (e.g. CRUD methods,
database and collection objects, command helpers) and we expect it to be a
common dependency for most applications built with MongoDB. This library
will also implement common
<link xlink:href="&url.mongodb.specs;">specifications</link>, in the
interest of improving API consistency across all of the
<link xlink:href="&url.mongodb.drivers;">drivers</link> maintained by
MongoDB (and hopefully some community drivers, too).
</para>
<para>
Sitting below that library we have the lower level driver.
This extension will effectively form the glue between PHP and our
system libraries (<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> and
<link xlink:href="&url.mongodb.libbson;">libbson</link>). This extension
will expose an identical public API for the most essential and
performance-sensitive functionality:
<simplelist>
<member>Connection management</member>
<member>BSON encoding and decoding</member>
<member>Object document serialization (to support ODM libraries)</member>
<member>Executing commands and write operations</member>
<member>Handling queries and cursors</member>
</simplelist>
</para>
<para>
By decoupling the driver internals and a high-level API into an extension and
PHP libraries, respectively, we hope to reduce our maintainence burden and
allow for faster iteration on new features. As a welcome side effect, this
also makes it easier for anyone to contribute to the driver. Additionally,
an identical public API will make it that much easier to port an
application across PHP runtimes, whether the application uses the low-level
driver directly or a higher-level PHP library.
</para>
<para>
<link xlink:href="&url.mongodb.docs.gridfs;">GridFS</link> is a great example
of why we chose this direction.
Although we implemented GridFS in C for our old mongo driver, it is actually
quite a high-level specification. Its API is just an abstraction for
accessing two collections: files (i.e. metadata) and chunks (i.e. blocks of
data). Likewise, all of the syntactic sugar found in the old mongo driver,
such as processing uploaded files or exposing GridFS files as PHP streams,
can be implemented in pure PHP. Provided we have performant methods for
reading from and writing to GridFS' collections and thanks to our low
level extensions, we will shifting this API to PHP is win-win.
</para>
<para>
Earlier I mentioned that we expect the PHP library to be a common
dependency for <emphasis>most</emphasis> applications, but not
<emphasis>all</emphasis>. Some users may prefer to stick to the no-frills
API offered by the extensions, or create their own high-level abstraction
(akin to <link xlink:href="&url.mongodb.doctrine;">Doctrine MongoDB</link> for
the old mongo driver). Future libraries could include a PHP library geared
for MongoDB administration, which provides an API for various user
management and ops commands. The next major version of
<link xlink:href="&url.mongodb.doctrine-odm;">Doctrine MongoDB ODM</link> will
likely also sit directly atop the extensions.
</para>
<para>
While we will continue to maintain and support the old mongo driver and its
users for the foreseeable future, we invite everyone to use the
next-generation driver and consider it for any new projects going forward.
You can find all of the essential components across GitHub and JIRA:
<table>
<title>Driver Source Code and JIRA Locations</title>
<tgroup cols="3">
<thead>
<row>
<entry>Project</entry>
<entry>GitHub</entry>
<entry>JIRA</entry>
</row>
</thead>
<tbody>
<row>
<entry>PHP Library</entry>
<entry><link xlink:href="&url.mongodb.github.phplib;">mongodb/mongo-php-library</link></entry>
<entry><link xlink:href="&url.mongodb.jira.phplib;">PHPLIB</link></entry>
</row>
<row>
<entry>PHP 5 and PHP 7 Driver (phongo)</entry>
<entry><link xlink:href="&url.mongodb.github.phpc;">mongodb/mongo-php-driver</link></entry>
<entry><link xlink:href="&url.mongodb.jira.phpc;">PHPC</link></entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
The existing <link xlink:href="&url.mongodb.jira;">PHP</link> project in JIRA
will remain open for reporting bugs against the old mongo driver, but we
would ask that you use the new projects above for anything pertaining to
our next-generation drivers.
</para>
</article>
<article xml:id="mongodb.connection-handling">
<titleabbrev>Connections</titleabbrev>
<title>Connection handling and persistence</title>
&mongodb.note.forking;
<section>
<title>Connection and topology persistence (PHP version since 1.2.0)</title>
<para>
All versions of the driver since 1.2.0 persist the
<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> client object in
the PHP worker process, which allows it to re-use database connections,
authentication states, <emphasis>and</emphasis> topology information across
multiple requests.
</para>
<para>
When <methodname>MongoDB\Driver\Manager::__construct</methodname> is
invoked, a hash is created from its arguments (i.e. URI string and array
options). The driver will attempt to find a previously persisted
<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> client object for
that hash. If an existing client cannot be found for the hash, a new client
will be created (and persisted for future use).
</para>
<para>
Each client contains its own database connections and a view of the server
topology (e.g. standalone, replica set, shard cluster). By persisting the
client between PHP requests, the driver is able to re-use established
database connections and remove the need for
<link xlink:href="&url.mongodb.sdam;">discovering the server topology</link>
on each request.
</para>
<para>
Consider the following example:
</para>
<programlisting role="php">
<![CDATA[
<?php
$managers = [
new MongoDB\Driver\Manager('mongodb://127.0.0.1'),
new MongoDB\Driver\Manager('mongodb://127.0.0.1'),
new MongoDB\Driver\Manager('mongodb://127.0.0.1:27017'),
new MongoDB\Driver\Manager('mongodb://rs1.example.com,rs2.example.com/', ['replicaSet' => 'myReplicaSet']),
];
foreach ($managers as $manager) {
$manager->executeCommand('test', new MongoDB\Driver\Command(['ping' => 1]));
}
?>
]]>
</programlisting>
<para>
The first two Manager objects will share the same
<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> client since
their constructor arguments are identical. The third and fourth objects will
each use their own client. In total, three clients will be created and the
PHP worker executing this script will open two connections to
<literal>127.0.0.1</literal> and one connection to each of
<literal>rs1.example.com</literal> and <literal>rs2.example.com</literal>.
If the driver discovers additional members of the replica set after issuing
<literal>isMaster</literal> commands, it will open additional connections to
those servers as well.
</para>
<para>
If the same worker executes the script again in a second request, the three
clients will be re-used and no new connections should be made. Depending on
how long ago the previous request was served, the driver may need to issue
additional <literal>isMaster</literal> commands to update its view of the
topologies.
</para>
</section>
<section>
<title>Socket persistence (PHP versions before 1.2.0)</title>
<para>
Versions of the PHP driver before 1.2.0 utilize PHP&apos;s Streams API for
database connections, using an API within
<link xlink:href="&url.mongodb.libmongoc;">libmongoc</link> to designate
custom handlers for socket communication; however, a new libmongoc client is
created for each <classname>MongoDB\Driver\Manager</classname>. As a result,
the driver persists individual database connections but not authentication
state or topology information. This means that the driver needs to issue
commands at the start of each request to authenticate and
<link xlink:href="&url.mongodb.sdam;">discover the server topology</link>.
</para>
<para>
Database connections are persisted by a hash derived from the server&apos;s
host, port, and the URI string used to construct the
<classname>MongoDB\Driver\Manager</classname>. The constructor&apos;s array
options are not included in this hash.
</para>
<note>
<simpara>
Versions of the driver &gt;= 1.1.8 and &lt; 1.2.0 do not persist sockets
for SSL connections. See
<link xlink:href="&url.mongodb.jira.phpc;-720">PHPC-720</link> for
additional information.
</simpara>
</note>
<para>
Despite its shortcomings with persisting SSL connections when and topology
information, this version of the driver supports all
<link linkend="context.ssl">SSL context options</link> since it uses
PHP&apos;s Streams API.
</para>
</section>
</article>
<article xml:id="mongodb.persistence">
<titleabbrev>Persisting Data</titleabbrev>
<title>Serialization and deserialization of PHP variables into MongoDB</title>
<para>
This document discusses the methods how compound structures (documents,
arrays, objects) are persisted through the drivers. And how they are brought
back into PHP land.
</para>
<section xml:id="mongodb.persistence.serialization">
<title>Serialization to BSON</title>
<section>
<title>Arrays</title>
<para>
If an array is a <emphasis>packed array</emphasis> — i.e. the keys start
at 0 and are sequential without gaps: <emphasis>BSON array</emphasis>.
</para>
<para>
If the array is not packed — i.e. having associative (string) keys, the
keys don't start at 0, or when there are gaps:: <emphasis>BSON
object</emphasis>
</para>
<para>
A top-level (root) document, <emphasis>always</emphasis> serializes as a
BSON document.
</para>
<section>
<title>Examples</title>
<para>
These serialize as a BSON array:
</para>
<programlisting role="text">
<![CDATA[
[ 8, 5, 2, 3 ] => [ 8, 5, 2, 3 ]
[ 0 => 4, 1 => 9 ] => [ 4, 9 ]
]]>
</programlisting>
<para>
These serialize as a BSON document:
</para>
<programlisting role="text">
<![CDATA[
[ 0 => 1, 2 => 8, 3 => 12 ] => { "0" : 1, "2" : 8, "3" : 12 }
[ "foo" => 42 ] => { "foo" : 42 }
[ 1 => 9, 0 => 10 ] => { "1" : 9, "0" : 10 }
]]>
</programlisting>
<para>
Note that the five examples are <emphasis>extracts</emphasis> of a full
document, and represent only <emphasis>one</emphasis> value inside a
document.
</para>
</section>
</section>
<section>
<title>Objects</title>
<para>
If an object is of the <classname>stdClass</classname> class, serialize
as a <emphasis>BSON document</emphasis>.
</para>
<para>
If an object is a supported class that implements
<interfacename>MongoDB\BSON\Type</interfacename>, then use the BSON
serialization logic for that specific type.
<interfacename>MongoDB\BSON\Type</interfacename> instances (excluding
<interfacename>MongoDB\BSON\Serializable</interfacename> may only be
serialized as a document field value. Attempting to serialize such an
object as a root document will throw a
<classname>MongoDB\Driver\Exception\UnexpectedValueException</classname>
</para>
<para>
If an object is of an unknown class implementing the
<interfacename>MongoDB\BSON\Type</interfacename> interface, then throw a
<classname>MongoDB\Driver\Exception\UnexpectedValueException</classname>
</para>
<para>
If an object is of any other class, without implementing any special
interface, serialize as a <emphasis>BSON document</emphasis>. Keep only
<emphasis>public</emphasis> properties, and ignore
<emphasis>protected</emphasis> and <emphasis>private</emphasis>
properties.
</para>
<para>
If an object is of a class that implements the
<interfacename>MongoDB\BSON\Serializable</interfacename> interface, call
<methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname> and use
the returned array or <classname>stdClass</classname> to serialize as a
BSON document or array. The BSON type will be determined by the following:
</para>
<para>
<orderedlist>
<listitem>
<para>Root documents must be serialized as a BSON
document.
</para>
</listitem>
<listitem>
<para>
<interfacename>MongoDB\BSON\Persistable</interfacename> objects must be
serialized as a BSON document.
</para>
</listitem>
<listitem>
<para>
If <methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname>
returns a packed array, serialize as a BSON array.
</para>
</listitem>
<listitem>
<para>
If <methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname>
returns a non-packed array or <classname>stdClass</classname>,
serialize as a BSON document.
</para>
</listitem>
<listitem>
<para>
If <methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname>
did not return an array or <classname>stdClass</classname>, throw an
<classname>MongoDB\Driver\Exception\UnexpectedValueException</classname>
exception.
</para>
</listitem>
</orderedlist>
</para>
<para>
If an object is of a class that implements the
<interfacename>MongoDB\BSON\Persistable</interfacename> interface (which
implies <interfacename>MongoDB\BSON\Serializable</interfacename>), obtain
the properties in a similar way as in the previous paragraphs, but
<emphasis>also</emphasis> add an additional property
<property>__pclass</property> as a Binary value, with subtype
<literal>0x80</literal> and data bearing the fully qualified class name
of the object that is being serialized.
</para>
<para>
The <property>__pclass</property> property is added to the array or
object returned by
<methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname>, which
means it will overwrite any <property>__pclass</property> key/property in
the <methodname>MongoDB\BSON\Serializable::bsonSerialize</methodname>
return value. If you want to avoid this behaviour and set your own
<property>__pclass</property> value, you must <emphasis>not</emphasis>
implement <interfacename>MongoDB\BSON\Persistable</interfacename> and
should instead implement
<interfacename>MongoDB\BSON\Serializable</interfacename> directly.
</para>
<section>
<title>Examples</title>
<programlisting role="php">
<![CDATA[
<?php
class stdClass {
public $foo = 42;
} // => { "foo" : 42 }
class MyClass {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
} // => { "foo" : 42 }
class AnotherClass1 implements MongoDB\BSON\Serializable {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
function bsonSerialize() {
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
}
} // => { "foo" : 42, "prot" : "wine" }
class AnotherClass2 implements MongoDB\BSON\Serializable {
public $foo = 42;
function bsonSerialize() {
return $this;
}
} // => MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")
class AnotherClass3 implements MongoDB\BSON\Serializable {
private $elements = [ 'foo', 'bar' ];
function bsonSerialize() {
return $this->elements;
}
} // => { "0" : "foo", "1" : "bar" }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass4 implements MongoDB\BSON\Serializable {
private $elements = [ 0 => 'foo', 2 => 'bar' ];
function bsonSerialize() {
return $this->elements;
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : { "0" : "foo", "2" : "bar" } }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass5 implements MongoDB\BSON\Serializable {
private $elements = [ 0 => 'foo', 2 => 'bar' ];
function bsonSerialize() {
return array_values($this->elements);
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : [ "foo", "bar" ] }
class ContainerClass implements MongoDB\BSON\Serializable {
public $things = AnotherClass6 implements MongoDB\BSON\Serializable {
private $elements = [ 'foo', 'bar' ];
function bsonSerialize() {
return (object) $this->elements;
}
}
function bsonSerialize() {
return [ 'things' => $this->things ];
}
} // => { "things" : { "0" : "foo", "1" : "bar" } }
class UpperClass implements MongoDB\BSON\Persistable {
public $foo = 42;
protected $prot = "wine";
private $fpr = "cheese";
function bsonSerialize() {
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
}
} // => { "foo" : 42, "prot" : "wine", "__pclass" : { "$type" : "80", "$binary" : "VXBwZXJDbGFzcw==" } }
]]>
</programlisting>
</section>
</section>
</section>
<section xml:id="mongodb.persistence.deserialization">
<title>Deserialization from BSON</title>
<para>
The legacy <link linkend="book.mongo">mongo</link> extension deserialized
both BSON documents and arrays as PHP arrays. While PHP arrays are
convenient to work with, this behavior was problematic because different
BSON types could deserialize to the same PHP value (e.g.
<literal>{"0": "foo"}</literal> and <literal>["foo"]</literal>) and make it
impossible to infer the original BSON type. By default, the current driver
addresses this concern by ensuring that BSON arrays and documents are
converted to PHP arrays and objects, respectively.
</para>
<para>
For compound types, there are three data types:
</para>
<para>
<variablelist>
<varlistentry>
<term>root</term>
<listitem>
<para>
refers to the top-level BSON document <emphasis>only</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>document</term>
<listitem>
<para>
refers to embedded BSON documents <emphasis>only</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>array</term>
<listitem>
<para>
refers to a BSON array
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Besides the three collective types, it is also possible to configure
specific fields in your document to map to the data types mentioned below.
As an example, the following type map allows you to
map each embedded document within an <literal>"addresses"</literal> array to
an <classname>Address</classname> class <emphasis>and</emphasis> each
<literal>"city"</literal> field within those embedded address documents to
a <classname>City</classname> class:
<programlisting role="text">
<![CDATA[
[
'fieldPaths' => [
'addresses.$' => 'MyProject\Address',
'addresses.$.city' => 'MyProject\City',
],
]
]]>
</programlisting>
</para>
<para>
Each of those three data types, as well as the field specific mappings,
can be mapped against different PHP types. The possible mapping values
are:
</para>
<para>
<variablelist>
<varlistentry>
<term><emphasis>not set</emphasis> or <type>NULL</type> (default)</term>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
A BSON array will be deserialized as a PHP <type>array</type>.
</para>
</listitem>
<listitem>
<para>
A BSON document (root or embedded) without a
<property>__pclass</property> property
<footnote xml:id="mongodb.pclass">
<para>
A __pclass property is only deemed to exist if
there exists a property with that name, and it is a Binary value,
and the sub-type of the Binary value is 0x80. If any of these three
conditions is not met, the __pclass property does not exist and
should be treated as any other normal property.
</para>
</footnote>
becomes a PHP <classname>stdClass</classname> object, with each
BSON document key set as a public <classname>stdClass</classname>
property.
</para>
</listitem>
<listitem>
<para>
A BSON document (root or embedded) with a
<property>__pclass</property> property <footnoteref linkend="mongodb.pclass"/> becomes a PHP object of
the class name as defined by the <property>__pclass</property>
property.
</para>
<para>
If the named class implements the
<interfacename>MongoDB\BSON\Persistable</interfacename> interface,
then the properties of the BSON document, including the
<property>__pclass</property> property, are sent as an associative
array to the
<methodname>MongoDB\BSON\Unserializable::bsonUnserialize</methodname>
function to initialise the object's properties.
</para>
<para>
If the named class does not exist or does not implement the
<interfacename>MongoDB\BSON\Persistable</interfacename> interface,
<classname>stdClass</classname> will be used and each BSON document
key (including <property>__pclass</property>) will be set as a
public <classname>stdClass</classname> property.
</para>
<para>
The <property>__pclass</property> functionality relies on the
property being part of a retrieved MongoDB document. If you use a
<link linkend="mongodb-driver-query.construct-queryOptions">projection</link>
when querying for documents, you need to include the
<property>__pclass</property> field in the projection for this
functionality to work.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>"array"</literal></term>
<listitem>
<para>
Turns a BSON array or BSON document into a PHP array. There will be no
special treatment of a <property>__pclass</property> property <footnoteref linkend="mongodb.pclass"/>,
but it may be set as an element in the returned array if it was
present in the BSON document.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>"object"</literal> or <literal>"stdClass"</literal></term>
<listitem>
<para>
Turns a BSON array or BSON document into a
<classname>stdClass</classname> object. There will be no special
treatment of a <property>__pclass</property> property <footnoteref linkend="mongodb.pclass"/>, but it may
be set as a public property in the returned object if it was present
in the BSON document.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>any other string</term>
<listitem>
<para>
Defines the class name that the BSON array or BSON object should be
deserialized as. For BSON objects that include
<property>__pclass</property> properties, that class will take
priority.
</para>
<para>
If the named class does not exist, is not concrete (i.e. it is
abstract or an interface), or does not implement
<interfacename>MongoDB\BSON\Unserializable</interfacename> then an
<classname>MongoDB\Driver\Exception\InvalidArgumentException</classname>
exception is thrown.
</para>
<para>
If the BSON object has a <property>__pclass</property> property and
that class exists and implements
<interfacename>MongoDB\BSON\Persistable</interfacename> it will
supersede the class provided in the type map.
</para>
<para>
The properties of the BSON document, <emphasis>including</emphasis>
the <property>__pclass</property> property if it exists, will be sent
as an associative array to the
<methodname>MongoDB\BSON\Unserializable::bsonUnserialize</methodname>
function to initialise the object's properties.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<section xml:id="mongodb.persistence.typemaps">
<title>TypeMaps</title>
<para>
TypeMaps can be set through the
<methodname>MongoDB\Driver\Cursor::setTypeMap</methodname> method on a
<classname>MongoDB\Driver\Cursor</classname> object, or the
<literal>$typeMap</literal> argument of
<function>MongoDB\BSON\toPHP</function>. Each of the three
classes (<emphasis>root</emphasis>, <emphasis>document</emphasis>, and
<emphasis>array</emphasis>) can be individually set, in addition to the
field specific types.
</para>
<para>
If the value in the map is <type>NULL</type>, it means the same as the
<emphasis>default</emphasis> value for that item.
</para>
</section>
<section>
<title>Examples</title>
<para>
These examples use the following classes:
</para>
<para>
<variablelist>
<varlistentry>
<term>MyClass</term>
<listitem>
<para>
which does <emphasis>not</emphasis> implement any interface
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>YourClass</term>
<listitem>
<para>
which implements
<interfacename>MongoDB\BSON\Unserializable</interfacename>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OurClass</term>
<listitem>
<para>
which implements
<interfacename>MongoDB\BSON\Persistable</interfacename>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>TheirClass</term>
<listitem>
<para>
which extends OurClass
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The <methodname>MongoDB\BSON\Unserializable::bsonUnserialize</methodname>
method of YourClass, OurClass, TheirClass iterate over the array and set
the properties without modifications. It <emphasis>also</emphasis> sets
the <literal>$unserialized</literal> property to <literal>true</literal>:
<programlisting role="php">
<![CDATA[
<?php
function bsonUnserialize( array $map )
{
foreach ( $map as $k => $value )
{
$this->$k = $value;
}
$this->unserialized = true;
}
]]>
</programlisting>
</para>
<para>
<programlisting role="text">
<![CDATA[
/* typemap: [] (all defaults) */
{ "foo": "yes", "bar" : false }
-> stdClass { $foo => 'yes', $bar => false }
{ "foo": "no", "array" : [ 5, 6 ] }
-> stdClass { $foo => 'no', $array => [ 5, 6 ] }
{ "foo": "no", "obj" : { "embedded" : 3.14 } }
-> stdClass { $foo => 'no', $obj => stdClass { $embedded => 3.14 } }
{ "foo": "yes", "__pclass": "MyClass" }
-> stdClass { $foo => 'yes', $__pclass => 'MyClass' }
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "MyClass" } }
-> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'MyClass') }
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "YourClass") }
-> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass') }
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "OurClass") }
-> OurClass { $foo => 'yes', $__pclass => Binary(0x80, 'OurClass'), $unserialized => true }
{ "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "YourClass") }
-> stdClass { $foo => 'yes', $__pclass => Binary(0x44, 'YourClass') }
]]>
</programlisting>
</para>
<para>
<programlisting role="text">
<![CDATA[
/* typemap: [ "root" => "MissingClass" ] */
{ "foo": "yes" }
-> MongoDB\Driver\Exception\InvalidArgumentException("MissingClass does not exist")
/* typemap: [ "root" => "MyClass" ] */
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
-> MongoDB\Driver\Exception\InvalidArgumentException("MyClass does not implement Unserializable interface")
/* typemap: [ "root" => "MongoDB\BSON\Unserializable" ] */
{ "foo": "yes" }
-> MongoDB\Driver\Exception\InvalidArgumentException("Unserializable is not a concrete class")
/* typemap: [ "root" => "YourClass" ] */
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MongoDB\BSON\Unserializable" } }
-> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MongoDB\BSON\Unserializable"), $unserialized => true }
/* typemap: [ "root" => "YourClass" ] */
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
-> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MyClass"), $unserialized => true }
/* typemap: [ "root" => "YourClass" ] */
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } }
-> OurClass { $foo => "yes", $__pclass => Binary(0x80, "OurClass"), $unserialized => true }
/* typemap: [ "root" => "YourClass" ] */
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } }
-> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true }
/* typemap: [ "root" => "OurClass" ] */
{ foo: "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } }
-> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true }
]]>
</programlisting>
</para>
<para>
<programlisting role="text">
<![CDATA[
/* typemap: [ 'root' => 'YourClass' ] */
{ foo: "yes", "__pclass" : { "$type": "80", "$binary": "YourClass" } }
-> YourClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass'), $unserialized => true }
]]>
</programlisting>
</para>
<para>
<programlisting role="text">
<![CDATA[
/* typemap: [ 'root' => 'array', 'document' => 'array' ] */
{ "foo": "yes", "bar" : false }
-> [ "foo" => "yes", "bar" => false ]
{ "foo": "no", "array" : [ 5, 6 ] }
-> [ "foo" => "no", "array" => [ 5, 6 ] ]
{ "foo": "no", "obj" : { "embedded" : 3.14 } }
-> [ "foo" => "no", "obj" => [ "embedded => 3.14 ] ]
{ "foo": "yes", "__pclass": "MyClass" }
-> [ "foo" => "yes", "__pclass" => "MyClass" ]
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
-> [ "foo" => "yes", "__pclass" => Binary(0x80, "MyClass") ]
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } }
-> [ "foo" => "yes", "__pclass" => Binary(0x80, "OurClass") ]
]]>
</programlisting>
</para>
<para>
<programlisting role="text">
<![CDATA[
/* typemap: [ 'root' => 'object', 'document' => 'object' ] */
{ "foo": "yes", "__pclass": { "$type": "80", "$binary": "MyClass" } }
-> stdClass { $foo => "yes", "__pclass" => Binary(0x80, "MyClass") }
]]>
</programlisting>
</para>
</section>
</section>
</article>
</book>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->