ドキュメント本文へスキップ
PHP

ページネーション

ページ分割されるすべての一覧で、1 ページ、全ページ、または 1 アイテムずつ。

list、listAll、iterate

ページ分割されるすべての一覧には 3 つのメソッドがあります。list は 1 ページを取得して OpenEmail\Result\Page を返します。listAll はすべてのページでカーソルをたどり、1 つの配列を返します。iterate は同じページを 1 アイテムずつたどって Generator を返し、次のページはそこに到達したときに初めて取得します。3 つとも一覧のフィルター、limit:、cursor:、apiKey: を受け取ります。

three_ways.php
$page = $client->emails->list(status: 'failed', limit: 50); foreach ($page as $email) {    echo $email['id'], ' ', $email['lastError'] ?? '', PHP_EOL;} $failures = $client->emails->listAll(status: 'failed'); foreach ($client->emails->iterate(status: 'failed') as $email) {    echo $email['id'], PHP_EOL;} echo count($failures), ' ', $page->hasMore ? 'more to come' : 'that is all', PHP_EOL;

名前空間に複数の一覧がある場合は、どこでも同じ 3 つの名前が、たどる一覧の名前を付けて繰り返されます。emails の listEvents、listAllEvents、iterateEvents、webhooks の listDeliveries、listAllDeliveries、iterateDeliveries などです。

OpenEmail\Result\Page

itemsarray
このページの行。API の `data` エンベロープから取り出したもので、それぞれ連想配列です。ページに何もなければ空です。
hasMorebool
次のページがあるかどうか。API が `hasMore` を送らない場合は、`nextCursor` があるときにちょうど true になります。
nextCursorstring or null
次のページのために `cursor:` として渡し返す値。最後のページでは null。

ページは不変で、プロパティはすべて readonly です。IteratorAggregate と Countable も実装しているため、foreach ($page as $item) で行をたどり、count($page) で行数を数えられます。

Generator

iterate は走査を始めるまで何も要求せず、現在のページのアイテムがすべて yield されて初めて次のページを要求します。そのため、早く止まる処理はリクエストも止めます。break で走査が終わり、ループを含む関数から return しても同じです。

generator.php
$latest = []; foreach ($client->emails->iterate(status: 'failed', limit: 100) as $email) {    $latest[] = $email;     if (count($latest) === 10) {        break;    }} $invoice = null; foreach ($client->emails->iterate(status: 'failed') as $email) {    if (($email['tags']['invoice'] ?? null) === 'inv_2026_09_4192') {        $invoice = $email;         break;    }} echo count($latest), ' ', $invoice['id'] ?? 'not found', PHP_EOL;

Generator に対して呼ぶ iterator_to_array() のように、すべてのアイテムを必要とする処理は、listAll と同様に、戻る前にすべてのページを読みます。

Generator は 1 回しか走査できません。2 回目の走査は例外をスローするため、アイテムがもう一度必要なときは iterate を再度呼ぶか、Generator ではなくアイテムを保持してください。

カーソルからの再開

カーソルは不透明な値です。最後に読んだページの nextCursor を保持し、cursor: として渡し返せば、後のリクエストや別のプロセスでもそこから続けられます。listAll と iterate も cursor: を受け取り、その後から走査を始めます。

resume.php
$firstPage = $client->emails->list(status: 'failed', limit: 25);$saved = $firstPage->nextCursor; if ($saved !== null) {    $rest = $client->emails->listAll(status: 'failed', cursor: $saved);    echo count($rest), PHP_EOL;}

カーソルはそれを返した一覧とフィルターに属するため、同じフィルターと一緒に送ってください。一覧が位置を特定できないカーソルは invalid_cursor で拒否され、その場合はカーソルなしで最初からやり直します。

limit:

limit: は合計ではなく各ページのサイズです。list では返ってくる行数です。listAll と iterate では各リクエストが要求する件数なので、大きな値にすれば同じ行数を少ない往復で取得できます。各一覧には独自の範囲と既定値があり、多くは 1〜100 で、指定しなければ 25 です。範囲外の値は丸められるのではなく拒否されます。各一覧のリファレンスにその範囲が書かれています。

