Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7366f73

Browse files
committed
Address code review
1 parent 5c75a08 commit 7366f73

File tree

1 file changed

+52
-47
lines changed

1 file changed

+52
-47
lines changed

‎docs/tutorial/codecs.txt‎

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,27 @@ Overview
1616
--------
1717

1818
Codecs are used to decode BSON documents into PHP objects, and encode PHP objects into BSON documents. In contrast to
19-
other methods, they allow for more flexibility and customization of the process and how different data types are
20-
handled. They allow separating the logic for BSON encoding and decoding from the domain classes, allowing to decode BSON
21-
into plain old PHP objects (POPOs).
19+
other methods (e.g. type maps), codecs allow for greater customization and handling of different data types. They allow
20+
separating the logic for BSON encoding and decoding from the domain classes, allowing to decode BSON into plain old PHP
21+
objects (POPOs).
2222

23-
Document Codec Usage
24-
--------------------
23+
Handling Documents
24+
------------------
2525

2626
The main logic is contained in a document codec. This class implements the ``MongoDB\Codec\DocumentCodec`` interface and
2727
defines what data types can be encoded/decoded and how. The following example defines a ``Person`` class and a codec to
28-
encode/decode it:
28+
transform it:
2929

3030
.. code-block:: php
3131

3232
<?php
3333

3434
final class Person
3535
{
36-
public MongoDB\BSON\ObjectId $id;
37-
public string $name;
38-
39-
public function __construct(string $name)
40-
{
41-
$this->id = new MongoDB\BSON\ObjectId();
42-
$this->name = $name;
43-
}
36+
public function __construct(
37+
public string $name,
38+
public readonly MongoDB\BSON\ObjectId $id = new MongoDB\BSON\ObjectId(),
39+
) {}
4440
}
4541

4642
.. code-block:: php
@@ -69,10 +65,10 @@ encode/decode it:
6965
throw UnsupportedValueException::invalidDecodableValue($value);
7066
}
7167

72-
$person = new Person($value->get('name'));
73-
$person->id = $value->get('_id');
74-
75-
return $person;
68+
return new Person(
69+
$value->get('name'),
70+
$value->get('_id'),
71+
);
7672
}
7773

7874
public function encode($value): MongoDB\BSON\Document
@@ -105,19 +101,21 @@ To then use this codec with a collection, specify the ``codec`` option when sele
105101
$person = $collection->findOne();
106102

107103
The example above selects a collection and instructs it to use the ``PersonCodec`` for encoding and decoding documents.
108-
When inserting data, the ``PersonCodec`` is used to encode the document. When retrieving data, the ``PersonCodec`` is
109-
used to decode BSON data into a ``Person`` instance. Note that while the ``PersonCodec`` could technically decode any
104+
When inserting data, the ``PersonCodec`` is used to encode the document. When retrieving data, the same ``PersonCodec``
105+
is used to decode BSON data into a ``Person`` instance. Note that while the ``PersonCodec`` could technically decode any
110106
BSON document that contains a name field, we wouldn't want to use it for any other documents. Document codecs are meant
111107
to be used in a collection, or when decoding embedded documents.
112108

113109
When working on a collection with a codec, the codec will only accept and return data of that type for certain
114-
operations. The ``bulkWrite``, ```findOneAndReplace``, ``insertMany``, ``insertOne``, and ``replaceOne`` operations
115-
will attempt to encode the given data using the provided codec. Trying to insert or replace a document that cannot be
116-
encoded will result in an exception. The ``aggregate``, ``find``, ``findOne``, ``findOneAndDelete``,
117-
``findOneAndReplace``, and ``findOneAndUpdate`` operations will attempt to decode returned documents using the provided
118-
codec. If the codec does not support the data returned, an exception will be thrown. You can disable codec usage for a
119-
specific operation or use a different codec (e.g. to decode the result of an aggregation pipeline) by specifying the
120-
nullable ``codec`` option for the operation. This will override the collection-level codec:
110+
operations. Insert and replace operations (e.g. ``insertOne``, ```findOneAndReplace``, and some ``bulkWrite``
111+
operations) will attempt to encode the given data using the provided codec. Trying to insert or replace a document that
112+
cannot be encoded will result in an exception. Read operations (e.g. ``aggregate``, ``find``, and ``findOneAndUpdate``)
113+
operations will attempt to decode returned documents using the provided codec. If the codec does not support the data
114+
returned, an exception will be thrown.
115+
116+
You can disable codec usage for a specific operation or use a different codec (e.g. to decode the result of an
117+
aggregation pipeline) by specifying the ``null`` for the ``codec`` option for any operation. This will override the
118+
collection-level codec:
121119

122120
.. code-block:: php
123121

