पेजिनेशन
हर पेज वाली सूची पर एक पेज, सभी पेज, या एक बार में एक आइटम।
list, listAll और iterate
पेज होने वाली हर सूची के तीन मेथड हैं। list एक पेज लाता है और एक OpenEmail\Result\Page लौटाता है। listAll हर पेज में cursor का पीछा करता है और एक array लौटाता है। iterate उन्हीं पेजों पर एक-एक आइटम करके चलता है और एक Generator लौटाता है, जो अगला पेज तभी लाता है जब आप वहाँ पहुँचते हैं। तीनों सूची के फ़िल्टर, limit:, cursor: और apiKey: लेते हैं।
$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;जहाँ भी किसी namespace में एक से ज़्यादा सूची हो, वही तीन नाम दोहराए जाते हैं, उस सूची के नाम पर जिस पर वे चलते हैं: emails पर listEvents, listAllEvents और iterateEvents, webhooks पर listDeliveries, listAllDeliveries और iterateDeliveries, इत्यादि।
OpenEmail\Result\Page
itemsarray- इस पेज की पंक्तियाँ, API के `data` envelope से बाहर निकाली गईं, हर एक associative array। जब पेज में कुछ न हो तो ख़ाली।
hasMorebool- क्या इसके बाद कोई और पेज है। जब API कोई `hasMore` नहीं भेजता, तो यह ठीक तभी true होता है जब कोई `nextCursor` हो।
nextCursorstring or null- अगले पेज के लिए `cursor:` के रूप में क्या वापस भेजना है, और आख़िरी पेज पर null।
पेज अपरिवर्तनीय है: उसकी properties readonly हैं। यह IteratorAggregate और Countable भी है, इसलिए foreach ($page as $item) उसकी पंक्तियों पर चलता है और count($page) उन्हें गिनता है।
एक Generator
iterate तब तक कुछ नहीं माँगता जब तक आप उस पर चलना शुरू न करें, और अगला पेज तभी माँगता है जब मौजूदा पेज का हर आइटम yield हो चुका हो, इसलिए जल्दी रुकने वाली कोई भी चीज़ रिक्वेस्ट भी रोक देती है: break चलना ख़त्म करता है, और लूप वाले फ़ंक्शन से return करना भी।
$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 पर सिर्फ़ एक बार चला जा सकता है। दूसरी बार चलने पर throw होता है, इसलिए जब आइटम दोबारा चाहिए हों तो iterate फिर से कॉल करें, या Generator के बजाय आइटम रखें।
cursor से आगे बढ़ना
cursor अपारदर्शी होता है। आपने जो आख़िरी पेज पढ़ा उसका nextCursor रखें और वहीं से आगे बढ़ने के लिए उसे cursor: के रूप में वापस भेजें, किसी बाद की रिक्वेस्ट में या किसी दूसरे प्रोसेस में। listAll और iterate भी cursor: लेते हैं, और उसके बाद से चलना शुरू करते हैं।
$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;}cursor उसी सूची और उन्हीं फ़िल्टरों का होता है जिनसे वह आया, इसलिए उसके साथ वही फ़िल्टर भेजें। जिस cursor को सूची पहचान न सके उसे invalid_cursor के साथ अस्वीकार किया जाता है, और तब हल यही है कि बिना cursor के फिर से शुरू करें।
limit:
limit: हर पेज का आकार है, कुल संख्या नहीं। list पर यह बताता है कि कितनी पंक्तियाँ लौटती हैं। listAll और iterate पर यह बताता है कि हर रिक्वेस्ट कितनी माँगती है, इसलिए बड़ा मान रखने पर उन्हीं पंक्तियों के लिए कम आना-जाना होता है। हर सूची की अपनी सीमा और डिफ़ॉल्ट होता है, ज़्यादातर 1 से 100, और कुछ न भेजने पर 25, और सीमा से बाहर का मान छोटा करने के बजाय अस्वीकार कर दिया जाता है। हर सूची का संदर्भ उसकी सीमा बताता है।
चलना कब रुकता है
- जब कोई पेज कहे कि
hasMorefalse है। - जब किसी पेज में कोई
nextCursorन हो, क्योंकि जो पेज और होने का दावा करे पर कोई cursor न बताए वह हमेशा के लिए लूप में घूमता रहता। - जब API ऐसा cursor लौटा दे जिसका पालन walk पहले ही कर चुका है, उसी कारण से।
हर पेज एक GET है, इसलिए कुछ भी throw होने से पहले उसे किसी भी read की तरह अपने आप retry किया जाता है। retry के बाद भी बची विफलता listAll से throw होती है, और पहले से लाए गए आइटम छोड़ दिए जाते हैं। iterate में तब तक पहले के पेजों के आइटम yield हो चुके होते हैं, इसलिए लूप जो करता है उसे दो बार चलाने में सुरक्षित बनाएँ, या list से पेज करें और हर nextCursor रखें ताकि दूसरा प्रयास वहीं से शुरू हो सके जहाँ पहला रुका था।
थ्रेड और ड्राफ़्ट
threads->list और drafts->list, अपने listAll और iterate के साथ, cursor के बजाय API के pageToken और nextPageToken से पेज करते हैं। क्लाइंट यह अंतर छिपा देता है: टोकन को cursor: के रूप में पास करें और उसे nextCursor से पढ़ें।
$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->list | AddressBookPage | items की जगह addresses, साथ में unrestricted और domains, hasMore और nextCursor के साथ। |
| addresses->listAll | AddressBook | हर पता addresses में, और unrestricted तथा domains वैसे जैसे आख़िरी पेज ने बताए। यह अकेला listAll है जो array के बजाय पूरी पता-पुस्तिका लौटाता है। addresses->iterate सिर्फ़ पते yield करता है। |
| contacts->listPeople | PeoplePage | seen, जो तब false होता है जब कुंजी मेल में दिखे पते नहीं पढ़ सकती। listAllPeople और iteratePeople सिर्फ़ लोगों को लौटाते हैं। |
| tempMail->listMessages | TempMessagesPage | expiresAt, जब इनबॉक्स की मियाद ख़त्म होती है। listAllMessages और iterateMessages सिर्फ़ संदेश लौटाते हैं। |
| templates->listSends | TemplateSends | cursor के बजाय संख्या से पेज होता है: items, total, page और pageSize। अगला पेज page: से माँगें। |
| emails->sendBatch | BatchResult | पेज नहीं: items, आपके भेजे हर संदेश के लिए एक, sent और failed गिनती के साथ। |
वे सूचियाँ जो API का array लौटाती हैं
कुछ सूचियाँ offset, पेज संख्या या अपने संख्यात्मक cursor से पेज करती हैं, और Page के बजाय डिकोड की गई बॉडी को जैसी आई वैसी ही लौटाती हैं, यानी data वाला एक array। इनमें listAll या iterate नहीं है, इसलिए इन्हें आप ख़ुद पेज करते हैं।
| मेथड | किससे पेज होता है | क्या लौटता है |
|---|---|---|
| exports->list | limit: और offset: | data, total और hasMore। |
| imports->listFailures | after: और limit: | data, और nextCursor, एक integer जिसे after: के रूप में वापस भेजना है और जो आख़िरी पेज पर null होता है। |
| subscriptions->list और subscriptions->listDomains | limit: और offset: | data, total, counts और hasMore। |
| billing->listInvoices | page: और limit: | data, total, page, limit, hasMore और metered। |
$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, वह अपनी पंक्तियाँ सीधे एक सादी सूची के रूप में लौटाती है।