如何为分页制作循环函数调用?

4

我正在尝试使用Airtable API从我的数据中检索记录,具体来说是一列单元格中的URL列表。

我编写了一个函数get_airtable_records,通过curl调用API,它可以正常工作,返回Json对象作为结果。具体来说,我将URL推送到一个数组$article_urls中。

唯一的问题是,Airtable将结果限制为最多100个记录的“页面”,而我的数据包含了更多记录。API接受参数maxRecordspageSize,但更重要的pageSize仍然被限制在100个记录以内。

Airtable返回的另一个Json值是offset,在这种情况下用于分页。 offset是一个记录ID,旨在用作输入参数(也称为offset)。您可以使用它来表示后续额外API调用中的起始记录。我理解这一点。

我不明白的是如何修改我的代码,以应对需要再次轮询Airtable的可能性。

换句话说,在没有offset值的情况下,我们应该始终从头开始运行。 然后,如果在返回的结果中存在offset值,我们应该再次运行 - 直到没有offset值为止。

这是我的代码。

  // Make get request, store result in array
  $articles = get_airtable_records($offset); // $offset won't exist at the start

  // Prepare Article URLs list as an array
  if (!isset($article_urls)) {
     $article_urls = array();
  }

  // For each URL found in Airtable
  foreach($articles['records'] as $record){
     $url = $record['fields']['Published URL'];
     // Add to our array list
     if (!empty($url)) {
        array_push($article_urls, $url);
     }
  }

  // URL list after first pass:
  echo '<pre>';
  print_r($article_urls);
  echo '</pre>';
  // May hit a max of 100

  // echo 'Offset: ' . $articles['offset'];
  // Value like "itrJYSLx0RfslI80f/recEu6TiPTPCSDxg5" may exist.
  // If so, go back to start, do get_airtable_records($offset) again and array_push
  // Until, once more there is no "offset" value at end

我猜想一种while循环会很有用……?
有几件事是真的……
- 在第一次调用中,不需要传递起始的offset值,因为它从记录0开始。 - 但是在后续的调用中可能会生成一个offset值,应该用它来进行另一次调用。 - 最后一次调用将不会生成offset值,因为它已经返回了最后一页耗尽的结果,没有必要重新开始。

这是一个重复的帖子。https://dev59.com/Sqnka4cB1Zd3GeqPM1_-#56178563 - david-littlefield
2个回答

1
感谢@anthony在这里对类似问题的回答,我好像有一些可用的代码...
  // Prepare Article URLs list as an array
  $article_urls = array();

  // Call Airtable records in pages of 100 max
  do {

        // Offset is either inherited from last page's results, or is nothing
        $offset = $articles['offset'] ?: "";

        // Make get request, store result in array
        $articles = get_airtable_records($offset);

        // For each URL found in Airtable
        foreach($articles['records'] as $record){
           $url = $record['fields']['Published url'];
           // Add to our array list
           if (!empty($url)) {
              array_push($article_urls, $url);
           }
        }

  } while(!empty($articles['offset'])); // If there's an offset value (ie. starting record of next page), do again

  // Output URL list for check
  echo '<pre>';
  print_r($article_urls);
  echo '</pre>';

解释似乎是:

使用dowhile循环。在开始时,将offset设置为从上一次运行继承的值或未设置任何值。

我的get_airtable_records函数已经限制了API调用中是否存在offset,以下是添加offset查询字符串到下一个API调用的URL的代码...

  if (!empty($offset)) {
    $q_offset = '&offset='.$offset;
  }

我已经测试过这个代码,它将两页中的所有137个结果添加到了我的$article_urls数组中。但我没有测试超过两页的结果。

0

递归匿名函数也非常适用于自动分页器。

// http client
    $client
    // closure
    $autoPaginate = function (int $offset) use (&$autoPaginate, $client) {
        $response = $client->get('https://blah.com, [
            'offset' => $offset,
            'per_page' => 100,
        ]);
        // do response business logic/work
        
        // check your response meta or
        // wherever the next page or offset is passed back
        if (!$response->meta->next->offset) return;
        return $autoPaginate($response->meta->next->offset);
    };
    $autoPaginate(0);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接