@@ -136,12 +134,14 @@ nullable ``codec`` option for the operation. This will override the collection-l
136134
'codec' => null,
137135
]);
138136

139-
Generic Codecs
140-
--------------
137+
Handling Fields and Data Types
138+
------------------------------
139+
140+
The previous example showed how to define a codec for a specific class. However, you may want to create a codec that
141+
handles a particular data type in any document. This can be achieved by implementing the ``MongoDB\Codec\Codec``
142+
interface.
141143

142-
The previous example showed how to define a codec for a specific class. However, sometimes you want to define codecs to
143-
handle a given type in all documents. For such codecs, you can implement the ``MongoDB\Codec\Codec`` interface. The
144-
following example defines a codec to store ``DateTimeInterface`` instances as BSON dates including the timezone:
144+
The following example defines a codec to store ``DateTimeInterface`` instances as BSON dates including the timezone:
145145

146146
.. code-block:: php
147147

@@ -203,7 +203,7 @@ following example defines a codec to store ``DateTimeInterface`` instances as BS
203203
}
204204
}
205205

206-
This codec can now be leveraged by other codecs encode and decode dates. Let's return to the previous example and add a
206+
This codec can now be leveraged by other codecs handle date fields. Let's return to the previous example and add a
207207
``createdAt`` field that contains the creation date. The modified encode and decode methods would look like this (other
208208
code omitted for brevity):
209209

@@ -213,11 +213,15 @@ code omitted for brevity):
213213

214214
final class PersonCodec implements MongoDB\Codec\DocumentCodec
215215
{
216+
use MongoDB\Codec\DecodeIfSupported;
217+
use MongoDB\Codec\EncodeIfSupported;
218+
216219
public function __construct(
217220
private readonly DateTimeCodec $dateTimeCodec = new DateTimeCodec(),
218221
) {}
219222

220-
// Other code omitted for brevity
223+
// Other methods omitted for brevity
224+
221225
public function decode($value): Person
222226
{
223227
if (! $this->canDecode($value)) {
@@ -245,12 +249,12 @@ code omitted for brevity):
245249
}
246250
}
247251

248-
Handling embedded documents
252+
Handling Embedded Documents
249253
---------------------------
250254

251-
The previous example showed how to handle a single document. However, sometimes you want to handle fields that contain
252-
embedded documents. To show this, let's create an address document that we'll be embedding into our ``Person`` document.
253-
To ensure consistency, we're going to make this a readonly class:
255+
A previous example showed how to handle a single document. However, sometimes you want to handle fields that contain
256+
embedded documents. We will demonstrate this using an ``Address`` document, which we will embed within a ``Person``
257+
document. To ensure consistency, we're going to make this a read-only class:
254258

255259
.. code-block:: php
256260

@@ -274,7 +278,11 @@ We can now create a document codec for this class:
274278

275279
final class AddressCodec implements MongoDB\Codec\DocumentCodec
276280
{
277-
// Other code omitted for brevity
281+
use MongoDB\Codec\DecodeIfSupported;
282+
use MongoDB\Codec\EncodeIfSupported;
283+
284+
// Other methods omitted for brevity
285+
278286
public function decode($value): Person
279287
{
280288
if (! $this->canDecode($value)) {
@@ -304,10 +312,7 @@ We can now create a document codec for this class:
304312
}
305313
}
306314

307-
This codec is quite similar to the ``PersonCodec`` we had before, except that we're not adding an identifier to it. The
308-
creation of the object also differs, as we have to pass all the fields to the constructor.
309-
310-
In the ``PersonCodec``, we can now extend the ``decode`` and ``encode`` methods to handle the address field. Note that
315+
In the ``PersonCodec``, we can now modify the ``decode`` and ``encode`` methods to handle the address field. Note that
311316
the example below excludes some code we've already shown in previous examples.
312317

313318
.. code-block:: php
@@ -359,10 +364,10 @@ the example below excludes some code we've already shown in previous examples.
359364
Codec Libraries
360365
---------------
361366

362-
If you have a number of codecs that you want to use in multiple places, you can create a codec library. A codec library
363-
contains a list of codecs and checks each codec if it supports a value. If it does, it will use that codec to encode or
364-
decode the given value. The following code snippet changes the ``PersonCodec`` to use a codec library instead of a
365-
hard-coded ``DateTimeCodec``:
367+
A codec library contains a list of codecs and presents itself as a codec. When encoding or decoding a value, it will
368+
consult each registered codec in sequence and delegate to the first supporting codec to transform that value.
369+
370+
The following code snippet changes the ``PersonCodec`` to use a codec library instead of a hard-coded ``DateTimeCodec``:
366371

367372
.. code-block:: php
368373

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /