Parsing and Embedding Twitter Feeds in PHP
Twitter feeds can be obtained in XML with this URL scheme:
http://twitter.com/statuses/user_timeline/$username.xml?count=$count
Where $username is the twitter user's name and $count is how far back you want to go.
If your environment allows url_fopen you can load the whole thing directly into an object with simplexml_load_file().
Portability is good and allow_url_fopen is arguably very dangerous. For the sake of brevity let's rip this class from the PHP manual's fopen() comments:
class HTTPRequest { var $_fp; // HTTP socket var $_url; // full URL var $_host; // HTTP host var $_protocol; // protocol (HTTP/HTTPS) var $_uri; // request URI var $_port; // port // scan url function _scan_url() { $req = $this->_url; $pos = strpos($req, '://'); $this->_protocol = strtolower(substr($req, 0, $pos)); $req = substr($req, $pos+3); $pos = strpos($req, '/'); if($pos === false) $pos = strlen($req); $host = substr($req, 0, $pos); if(strpos($host, ':') !== false) { list($this->_host, $this->_port) = explode(':', $host); } else { $this->_host = $host; $this->_port = ($this->_protocol == 'https') ? 443 : 80; } $this->_uri = substr($req, $pos); if($this->_uri == '') $this->_uri = '/'; } // constructor function HTTPRequest($url) { $this->_url = $url; $this->_scan_url(); } // download URL to string function DownloadToString() { $crlf = "\r\n"; // generate request $req = 'GET ' . $this->_uri . ' HTTP/1.0' . $crlf . 'Host: ' . $this->_host . $crlf . $crlf; // fetch $this->_fp = fsockopen(($this->_protocol == 'https' ? 'ssl://' : '') . $this->_host, $this->_port); fwrite($this->_fp, $req); while(is_resource($this->_fp) && $this->_fp && !feof($this->_fp)) $response .= fread($this->_fp, 1024); fclose($this->_fp); // split header and body $pos = strpos($response, $crlf . $crlf); if($pos === false) return($response); $header = substr($response, 0, $pos); $body = substr($response, $pos + 2 * strlen($crlf)); // parse headers $headers = array(); $lines = explode($crlf, $header); foreach($lines as $line) if(($pos = strpos($line, ':')) !== false) $headers[strtolower(trim(substr($line, 0, $pos)))] = trim(substr($line, $pos+1)); // redirection? if(isset($headers['location'])) { $http = new HTTPRequest($headers['location']); return($http->DownloadToString($http)); } else { return($body); } } }
We also need to give the links anchors, so we'll modify Jonathan Sampson's clever little function to not shorten URLs since twitter already does this for us these days:
function auto_link_text($text) { $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#'; $callback = create_function('$matches', ' $url = array_shift($matches); $url_parts = parse_url($url); $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); $text = preg_replace("/^www./", "", $text); $last = -(strlen(strrchr($text, "/"))) + 1; return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text); '); return preg_replace_callback($pattern, $callback, $text); }
Here we go:
$username = "username"; $count = 5; $feed = "http://twitter.com/statuses/user_timeline/$username.xml?count=$count"; $r = new HTTPRequest($feed); $tweets = $r->DownloadToString(); $twitter_xml = simplexml_load_string($tweets); $tweet_data = ''; foreach($twitter_xml->status as $status_object) { $tweet_epoch = strtotime($status_object->created_at); $tweet_data .= "<div class=\"tweet\"><span class=\"tweet_date\">".date("F j g:ia", $tweet_epoch)."</span><div class=\"tweet_message\">".auto_link_text($status_object->text)."</div></div>"; } print($tweet_data);
Comments
Thanks for that code snippet. It is working perfectly on my site.