Build a local cache of all streams from Twitch.TV API I am trying to cache the entirety of streams from Twitch.TV public API with the following code. It is successful but takes almost a full minute to execute so I am wondering if it's my code or just the speed of the API delivery. In any case, because it is my first PHP script (and really, I'm new in general), I am certain there are logical missteps and performance crushing flows and I would appreciate some review!  

The function buildPages() is mainly what is in question for this post.  

The data is always returned as json and I dump it all to disk for local testing. Suggestions on how to implement an accelerator for this collection are welcomed since I've never played with one before. APC or Memcache(d)? I have a lot of reading to do..  

Also, I am not certain why the lines

$length = count($page-&gt;streams);
$length = count($page['streams']);


had to be written as such. stdClass Object versus ArrayAccess? I don't really understand why I would get errors when trying to use the same accessor in the case of my code. Is $page not always an associative array created from the JSON data?

&lt;?php

$base = 'https://api.twitch.tv/kraken/';

$thatlist = array(
    'games'=&gt; array(
        'url'=&gt;'games/top',
        'params'=&gt; array(
            'limit'=&gt;100,
            'offset'=&gt;0
        )
    ),
    'featured'=&gt;array(
        'url'=&gt;'streams/featured',
        'params'=&gt;array(
            'limit'=&gt;100,
            'offset'=&gt;0
        )
    ),
    'summary'=&gt;array(
        'url'=&gt;'streams/summary',
        'params'=&gt;array(
            'limit'=&gt;100,
            'offset'=&gt;0
        )
    ),
    'teams'=&gt;array(
        'url'=&gt;'teams',
        'params'=&gt;array(
            'limit'=&gt;100,
            'offset'=&gt;0
        )
    )
);

foreach($thatlist as $key =&gt; $val) {

    $fullurl = $base . $val['url'];

    foreach($val['params'] as $foo =&gt; $bar){

        $fullurl .= '?' . $foo . '=' . $bar;

    }

    $quicklist[$key] = json_decode(file_get_contents($fullurl), true);

}

function buildPages() {

    $streams = array();
    $offset = 0;

    $page = json_decode(file_get_contents("https://api.twitch.tv/kraken/streams?offset=".$offset."&amp;limit=100", true));

    $length = count($page-&gt;streams);

    array_push($streams, $page);

    // request always returns 100 items unless at the end of live data
    while($length = 100) {

        $index = count($streams);
        $offset = $index * 100;

        $page = json_decode(file_get_contents("https://api.twitch.tv/kraken/streams?offset=".$offset.'&amp;limit=100'), true);

        $length = count($page['streams']);

        echo "Index: ".$index."&lt;br/&gt;";
        echo "Length: ".$length."&lt;br/&gt;";

        array_push($streams, $page);

    }

    var_dump($streams);
    $sd = fopen('streams-dump.json', 'w');
    fwrite($sd, json_encode($streams));
    fclose($sd);

}

$qld= fopen('quicklist-dump.json', 'w');
fwrite($qld, json_encode($quicklist));
fclose($qld);

buildPages();

?&gt;
At a glance I'd be almost certain that the network requests are your bottleneck here.

If you think of the difference between some code interpreted and run locally vs instantiating a network connection, sending the request, waiting for their servers to run their code and the network latency to respond I think it's safe to say the network time is going to be the bottleneck. Particularly when you consider you're doing hundreds of network connections.

To speed this up I'd say Memcached is your best option. APC is also pretty useful, but not specifically for this. The general idea would be to check if you have cached results and if not generate the data you need and stick it in memcached and return the data. Then, in separate code, take that data and format it as required.

Roughly speaking:

if (Cache-&gt;check('key-to-your-data'))
{
    $twitchTvData = Cache-&gt;get('key-to-your-data');
}
else
{
    $twitchTvScraper = new TwitchTvScraper();
    $twitchTvData = $twitchTvScraper-&gt;scrape();
    Cache-&gt;set('key-to-your-data', $twitchTvData);
}

echo PageBuilder-&gt;buildFoo($twitchTvData);


In this example I've split out the caching, scraping of content and building of pages into separate classes. Having these all in the one place is a recipe for disaster/embarrassingly silly bugs.

Also, it's worth noting that hitting someone's API repeatedly like this is usually considered bad form and if they're monitoring for such activity you could get blocked. It might be worth looking into a package that can scrape pages with a rate limit. I'm sure there are a few out there. If you don't need the data refreshed often you could just use wget and read the files from a directory locally.

Finally; it's fine to stick some html together when you're learning a new language but in practice it isn't the way to go. Typically you use an off the shelf framework that can build HTML from templates. Something like, Zend, Laravel etc. (http://www.phpframeworks.com/ for more).

Having said all that, if you're just learning to code, don't take this all on at once! Take it piece by piece and save early, save often.