Topic: Twitter & PHP

OK, so I've been working on a simple script that pulls my twitter status/time posted from twitter.com and displays it in my website.  Here is the code that I have so far:

// http://twitter.pbwiki.com/RelativeTimeScripts
function get_elapsedtime($time) {
    $gap = time() - $time;
    if ($gap < 5) {
        return 'less than 5 seconds ago';
    } else if ($gap < 10) {
        return 'less than 10 seconds ago';
    } else if ($gap < 20) {
        return 'less than 20 seconds ago';
    } else if ($gap < 40) {
        return 'half a minute ago';
    } else if ($gap < 60) {
        return 'less than a minute ago';
    }
    $gap = round($gap / 60);
    if ($gap < 60)  { 
        return $gap.' minute'.($gap > 1 ? 's' : '').' ago';
    }
    $gap = round($gap / 60);
    if ($gap < 24)  { 
        return 'about '.$gap.' hour'.($gap > 1 ? 's' : '').' ago';
    }
    return date('h:i A F d, Y', $time);
}

function twitter_status($username) {

    $twitter_url = "http://twitter.com/statuses/user_timeline/$username.xml?count=1";
    $buffer = file_get_contents($twitter_url);    
    $xml = new SimpleXMLElement($buffer);
    $status_item = $xml -> status;
    $status =  $status_item -> text;
    $created_at = get_elapsedtime(strtotime($status_item -> created_at));
        
    return "\"$status\"<br/><span class='twitter_time'>$created_at</span>";
}

$twitter = twitter_status("falkencreative"); 

This works... as long as I can access my Twitter account. It looks like after 100 requests in an hour, the script dies with this PHP error and causes most of my page to stop displaying:

