# La classe MongoDB\Driver\Cursor

(mongodb >=1.0.0)

## Introduction

La classe MongoDB\Driver\Cursor encapsule le résultat d'une commande ou d'une requête MongoDB, pouvant être retournée par, respectivement, MongoDB\Driver\Manager::executeCommand() ou MongoDB\Driver\Manager::executeQuery().

## Synopsis de la classe

final class MongoDB\Driver\Cursor implements MongoDB\Driver\CursorInterface {
/* Méthodes */
final private __construct()
public current(): array|object|null
final public getId(): MongoDB\BSON\Int64
final public getServer(): MongoDB\Driver\Server
final public isDead(): bool
public key(): int
public next(): void
public rewind(): void
final public setTypeMap(array `$typemap`): void
final public toArray(): array
public valid(): bool
}

## Historique

Version | Description
--- | ---
PECL mongodb 1.9.0 | Implémente Iterator.
PECL mongodb 1.6.0 | Iméplémentation de MongoDB\Driver\CursorInterface, qui étend Traversable.

## Exemples

Exemple #1 Lecture d'un jeu de résultats

MongoDB\Driver\Manager::executeCommand() et MongoDB\Driver\Manager::executeQuery() les deux renvoient leur (s) résultat (s) en tant qu'objet MongoDB\Driver\Cursor. Cet objet peut être utilisé pour itérer au sein du jeu de résultats de la commande ou de la requête.

Parce que MongoDB\Driver\Cursor implémente l'interface Traversable, vous pouvez simplement itérer sur le jeu de résultats avec `foreach`.

`<?php
$manager = new MongoDB\Driver\Manager();
/* Insérez des documents afin que notre requête renvoie des informations */
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['name' => 'Ceres', 'size' => 946, 'distance' => 2.766]);
$bulkWrite->insert(['name' => 'Vesta', 'size' => 525, 'distance' => 2.362]);
$manager->executeBulkWrite("test.asteroids", $bulkWrite);
/* Requête pour tous les éléments de la collection */
$query = new MongoDB\Driver\Query( [] );
/* Interrogez la collection "asteroids" de la base de données "test" */
$cursor = $manager->executeQuery("test.asteroids", $query);
/* $cursor contient maintenant un objet qui entoure le jeu de résultats.
* Utilisez foreach() pour itérer sur tous les résultats */
foreach($cursor as $document) {
print_r($document);
}
?>`

Résultat de l'exemple ci-dessus est similaire à :

    stdClass Object
    (
        [_id] => MongoDB\BSON\ObjectId Object
            (
                [oid] => 5a4cff2f122d3321565d8cc2
            )

        [name] => Ceres
        [size] => 946
        [distance] => 2.766
    )
    stdClass Object
    (
        [_id] => MongoDB\BSON\ObjectId Object
            (
                [oid] => 5a4cff2f122d3321565d8cc3
            )

        [name] => Vesta
        [size] => 525
        [distance] => 2.362
    }

Exemple #2 Lecture d'un jeu de résultats pour un curseur à queue

Les » curseurs à queue sont un type spécial de curseur MongoDB qui permet au client de lire quelques résultats et d'attendre jusqu'à ce que plus de documents deviennent disponibles. Ces curseurs sont principalement utilisés avec » Capped Collections et » Change Streams.

Bien que les curseurs normaux puissent être parcourus une fois avec `foreach`, cette approche ne fonctionnera pas avec les curseurs à queue. Lorsque `foreach` est utilisé avec un curseur à queue, la boucle s'arrêtera à la fin du jeu de résultats initial. Tenter de continuer l'itération sur le curseur avec une seconde `foreach` lèverait une exception, car PHP tente de rembobiner le curseur. Comme pour les objets result dans d'autres pilotes de base de données, les curseurs dans MongoDB prennent uniquement en charge l'itération en avant, ce qui signifie qu'ils ne peuvent pas être rembobinés.

Afin de lire en continu à partir d'un curseur de queue, l'objet Cursor doit être enveloppé avec un IteratorIterator. Cela permet à l'application de contrôler directement l'itération du curseur, d'éviter de rembobiner par inadvertance le curseur et de décider quand attendre les nouveaux résultats ou arrêter complètement l'itération.

