0

我制作了一个使用 Twitch API 的小脚本。API 只允许每个查询最多 100 个结果。我希望继续进行此查询,直到没有更多结果为止。

我背后的理论是运行一个 foreach 或 while 循环并每次将偏移量增加 1。

然而,我的问题是我无法更改其自身的 foreach 参数。有没有办法有效地执行这个而不导致无限循环?

这是我当前的代码:

 <?php
        $newcurrentFollower = 0;
        $offset=0;
        $i = 100;
        $json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
        foreach ($json->follows as $follow)
            {
                    echo $follow->user->name . ' (' . $newcurrentFollower . ')' . "<br>";
                    $newcurrentFollower++;
                    $offset++;
                    $json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
            }
    ?>

使用 While 循环:

while($i < $total)
    {
        $json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
            echo $json->follows->user->name . ' (' . $newcurrentFollower . ')' . "<br>";
            $newcurrentFollower++;
            $offset++;
            $i++;
    }

最终回应了这一点(没有成功抓住任何名字): 在此处输入图像描述

这是 $json->follows 的 API 部分:

https://github.com/justintv/Twitch-API/blob/master/v2_resources/channels.md#get-channelschannelfollows

4

3 回答 3

3

你可以使用这个:

$offset = 0;
$count = 1;

do {
    $response = json_decode(file_get_contents(
        'https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=100&offset='  . $offset
    )); 

    foreach($response->follows as $follow) {
        echo $follow->user->name . ' (' . ($count++) . ')' . "</br>";
    }   

    $offset+=25;

} while (!empty($response->follows));
于 2014-09-08T13:30:42.060 回答
1

你想在这里使用一个while循环,而不仅仅是一个foreach。基本上:

while (the HTTP request returns results)
{
   foreach ($json->follows as $follow)
   {
       do stuff
   }
   increment offset so the next request returns the next one not already processed
}

最棘手的部分是让 while 条件正确,以便在请求没有更多结果时返回 false,如果没有更多结果,将取决于 API 实际返回的内容。

同样重要的是,最简洁的方法是将 HTTP 请求作为 while 条件的一部分发生,但如果您需要对 JSON 返回进行一些复杂的计算以检查条件,您可以在循环之前放置一个初始 HTTP 请求,然后在每个 while 循环迭代结束时执行另一个请求。

于 2014-09-08T13:32:22.430 回答
0

问题是您只捕获键而不是值。将其放入数据结构中以访问信息。

老实说,我发现递归函数比迭代/循环方法更有效,然后在下一次调用之前更新数据表或列表。它很简单,使用游标,轻量级并且可以完成工作。如果您也使用泛型,则可重用。

这段代码将在 c# 中,但是我知道只需稍作更改,您就可以轻松地在 php 中使用它。

query = //follower object get request//
private void doProcessFollowers(string query)
        {

            HTTPParse followerData = new HTTPParse(); //custom json wrapper. using the basic is fine. Careful with your cons though
            var newRoot = followerData.createFollowersRoot(query); // generates a class populated by json
            if (newRoot[0]._cursor != null) 
            {
                populateUserDataTable(newRoot); //update dataset
                doProcessFollowers(newRoot[0]._links.next); //recurse
            }
        }

无论如何 - 这只是允许您滚动游标而无需担心索引 - 除非您出于任何原因特别想要它们。如果您正在使用泛型,则可以毫无问题地重用此代码。在下面找到一个通用示例。要使其可重用,您需要做的就是在方法调用的 <> 中传递正确的类。可以用于任何用于解析 json 数据的自定义类。这基本上就是上面代码中的“createfollowerroot()”,除了它是硬类型的。

我也知道它在 c# 中,主题是 php,对语法进行一些小的更改,你会很容易地让它工作。

无论如何希望这对某人有所帮助

通用示例:

public static List<T> rootSerialize<T>(JsonTextReader reader)
    {
        List<T> outputData = new List<T>();
        while (reader.Read())
        {
            JsonSerializer serializer = new JsonSerializer();
            var tempData = serializer.Deserialize<T>(reader);
            outputData.Add(tempData);
        }
        return outputData;
    }
于 2016-01-04T11:06:04.380 回答