Stream Context

Just a quick post since this doesn’t seem to be very well covered, but could be useful to someone. You may be familiar with PHP’s file_get_contents function as a way to load the contents of a file into a variable. But it can also be used to get fetch the content of a site, by passing it a URL instead of a filepath.

This is fine, but what if the site whose URL you pass is down? cURL is probably more commonly used for fetching URL content which is understandable–it offers WAY more options and flexibility. One of the parameters you can specify is timeout. Recently I was writing a simple Drupal module to pull certain tweets from Twitter. Drupal’s caching would be used to hold retrieve the tweets for display, the cache updated via cron. While in development, we experienced one of Twitter’s seemingly regular periods of unavailability. With cURL, a preset timeout would solve this as the script wouldn’t be sitting waiting beyond our preset time limit, but cURL seemed like overkill for a simple fetch task where a quick file_get_contents would do. Could I specify a timeout for this function?

Well… yes.

Googling around, I couldn’t find anything immediately. It certainly wasn’t thorough research to be sure, but nothing jumped out (sorry if I missed anyone else doing the same thing I am here). But then I spotted a short comment in the PHP manual page for file_get_contents. The upshot is that you can specify a timeout by creating a stream context for the function like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
// Create the stream context
$context = stream_context_create(array(
    'http' => array(
        'timeout' => 3      // Timeout in seconds
    )
));

// Fetch the URL's contents
$contents = file_get_contents('http://tomdancer.com', 0, $context);

// Check for empties
if (!empty($contents))
{
    // Woohoo
    echo $contents;
}
else
{
    // A terrible, terrible disaster occurs
}

It may be worth noting that a Warning level error is generated on timeout but, of course, you won’t have error reporting enabled on a production site, right? Also, you could suppress it if you want, but that’s nasty so don’t.

Hope this is useful to someone else.