We will be utilizing the statuses/user_timeline method of the Twitter REST API. Basically, this is a special URL that returns the requested data in the requested format. In this case, we will request the user_timeline as XML, so our URL looks like: "http://twitter.com/statuses/user_timeli ... e=username"[/b].
All we need to do is write a PHP script that fetches the URL and then parses the XML that it receives. We should also cache the results so we don't spam Twitter with a request every time someone views your page and exceed the limit. My caching method of choice it to store the data in a MySQL database, since it is most widely available, so let's create the needed tables now:
Code: Select all
CREATE TABLE `twitter` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`twid` bigint(32) NOT NULL,
`text` varchar(256) NOT NULL,
`time` bigint(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `twid` (`twid`)
);
CREATE TABLE `twitter_status` (
`twid` bigint(32) NOT NULL,
`time` bigint(11) NOT NULL
);
INSERT INTO `twitter_status` (`twid`, `time`) VALUES (0, 0);
Fetching the Data
Now we're going to create a function that grabs a supplied user's timeline and returns a list of updates, each as an array of update ID, text, and date (as a Unix timestamp).
Code: Select all
function fetch_twitter_feed($user, $since = 0) {
$url = 'http://twitter.com/statuses/user_timeline.xml?screen_name=' . $user;
if($since > 0) {
$url .= '&since_id=' . $since;
}
$data = file_get_contents($url);
$xmlDoc = DOMDocument::loadXML($data);
$statuses = $xmlDoc->getElementsByTagName('status');
$updates = array();
if($statuses->length > 0) {
foreach($statuses as $status) {
$id = $status->getElementsByTagName('id')->item(0)->nodeValue;
$text = $status->getElementsByTagName('text')->item(0)->nodeValue;
$date = strtotime($status->getElementsByTagName('created_at')->item(0)->nodeValue);
$updates[] = array($id, $text, $date);
}
}
return $updates;
}
We add each result to an array and then return the array when the loop is complete. One more thing to note is that we convert the time to a Unix timestamp using strtotime.
Caching the Data
Now that we can fetch the data from the Twitter API, we need to add some form of caching so we don't access the API on every page view. So we'll wrap the function in another function that will handle the caching, and we'll call it get_twitter_feed:
Code: Select all
function get_twitter_feed($user, $reverse = true, $limit = 10) {
$db = new MySQLi('localhost', 'user', 'pass', 'database');
if($result = $db->query("SELECT * FROM `twitter_status`")) {
$row = $result->fetch_assoc();
$result->close();
if(time()-$row['time'] >= 300) {
$updates = fetch_twitter_feed($user, $row['twid']);
if(count($updates) > 0){
krsort($updates);
foreach($updates as $update) {
$id = $db->escape_string($update[0]);
$text = $db->escape_string($update[1]);
$time = $db->escape_string($update[2]);
$db->query("INSERT INTO `twitter` VALUES ('', '" . $id . "', '" . $text . "', '" . $time . "')");
}
$db->query("UPDATE `twitter_status` SET `twid` = '" . $id . "', `time` = '" . time() . "'");
}
else {
$db->query("UPDATE `twitter_status` SET `time` = '" . time() . "'");
}
}
}
$limit = $db->escape_string($limit);
$updates = array();
if($result = $db->query("SELECT * FROM `twitter` ORDER BY `id` DESC LIMIT " . $limit)) {
while($row = $result->fetch_assoc()) {
$updates[] = array('id' => $row['id'], 'twid' => $row['twid'], 'text' => $row['text'], 'time' => $row['time']);
}
$result->close();
if(!$reverse) {
krsort($updates);
}
return $updates;
}
return false;
}
The first part of the function checks the time from the twitter_status table, and if the time is more than 5 minutes (300 seconds) ago it will call fetch_twitter_feed to update the cache with any new entries, and then update twitter_status table with the time and last tweet ID. After checking/updating the cache, the function gets the data from the cache database and returns it as an array.
The get_twitter_feed function accepts 3 arguments: $user is the Twitter username, $reverse (optional, default true) decides whether to reverse sort the tweets from newest to oldest (just like Twitter does by default), and $limit (optional, default 10) specifies how many tweets to return.
Note: Be sure to replace the connection details at the top of this function with your own, or replace $db entirely with your own database implementation (here I use MySQLi).
Putting it all Together
Here's an example of this function in action:
Code: Select all
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Twitter Feed</title>
<style type="text/css">
<!--
#feed {
padding: 4px;
width: 400px;
border: 1px solid #333333;
}
#feed ul {
list-style-type: none;
margin: 0px;
padding: 0px;
}
#feed li {
display: block;
margin: 2px;
padding: 4px;
border: 1px solid #FFA119;
font-size: 0.9em;
}
#feed .caption {
font-size: 0.8em;
font-style: italic;
color: #333333;
}
-->
</style>
</head>
<body>
<div id="feed">
<ul>
<?php
if($updates = get_twitter_feed('robot.lk')) {
foreach($updates as $update) {
$text = htmlspecialchars($update['text']);
$time = date('m/d/y g:i A', $update['time']);
?>
<li>
<div class="caption"><?php echo $time; ?></div>
<?php echo $text; ?></li>
<?php
}
}
?>
</ul>
</div>
</body>
</html>