All you need for searching & showing tweets with PHP

drunken

Last Saturday I started to study Twitter API. My goal was to pull out some tweets with certain search operators using PHP and learn how to handle the received data. That’s exactly what I learned and this tutorial is for saving the trouble for you and getting started with Twitter API.

To be more specific, in this tutorial we are going to:

– Search tweets with certain operators
– Pull out the information we like from the data
– Re-arrange the information in to the web page (by that I mean we are going to show the tweets)

This is written completely step by step so your grandpa could feel like a hard core coder when following it, but I might get you lost somewhere. If so or you are a more advanced coder, you can find the full code at the end of the post.

1. Setting up your Twitter application

Before we can dive in to the code, you should head to Twitter developer page and setup your application. You need to authenticate your app before you can get access to Twitter data, so basically you can’t do anything before you get the keys. But you can read more about authentication for example in here. It’s not really in my focus at this post, even though we need to go through those steps. But we’ll get back to that later. Now go and setup your app, my young padawan.

Already done? The next task is

2. Authenticating your app

I searched for couple of hours and I couldn’t find any decent tutorials or instructions how the application is meant to be authenticated. Quite frankly I don’t think there is much of those. Twitter advices to use ready made libraries for that.

I decided to use library named Codebird, which is very well documented. Download the library and place it where ever you like under your server root folder. I decided to put it in the folder named lib. Don’t forget to place the .pem file in the same folder. Otherwise the library won’t work.

Now open your Notepad++, Dreamweaver, Text Wrangler (which I prefer) or whatever editor you like to use. Create a new .php file and type

<head> <meta charset="utf-8"> </head>
<?php

    require_once ('lib/codebird.php');

    $cb = \Codebird\Codebird::getInstance();
    $cb->setConsumerKey('YourConsumerKeyHere', 'YourConsumerSecretHere');
    $cb->setToken('YourAccessTokenHere', 'AndYourAccessTokenSecretGoesRightHere');

?>

Let’s look at the code:

require_once ('lib/codebird.php');

Require once adds the library.

$cb->setConsumerKey('YourConsumerKeyHere', 'YourConsumerSecretHere');
$cb->setToken('YourAccessTokenHere', 'AndYourAccessTokenSecretGoesRightHere');

Okay, so if you can’t connect the dots by yourself here, let me explain. You can find your your keys and tokens from the Twitter application page, which you just created. Open “oauth” tab and you should see this:

keys_n_tokens

Copy and paste the right keys in to the right place inside your code. Save and open the .php file you created in your browser. If you did everything right, you should see nothing. However, if you want to be 100% sure, you can open the codebird.php and type this in to the third line:

print ("Yeah I'm here.");

Now when you save the file and refresh your browser you’ll see if codebird.php is loaded or not.

3. Searching for tweets

Add following lines to the code:

$params = array('q'=>'#kahvi','lang'=>'fi');    
$reply = (array) $cb->search_tweets($params);

$data = (array) $reply['statuses'];

print_r ($data);

Now when you save and refresh, you should see a mess like this:

Screen Shot 2014-01-29 at 10.54.57 PM

Yeah, it’s pretty intense, but at least you know your search was successful. It’s crazy how much data there is included in a one single tweet. One would think there is only 140 characters but no, there is location, name information about the tweeter… all kinds of stuff. We’ll examining that shortly, but at first let me explain what happens in the code:

$params = array('q'=>'#kahvi','lang'=>'fi');

Here you define the search terms. I’m searching #kahvi, which is Finnish word for coffee. Then I set the language to Finnish. You might want to change that to whatever language you speak.

$reply = (array) $cb->search_tweets($params);

This line tells Codebird to do the search and save the results to an array named reply.

$data = (array) $reply['statuses'];

Now at this point it would be pretty useful if you’re not completely unaware of how the arrays work. If that is the case, at least take a look of the PHP documentation covering the subject.

However, there is some stuff we don’t need stored in $reply, so we go through it and search for the “statuses”. In Twitter API language status actually means a tweet and all the metadata included. We store them inside an another array. Let’s call it “data”.

print_r ($data);

You can remove the print_r line now. You’ve seen what you’ve found already. Now we can start to think what to do with it.

4. Sorting out the data

As said above, there is quite a bit of data included in one Tweet. You can see the full list at Twitter API documentation. We’re gonna take only the most important parts, but first we have to do a small for loop:

$s = count($reply['statuses']);

for ($a = 0; $a < $s; $a++) {

    $status = $data[$a];
    echo $status->user->name . " (@" . $status->user->screen_name . ")";

}

After including this inside your code you should see a list of tweeters. Those are the guys who’s tweets you found earlier!

I use the for loop to separate the tweets from each other, but because explaining the method is not the point of this post, I’m going to move on. There is plenty of material covering it but if you need further assistance with it, please reply in comment field.

$status->user->name and $status->user->screen_name gets us the name and alias of tweeter. We could easily also get the content of the tweet now, but I think we should pay attention to one thing before going further.

5. Separating tweets and re-tweets

The one thing very characteristics for Twitter is re-tweeting. We could search for the tweets and print them out not really giving a shit if the tweets are originals or not. If we do so, we get content in a form like this:

