
This write-up will go through the process of displaying your Twitter tweets on a web page using a little bit of PHP. Learn how to read your Twitter RSS Feed, Cache it and then display it.
Sure, you can probably use a widget, but, maybe you want to do something custom or maybe build your own widget.
Getting Your Twitter RSS Feed
First you will want to find your Twitter RSS feed link, copy the link location as you will use this in the code below. My RSS link looks like this:
http://twitter.com/statuses/user_timeline/18060713.rss
The Solution
Here is the code, I’ll explain the different parts below: [+ show code]
Taking it Step By Step
When using the code above, there are four key variables which you can adjust: $url is your twitter feed url, $cache_expire is the amount of time (in seconds) that the twitter feed will be remembered, $info_file and $cache_file are the data files used by the script to remmeber the Twitter feed, you probably will not need to change the location of these files.
$url = 'http://twitter.com/statuses/user_timeline/18060713.rss'; $cache_expire = 3600; // in seconds $ts = time(); $info_file = 'tmp-info.txt'; $cache_file = 'tmp-'.$ts.'.xml';
Lets go through how the script does its thing: first it trys to open the “info” file and get some information about the “cache” file.
// current info $info = unserialize(@file_get_contents($info_file));
Then the script checks if the cache files have expired. The if statement basically reads like this: “if there is no info or the current time is greater than when the cache was set to expire” …
if (empty($info) OR $ts > ($info['cache_ts']+$cache_expire))
Lets first explore if the statement is FALSE: this means that the cache has not expired yet. This is the simplest scenario, the script simply reads the cache file and gets the content.
$content = file_get_contents($info['cache_file']);
However, if the statement is TRUE, the script will get your latest tweets from Twitter (it uses CURL to request the feed as most servers have it enabled).
$ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); $content = curl_exec($ch); curl_close($ch);
The script confirms the content with a simple check, basically looking for the presence of a specific XML element. If it finds it, it assumes that all is OK and writes the contents to a file. Additionally, the old cache file is removed.
// if a description tag is present we're OK
if (preg_match('/<description>/iS',$content))
{
file_put_contents($cache_file,$content);
@unlink($info['cache_file']);
}
If the check fails, the script assumes that some sort of error has occured. Instead of writing any new data, the script gets the old data and resets the “info” file to be checked again at a new expire time (giving any errors time to resolve itself).
// known error strings: "over capacity", "rate limit exceeded"
// else if a description tag is not present something is wrong
else
{
// use current cache until errors resolve itself
$cache_file = $info['cache_file'];
$content = file_get_contents($info['cache_file']);
}
// update next cache time and cache file name
file_put_contents($info_file,serialize(array('cache_ts'=>$ts,'cache_file'=>$cache_file)));
Once the script has the RSS content it needs and all the cache files have been updated, it then loops the XML content and creates an array to be used somewhere on the page.
$feed = array();
$doc = new DOMDocument();
$doc->loadXML($content);
foreach ($doc->getElementsByTagName('item') as $node)
{
array_push($feed, array
(
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => preg_replace('/^\w+:/i','',$node->getElementsByTagName('description')->item(0)->nodeValue),
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
));
}
Outputting The Twitter Feed
With the array that was created, looping the feed content is straight forward, here is an example of outputting the feed to the page (in this example we output only the most recent 5 tweets):
<?php if (is_array($feed)): ?> <ul> <?php array_splice($feed,5); ?> <?php foreach ($feed as $item): ?> <li><?php echo linkify_tweet($item['desc']); ?></li> <?php endforeach; ?> </ul> <?php endif; ?>
You may have also noticed that the linkify_tweet function being used in this example, it basically makes URLs, usernames and hashtags into clickable links.
function linkify_tweet($v)
{
$v = ' ' . $v;
$v = preg_replace('/(^|\s)@(\w+)/', '\1@<a href="http://www.twitter.com/\2">\2</a>', $v);
$v = preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2">\2</a>', $v);
$v = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t<]*)#ise", "'\\1<a href=\"\\2\" >\\2</a>'", $v);
$v = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r<]*)#ise", "'\\1<a href=\"http://\\2\" >\\2</a>'", $v);
$v = preg_replace("#(^|[\n ])([a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $v);
return trim($v);
}

@Brent, what should be happening is that the old
tmp-[TIMESTAMP].xmlgets deleted when a new one is written (but at all times there are two files,tmp-info.txtandtmp-[TIMESTAMP].xml) … what are you seeing?