走査が止まるとき

  • ページの hasMore が false のとき。
  • ページに nextCursor がないとき。続きがあると言いながらカーソルを示さないページは、永遠にループしてしまうからです。
  • API が、すでにたどったカーソルを返してきたとき。理由は同じです。

各ページは GET なので、例外がスローされる前に他の読み取りと同様に個別にリトライされます。リトライ後も残った失敗は listAll からスローされ、それまでに取得したアイテムは破棄されます。iterate ではその時点で前のページのアイテムはすでに yield されているため、ループの処理を 2 回実行しても安全にするか、list でページを取得して各 nextCursor を保持し、2 回目の試行が 1 回目の止まった所から始められるようにしてください。

スレッドと下書き

threads->list と drafts->list、およびそれぞれの listAll と iterate は、カーソルではなく API の pageToken と nextPageToken でページ分割します。クライアントはこの違いを隠します。トークンは cursor: として渡し、nextCursor から読み取ってください。

page_token.php
$page = $client->threads->list(folder: 'inbox', limit: 50);$later = $page->hasMore ? $client->threads->list(folder: 'inbox', limit: 50, cursor: $page->nextCursor) : null; echo count($page), ' ', $later === null ? 0 : count($later), PHP_EOL;

サーバーはページが満杯で返ってくるたびにトークンを出すため、結果的に最後だったページでも hasMore が true になることがあり、その場合は次の呼び出しがアイテムを返しません。

追加の情報を持つページ

いくつかの一覧は行以外の情報も返し、Page の代わりに OpenEmail\Result の独自のオブジェクトを返します。いずれも不変で、行に対する IteratorAggregate であり、Countable でもあります。

メソッド返すもの追加されるもの
addresses->listAddressBookPageitems の代わりに addresses、さらに unrestricted と domains、および hasMore と nextCursor。
addresses->listAllAddressBookaddresses にすべてのアドレスが入り、unrestricted と domains は最後のページが報告した値になります。配列ではなくアドレス帳全体を返す唯一の listAll です。addresses->iterate はアドレスだけを yield します。
contacts->listPeoplePeoplePageseen。キーがメールに現れたアドレスを読めない場合は false です。listAllPeople と iteratePeople は人だけを返します。
tempMail->listMessagesTempMessagesPageexpiresAt。受信箱の期限が切れる時刻です。listAllMessages と iterateMessages はメッセージだけを返します。
templates->listSendsTemplateSendsカーソルではなくページ番号でページ分割します:items、total、page、pageSize。次のページは page: で要求します。
emails->sendBatchBatchResultページではありません:送信した各メッセージに 1 つずつの items と、sent と failed の件数。

API の配列を返す一覧

一部の一覧はオフセット、ページ番号、または独自の数値カーソルでページ分割し、Page ではなく、デコード済みのボディを受け取ったまま、つまり data を持つ配列として返します。listAll や iterate はないため、ページ分割は自分で行います。

メソッドページ分割の方法返ってくるもの
exports->listlimit: と offset:data、total、hasMore。
imports->listFailuresafter: と limit:data と、after: として渡し返す整数の nextCursor。最後のページでは null です。
subscriptions->list と subscriptions->listDomainslimit: と offset:data、total、counts、hasMore。
billing->listInvoicespage: と limit:data、total、page、limit、hasMore、metered。
offset_paging.php
$offset = 0; do {    $batch = $client->subscriptions->list(status: 'active', limit: 50, offset: $offset);     foreach ($batch['data'] as $row) {        echo $row['senderEmail'], ' ', $row['total'], PHP_EOL;    }     $offset += count($batch['data']);} while ($batch['hasMore'] && $batch['data'] !== []);

languages->list、labels->listColors、roles->listPermissions のように、ページ分割されない一覧は、行をそのまま通常のリストとして返します。