@NameOfTheRetweeter: RT @NameOfTheOriginal Aaaand this is the tweet.

However I’m not satisfied with this solution. It’s a bit ugly way to show the tweets. I prefer this way:

@NameOfTheRetweeter retweeted @NameOfTheOriginal: Aaaand this is the tweet.

Got my point? If not, you understand me later. Just keep on going.

To achieve what we want, we have to do a little condition with if statement. Now make the for loop look like this:

    for ($a = 0; $a < $s; $a++) {

        $status = $data[$a];

        if ($status->retweeted_status != null) {

            echo $status->user->name . " (@" . $status->user->screen_name . ") retweeted:"; 
            echo "<br/>";
            $b = $status->retweeted_status;

        }

        else {

            $b = $status;

        }

    }

At first the function checks if we are dealing with the re-tweet or not:

if ($status->retweeted_status != null) {

If that’s the case, we print text like “Tweeting Dude (@TweetingDude) retweeted”:

echo $status->user->name . " (@" . $status->user->screen_name . ") retweeted:";

The contents of the original are stored inside an array called “retweeted_status”. We put the contents of the original tweet to the variable b:

$b = $status->retweeted_status;

If the tweet is original, we don’t really need to dig the data any deeper:

$b = $status;

You might wonder, why I’m storing the data in variable b even if it’s unchanged. Reason is that it’s easier to form functions later on when we are only having one variable name at the point where we’re…

6. Printing out the tweets (finally)

We use simple echo functions to create the tweets. Add this inside the for loop:

echo "<br/>";
echo "<img src=\"" . $b->user->profile_image_url . "\"/> " . $b->user->name . " (@" . $b->user->screen_name . ")" . " at " . $b->created_at;
echo "<br/>";
echo $b->text;
echo "<div style=\"height: 1px; width: 100%; background-color: orange;\"></div>";

With this line

echo "<img src=\"" . $b->user->profile_image_url . "\"/> " . $b->user->name . " (@" . $b->user->screen_name . ")" . " at " . $b->created_at;

we search the profile image, the name, alias and the timestamp.

This line is the most important one for us:

echo $b->text;

Text means actually the content of the tweet.

echo "<div style=\"height: 1px; width: 100%; background-color: orange;\"></div>";

The last line is just a divider, so you can see where the last tweet ends and the next one starts.

Now we are pretty far, but there is one thing missing.

7. Showing the images

As you might have noticed, some of the tweets seem to be empty. They necessarily aren’t. We just haven’t searched for the images yet.

Add this code inside the for loop

if ($b->entities->media[0] != null) {

    $media = $b->entities->media[0];
    echo "<br/>" . "<img src=\"" . $media->media_url_https . "\">";

}

This function checks if there is images included. If so, we obviusly want to show them.

Now we are done! If everything went well, the full code should look somewhat like this:

<head> <meta charset="utf-8"> </head>
<?php

    require_once ('lib/codebird.php');

    $cb = \Codebird\Codebird::getInstance();
    $cb->setConsumerKey('YourConsumerKeyHere', 'YourConsumerSecretHere');
    $cb->setToken('YourAccessTokenHere', 'AndYourAccessTokenSecretGoesRightHere');

    $params = array('q'=>'#kahvi','lang'=>'fi');    
    $reply = (array) $cb->search_tweets($params);

    $data = (array) $reply['statuses'];
    $s = count($reply['statuses']);

    for ($a = 0; $a < $s; $a++) {

        $status = $data[$a];

        if ($status->retweeted_status != null) {

            echo $status->user->name . " (@" . $status->user->screen_name . ") retweeted:"; 
            echo "<br/>";
            $b = $status->retweeted_status;

        }

        else {

            $b = $status;

        }

        echo "<br/>";
        echo "<img src=\"" . $b->user->profile_image_url . "\"/> " . $b->user->name . " (@" . $b->user->screen_name . ")" . " at " . $b->created_at;
        echo "<br/>";
        echo $b->text;
        echo "<div style=\"height: 1px; width: 100%; background-color: orange;\"></div>";

        if ($b->entities->media[0] != null) {

                $media = $b->entities->media[0];
                echo "<br/>" . "<img src=\"" . $media->media_url_https . "\">";

        }

    }

?>

From now on it’s easy for you to toss in some CSS and present your tweets in an appealing way.

Was there something you didn’t understand? The code saved your ass? You know 1000+ times better way to do this? My language skills sux? Please leave feedback.

Advertisements

6 thoughts on “All you need for searching & showing tweets with PHP

  1. Guy, brilliant explanation! Just a doubt: I’m trying to search for two hashtags at the same time. I tried a couple of things but I couldn’t do it. Do you have idea about how to do it?

    I tried defining:
    $params = array(‘q’=> ‘#coffe or #milk’)

    and $params = array(‘q’=> array(‘#coffe, #milk’))

    Nothing worked…

    • First of all, sorry for the late reply, I’ve been on a long vacation.

      Have you figured this one out yet? First thing which crosses my mind is that maybe “or” should be “OR”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s