[30-Dec-2008 13:12:46] PHP Warning:  file_get_contents(http://twitter.com/statuses/user_timeline/falkencreative.xml?count=1) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
in /Applications/MAMP/htdocs/Ver 2.0/Development/resources/includes/incl_functions.php on line 66
[30-Dec-2008 13:12:46] PHP Fatal error:  Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /Applications/MAMP/htdocs/Ver 2.0/Development/resources/includes/incl_functions.php:67
Stack trace:
#0 /Applications/MAMP/htdocs/Ver 2.0/Development/resources/includes/incl_functions.php(67): SimpleXMLElement->__construct('')
#1 /Applications/MAMP/htdocs/Ver 2.0/Development/resources/includes/incl_sidebar.php(8): twitter_status()
#2 /Applications/MAMP/htdocs/Ver 2.0/Development/portfolio.php(110): include('/Applications/M...')
#3 {main}
  thrown in /Applications/MAMP/htdocs/Ver 2.0/Development/resources/includes/incl_functions.php on line 67

Line 67 is this line: "$xml = new SimpleXMLElement($buffer);"

Regularly, the XML that should be returned is this:

<statuses type="array">
−
<status>
<created_at>Tue Dec 30 21:37:30 +0000 2008</created_at>
<id>1086676756</id>
<text>OK, just populating my portfolio left...</text>
−
<source>
<a href="http://iconfactory.com/software/twitterrific">twitterrific</a>
</source>
<truncated>false</truncated>
<in_reply_to_status_id/>
<in_reply_to_user_id/>
<favorited>false</favorited>
<in_reply_to_screen_name/>
−
<user>
<id>9250782</id>
<name>Benjamin Falk</name>
<screen_name>falkencreative</screen_name>
<location>Orange County, CA</location>
−
<description>
Benjamin Falk | student, designer and frontend developer.
</description>
−
<profile_image_url>
http://s3.amazonaws.com/twitter_production/profile_images/57732233/getavatar_normal.jpeg
</profile_image_url>
<url>http://www.falkencreative.com</url>
<protected>false</protected>
<followers_count>16</followers_count>
</user>
</status>
</statuses>

But when I get the error, this is what I get:

<hash>
<request>/statuses/user_timeline/falkencreative.xml?count=1</request>
−
<error>
Rate limit exceeded. Clients may not make more than 100 requests per hour.
</error>
</hash>

Is there any way I could add some sort of error checking (perhaps through try/catch?) to catch the error and return an error message, instead of generating the PHP error? I've tried playing around with it myself, but it's going over my head.

Benjamin Falk | Falken Creative : Twitter
Skills: Photoshop, Illustrator, HTML, CSS, jQuery, PHP and CodeIgniter

Vote up Vote down

Re: Twitter & PHP

You should be able to wrap the function call in a try/catch and then set it to catch any error. This way, you can display a nice friendly message to users.

If you knew the twitter API, you could get a list of errors it throws, then create a more fine-tuned error handling routine. If not, just do a catch all and you should be fine.

Stefan

Practical web design training videos: KillerSites University

Vote up Vote down

Re: Twitter & PHP

Here's what I eventually settled on... based mostly on a code sample from http://abeautifulsite.net/notebook.php?article=75

-- Caches the tweets, refreshes the cache every 10 minutes (reduces load on Twitter.com, which only allows 100 calls per hour)
-- parses URLs properly, and if the tweet includes a URL, adds the link
-- Includes the time the tweet was posted, in a "two minutes ago" or "two hours ago" type format, rather than an exact time
-- Includes basic error checking

The object gets accessed like this:

$gettwitter = new twitter('twitterid#here');
echo $gettwitter->getStatus();

Class:

<?php

class twitter{
    const CACHE_FNAME = 'resources/twitter.status';
    
    function __construct($id,$addAnchors=true) {
        $this->id = $id;
        $this->addAnchors = $addAnchors;
        $this->status = $this->load();
    }
    
    private function load() {
        $ret = '';
        
        $life = (time() - filectime(self::CACHE_FNAME));
        if($life < (10*60) and $life > 0)
            $ret = trim(file_get_contents(self::CACHE_FNAME));
        
        return $ret;
    }
    
    private function save() {
        file_put_contents(self::CACHE_FNAME,$this->status);
    }

    function getStatus() {
        // fetch new status
        if(!strlen($this->status)){
            $this->status = $this->fetch();
            $this->save();
        }

        return $this->status;
    }
    
    // http://twitter.pbwiki.com/RelativeTimeScripts
    function get_elapsedtime($time) {
        $gap = time() - $time;
        if ($gap < 5) {
            return 'less than 5 seconds ago';
        } else if ($gap < 10) {
            return 'less than 10 seconds ago';
        } else if ($gap < 20) {
            return 'less than 20 seconds ago';
        } else if ($gap < 40) {
            return 'half a minute ago';
        } else if ($gap < 60) {
            return 'less than a minute ago';
        }
        $gap = round($gap / 60);
        if ($gap < 60)  { 
            return $gap.' minute'.($gap > 1 ? 's' : '').' ago';
        }
        $gap = round($gap / 60);
        if ($gap < 24)  { 
            return 'about '.$gap.' hour'.($gap > 1 ? 's' : '').' ago';
        }
        return date('h:i A F d, Y', $time);
    }
    
    private function fetch() {
        // init
        $c = curl_init();
        curl_setopt($c,CURLOPT_URL,"http://twitter.com/statuses/user_timeline/$this->id.xml");
        curl_setopt($c,CURLOPT_RETURNTRANSFER,1);
        
        // exec
        $src = curl_exec($c);
        curl_close($c);
        preg_match('/<text>(.*)<\/text>/',$src,$m);
        $status = @htmlentities($m[1]);
        
        // check for errors, in case request is over 100 request limit
        if(!$status) { return "<strong>Error: </strong>Error connecting to Twitter!"; }
        
        // add anchors?
        if($this->addAnchors)
        $status = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]","<a href=\"\\0\">\\0</a>",$status);
        
        // get time
        preg_match('/<created_at>(.*)<\/created_at>/',$src,$m);
        $created_at = $this->get_elapsedtime(strtotime($m[1]));
        
        return $status . "<br/>" . $created_at;
    }
}

?>
Benjamin Falk | Falken Creative : Twitter
Skills: Photoshop, Illustrator, HTML, CSS, jQuery, PHP and CodeIgniter

Vote up Vote down

Re: Twitter & PHP

There are a couple plugins for cmsms to feed your tweets too.

Vote up Vote down