我如何通过光标的结果遍历每个页面

时间:2017-04-18 22:54:52

标签: php json

所以我已经尝试了几个小时来基本上获得用这个api选择的用户的recentAverageRap。所以我可以用代码获得它的一部分。但如果有下一页,我无法弄清楚如何进入下一页。所有我知道的是在我需要更改的url:cursor =到nextPageCursor的json值以进入下一页。但我一直在努力,无法从所有页面获得正确的信息。

到目前为止我的代码只有第一页:

<?php
    $userid = htmlentities($_GET['userid'], ENT_QUOTES);
    $assettypes = array("Hat", "Face", "Gear", "HairAccessory", "FaceAccessory", "NeckAccessory", "ShoulderAccessory", "FrontAccessory", "BackAccessory", "WaistAccessory");

    $rap2 = 0;
    foreach($assettypes as $assettype){
        $url = "https://inventory.roblox.com/v1/users/" . $userid . "/assets/collectibles?assetType=" . $assettype . "&sortOrder=Asc&limit=100&cursor=";
        $get = file_get_contents($url);
        $json = json_decode($get);
        $rap = 0;

        foreach($json->data as $val){
            $rap += $val->recentAveragePrice;
        }

        $rap2 += $rap;
    }

    echo $rap2;
?>

1 个答案:

答案 0 :(得分:0)

很抱歉重新提出一个旧问题,但我自己偶然发现了这个问题,并写了一个小的PHP类来帮助我在单个请求中完成获取Roblox的分页WebAPI端点的所有页面。

基本解决方案(顺序和慢速)将激活某种不断调用api的循环,同时递增?page?cursor查询参数值,直到给定AssetType的响应为止更长时间返回nextPageCursor值,然后打破循环并继续前进。

<?php
    function get_page($userid, $assettype, $page, $cursor){
        $url = "https://inventory.roblox.com/v1/users/" . $userid . "/assets/collectibles?assetType=" . $assettype . "&sortOrder=Asc&limit=100&cursor=" . $cursor . "&page=" . $page;
        $get = file_get_contents($url);
        $json = json_decode($get);
        $rap = 0;
        $items = 0;
        foreach($json->data as $val){
            $rap += $val->recentAveragePrice;
            $items += 1;
        }
        return [$rap, $items, $json->nextPageCursor];
    }
    function get_all_pages_for_asset_type($userid, $assettype){
        $keep_fetching = true;
        $cursor = '';
        $page = 1;
        $rap = 0;
        $items = 0;
        while($keep_fetching){
            $results = get_page($userid, $assettype, $page, $cursor);
            $rap += $results[0];
            $items += $results[1];
            if(!$results[2] || empty(trim($results[2]))){
                // nextPageCursor empty, break
                $keep_fetching = false;
                break;
            }else{
                // nextPageCursor present, continue & fetch next page...
                $page+=1;
                $cursor = $results[2];
            }
        }
        return [$page, $items, $rap];
    }
    $userid = htmlentities($_GET['userid'], ENT_QUOTES);
    $assettypes = array("Hat", "Face", "Gear", "HairAccessory", "FaceAccessory", "NeckAccessory", "ShoulderAccessory", "FrontAccessory", "BackAccessory", "WaistAccessory");
    $rap2 = 0;
    $exec_time_start = microtime(true);
    $items_total = 0;
    $pages_total = 0;
    foreach($assettypes as $assettype){
        $results = get_all_pages_for_asset_type($userid, $assettype);
        $pages_total += $results[0];
        $items_total += $results[1];
        $rap2 += $results[2];
    }
    echo json_encode([
        'total_rap' => $rap2,
        'items' => $items_total,
        'pages' => $pages_total,
        'rendertime' => (microtime(true) - $exec_time_start)
    ]);
?>

更高级的解决方案(并发和更快)将触发多个动态承诺链,每个AssetType 1,它们将在各自的循环中动态运行,直到nextPageCursor为空,特定的AssetType的承诺链可以解决。一旦所有10个承诺链完全解决,(使用GuzzleHttp\Promise\Settle,就像JS的Promise.all(promises[])一样,最终计算完成并返回。

我已经在这里向Github发布了两个解决方案的完整代码:https://github.com/jakedowns/roblox-api-fetch-all-pages

index.php文件包括:

  1. 您的原始问题示例代码
  2. 基于while-loop的基本解决方案
  3. 复杂的Guzzle,Promise,CurlMulti方法
  4. 方法之间的一些基本时间比较:

    // ~4 seconds for 10 pages of 607 items (incomplete)
    original_example();
    
    // ~15 seconds for 31 pages of 2483
    basic_solution();
    
    // ~4 seconds for 31 pages of 2483 items
    advanced_solution();