Skip to content

Commit 91ce422

Browse files
committed
Update tailable cursor documentation to account for cursor changes
1 parent 84a9106 commit 91ce422

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

docs/tutorial/tailable-cursor.txt

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Overview
1818
When the driver executes a query or command (e.g.
1919
:manual:`aggregate </reference/command/aggregate>`), results from the operation
2020
are returned via a :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>`
21-
object. The Cursor class implements PHP's :php:`Traversable <traversable>`
21+
object. The Cursor class implements PHP's :php:`Iterator <iterator>`
2222
interface, which allows it to be iterated with ``foreach`` and interface with
2323
any PHP functions that work with :php:`iterables <types.iterable>`. Similar to
2424
result objects in other database drivers, cursors in MongoDB only support
@@ -37,18 +37,23 @@ the loop will stop upon reaching the end of the initial result set. Attempting
3737
to continue iteration on the cursor with a second ``foreach`` would throw an
3838
exception, since PHP attempts to rewind the cursor.
3939

40-
In order to continuously read from a tailable cursor, we will need to wrap the
41-
Cursor object with an :php:`IteratorIterator <iteratoriterator>`. This will
42-
allow us to directly control the cursor's iteration (e.g. call ``next()``),
43-
avoid inadvertently rewinding the cursor, and decide when to wait for new
44-
results or stop iteration entirely.
40+
In order to continuously read from a tailable cursor, we will need to directly
41+
control the cursor's iteration (e.g. call ``next()``), avoid inadvertently
42+
rewinding the cursor, and decide when to wait for new results or stop iteration
43+
entirely.
4544

46-
Wrapping a Normal Cursor
47-
------------------------
45+
.. note::
46+
47+
Before version 1.9.0 of the ``ext-mongodb`` extension, the cursor class does
48+
not implement the :php:`Iterator <iterator>` interface. To manually iterate
49+
cursors using the method described below, cursors must be wrapped in a
50+
:php:`IteratorIterator <iteratoriterator>`.
51+
52+
Manually Iterating a Normal Cursor
53+
----------------------------------
4854

49-
Before looking at how a tailable cursor can be wrapped with
50-
:php:`IteratorIterator <iteratoriterator>`, we'll start by examining how the
51-
class interacts with a normal cursor.
55+
Before looking at how a tailable cursor can be iterated, we'll start by
56+
examining how the class interacts with a normal cursor.
5257

5358
The following example finds five restaurants and uses ``foreach`` to view the
5459
results:
@@ -74,7 +79,7 @@ not occurred, the iterator then advances to the next position, control jumps
7479
back to the validity check, and the loop continues.
7580

7681
With the inner workings of ``foreach`` under our belt, we can now translate the
77-
preceding example to use IteratorIterator:
82+
preceding example to use the Iterator methods directly:
7883

7984
.. code-block:: php
8085

@@ -84,28 +89,26 @@ preceding example to use IteratorIterator:
8489

8590
$cursor = $collection->find([], ['limit' => 5]);
8691

87-
$iterator = new IteratorIterator($cursor);
92+
$cursor->rewind();
8893

89-
$iterator->rewind();
90-
91-
while ($iterator->valid()) {
92-
$document = $iterator->current();
94+
while ($cursor->valid()) {
95+
$document = $cursor->current();
9396
var_dump($document);
94-
$iterator->next();
97+
$cursor->next();
9598
}
9699

97100
.. note::
98101

99-
Calling ``$iterator->next()`` after the ``while`` loop naturally ends would
102+
Calling ``$cursor->next()`` after the ``while`` loop naturally ends would
100103
throw an exception, since all results on the cursor have been exhausted.
101104

102105
The purpose of this example is simply to demonstrate the functional equivalence
103106
between ``foreach`` and manual iteration with PHP's :php:`Iterator <iterator>`
104-
API. For normal cursors, there is little reason to use IteratorIterator instead
105-
of a concise ``foreach`` loop.
107+
API. For normal cursors, there is little reason to manually iterate results
108+
instead of a concise ``foreach`` loop.
106109

107-
Wrapping a Tailable Cursor
108-
--------------------------
110+
Iterating a Tailable Cursor
111+
---------------------------
109112

110113
In order to demonstrate a tailable cursor in action, we'll need two scripts: a
111114
"producer" and a "consumer". The producer script will create a new capped
@@ -154,7 +157,7 @@ If you execute this consumer script, you'll notice that it quickly exhausts all
154157
results in the capped collection and then terminates. We cannot add a second
155158
``foreach``, as that would throw an exception when attempting to rewind the
156159
cursor. This is a ripe use case for directly controlling the iteration process
157-
using :php:`IteratorIterator <iteratoriterator>`.
160+
using the :php:`Iterator <iterator>` interface.
158161

159162
.. code-block:: php
160163

@@ -167,17 +170,15 @@ using :php:`IteratorIterator <iteratoriterator>`.
167170
'maxAwaitTimeMS' => 100,
168171
]);
169172

170-
$iterator = new IteratorIterator($cursor);
171-
172-
$iterator->rewind();
173+
$cursor->rewind();
173174

174175
while (true) {
175-
if ($iterator->valid()) {
176-
$document = $iterator->current();
176+
if ($cursor->valid()) {
177+
$document = $cursor->current();
177178
printf("Consumed document created at: %s\n", $document->createdAt);
178179
}
179180

180-
$iterator->next();
181+
$cursor->next();
181182
}
182183

183184
Much like the ``foreach`` example, this version on the consumer script will

0 commit comments

Comments
 (0)