Afin de démontrer un curseur en action, deux scripts seront utilisés: un "Producer" et un "Consumer". Le script Producer créera une nouvelle collection plafonnée à l'aide de la commande » Create et procédera à l'insertion d'un nouveau document dans cette collection chaque seconde.

`<?php
$manager = new MongoDB\Driver\Manager;
$manager->executeCommand('test', new MongoDB\Driver\Command([
'create' => 'asteroids',
'capped' => true,
'size' => 1048576,
]));
while (true) {
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['createdAt' => new MongoDB\BSON\UTCDateTime]);
$manager->executeBulkWrite('test.asteroids', $bulkWrite);
sleep(1);
}
?>`

Avec le script Producer toujours en cours d'exécution, un deuxième script consommateur peut être exécuté pour lire les documents insérés à l'aide d'un curseur de queue, indiqué par les options `tailable` et `awaitData` à MongoDB\Driver\Query::__construct().

`<?php
$manager = new MongoDB\Driver\Manager;
$query = new MongoDB\Driver\Query([], [
'tailable' => true,
'awaitData' => true,
]);
$cursor = $manager->executeQuery('test.asteroids', $query);
$iterator = new IteratorIterator($cursor);
$iterator->rewind();
while (true) {
if ($iterator->valid()) {
$document = $iterator->current();
printf("Consumed document created at: %s\n", $document->createdAt);
}
$iterator->next();
}
?>`

Le script consommateur va commencer par imprimer rapidement tous les documents disponibles dans la collection plafonnée (comme si `foreach` avait été utilisé); toutefois, il ne se terminera pas à la fin du jeu de résultats initial. Étant donné que le curseur est en file d'attente, l'appel de IteratorIterator::next() se bloque et attend des résultats supplémentaires. IteratorIterator::valid() est également utilisé pour vérifier s'il y a effectivement des données disponibles à lire à chaque étape.

> Note: Cet exemple utilise l'option de requête `awaitData` pour indiquer au serveur de bloquer pendant une courte période (par exemple une seconde) à la fin du jeu de résultats avant de retourner une réponse au pilote. Ceci est utilisé pour empêcher le pilote d'interroger agressivement le serveur lorsqu'il n'y a aucun résultat disponible. L'option `maxAwaitTimeMS` peut être utilisée conjointement avec `tailable` et `awaitData` pour spécifier la durée pendant laquelle le serveur doit se bloquer lorsqu'il atteint la fin du jeu de résultats.

## Erreurs / Exceptions

Lors de l'itération sur l'objet Cursor, les données BSON sont converties en variables PHP. Cette itération peut provoquer les exceptions suivantes:

- Lèle une exception MongoDB\Driver\Exception\InvalidArgumentException si une classe dans le mappage de type ne peut pas être instanciée ou n'implémente pas MongoDB\BSON\Unserializable.
- Lance une exception MongoDB\Driver\Exception\UnexpectedValueException si l'entrée ne contient pas exactement un document BSON. Les raisons possibles comprennent, mais ne sont pas limitées à, BSON invalide, des données supplémentaires (après avoir lu un document BSON), ou une erreur imprévu de » libbson.

## Sommaire

- MongoDB\Driver\Cursor::__construct — Créer un nouveau curseur (non utilisé)
- MongoDB\Driver\Cursor::current — Renvoie l'élément courant
- MongoDB\Driver\Cursor::getId — Retourne l'ID de ce curseur
- MongoDB\Driver\Cursor::getServer — Retourne le serveur associé à ce curseur
- MongoDB\Driver\Cursor::isDead — Vérifie si le curseur est épuisé ou peut avoir des résultats supplémentaires
- MongoDB\Driver\Cursor::key — Renvoie le numéro de l'index du résultat courant dans le curseur
- MongoDB\Driver\Cursor::next — Avance le curseur vers le résultat suivant
- MongoDB\Driver\Cursor::rewind — Rembobine le curseur jusqu'au premier résultat
- MongoDB\Driver\Cursor::setTypeMap — Défini un type de carte à utiliser pour la désérialisation BSON
- MongoDB\Driver\Cursor::toArray — Retourne un tableau contenant tous les résultats pour ce curseur
- MongoDB\Driver\Cursor::valid — Vérifie si la position actuelle du curseur est valide