可以覆盖自身内的foreach变量参数吗?

时间:2014-09-08 13:15:24

标签: php foreach twitch

我制作了一个使用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++;
    }

结束回应(没有名字被成功抓取): enter image description here

以下是$ json-&gt;的API部分:

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

3 个答案:

答案 0 :(得分: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));

答案 1 :(得分: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循环迭代结束时再做一次请求。

答案 2 :(得分:0)

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

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

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

<form action="" method="post">
                        <div class="marginTop form-group col-xs-12 col-sm-10 col-md-8 col-lg-6">
                            <input class="form-control" 
                                   type="email" 
                                   id="email"
                                   name="email" 
                                   placeholder="example@email.com">
                        </div> 
                        <div class="col-xs-12">
                            <button class="btn btn-default"
                                    type="submit"
                                    id="emailVerzenden"
                                    name="emailVerzenden"><?php echo $class->verzenden ?>
                            </button>
                        </div>
                    </form> 

无论如何 - 这只是允许你在不需要担心索引的情况下浏览游标 - 除非你出于某种原因特别想要它们。如果您正在使用泛型,那么您可以毫无问题地重复使用此代码。在下面找到一个通用示例。要使其可重复使用,您需要做的就是在&lt;&gt;中传递正确的类。方法调用。可以用于任何用于解析json数据的自定义类。这基本上是'createfollowerroot()'在上面的代码中,除了硬类型。

我也知道它在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
            }
        }