@@ -18,7 +18,7 @@ Overview
18
18
When the driver executes a query or command (e.g.
19
19
:manual:`aggregate </reference/command/aggregate>`), results from the operation
20
20
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 >`
22
22
interface, which allows it to be iterated with ``foreach`` and interface with
23
23
any PHP functions that work with :php:`iterables <types.iterable>`. Similar to
24
24
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
37
37
to continue iteration on the cursor with a second ``foreach`` would throw an
38
38
exception, since PHP attempts to rewind the cursor.
39
39
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.
45
44
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
+ ----------------------------------
48
54
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.
52
57
53
58
The following example finds five restaurants and uses ``foreach`` to view the
54
59
results:
@@ -74,7 +79,7 @@ not occurred, the iterator then advances to the next position, control jumps
74
79
back to the validity check, and the loop continues.
75
80
76
81
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 :
78
83
79
84
.. code-block:: php
80
85
@@ -84,28 +89,26 @@ preceding example to use IteratorIterator:
84
89
85
90
$cursor = $collection->find([], ['limit' => 5]);
86
91
87
- $iterator = new IteratorIterator($ cursor);
92
+ $cursor->rewind( );
88
93
89
- $iterator->rewind();
90
-
91
- while ($iterator->valid()) {
92
- $document = $iterator->current();
94
+ while ($cursor->valid()) {
95
+ $document = $cursor->current();
93
96
var_dump($document);
94
- $iterator ->next();
97
+ $cursor ->next();
95
98
}
96
99
97
100
.. note::
98
101
99
- Calling ``$iterator ->next()`` after the ``while`` loop naturally ends would
102
+ Calling ``$cursor ->next()`` after the ``while`` loop naturally ends would
100
103
throw an exception, since all results on the cursor have been exhausted.
101
104
102
105
The purpose of this example is simply to demonstrate the functional equivalence
103
106
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.
106
109
107
- Wrapping a Tailable Cursor
108
- --------------------------
110
+ Iterating a Tailable Cursor
111
+ ---------------------------
109
112
110
113
In order to demonstrate a tailable cursor in action, we'll need two scripts: a
111
114
"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
154
157
results in the capped collection and then terminates. We cannot add a second
155
158
``foreach``, as that would throw an exception when attempting to rewind the
156
159
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 .
158
161
159
162
.. code-block:: php
160
163
@@ -167,17 +170,15 @@ using :php:`IteratorIterator <iteratoriterator>`.
167
170
'maxAwaitTimeMS' => 100,
168
171
]);
169
172
170
- $iterator = new IteratorIterator($cursor);
171
-
172
- $iterator->rewind();
173
+ $cursor->rewind();
173
174
174
175
while (true) {
175
- if ($iterator ->valid()) {
176
- $document = $iterator ->current();
176
+ if ($cursor ->valid()) {
177
+ $document = $cursor ->current();
177
178
printf("Consumed document created at: %s\n", $document->createdAt);
178
179
}
179
180
180
- $iterator ->next();
181
+ $cursor ->next();
181
182
}
182
183
183
184
Much like the ``foreach`` example, this version on the consumer script will
0 commit comments