How to Pull a Twitter Feed Into Your Site Using PHP, MySQL, and the Twitter API
These days, Twitter feeds are everywhere, it seems. There are a million widgets, gadgets, and doohickeys that let you pull your Twitter posts onto your site, but the problem with all of them is that they're tough to customize. Suppose you want to be able to grab from multiple Twitter feeds? Or omit any tweets that contain URLs or certain flagged words? With those widgets, it's tough to do. That's why I figured out how to gather my Tweets on my own. I imagine a few other people out there will want to do the same. Hopefully this tutorial will save them (you) some time. Enjoy. And, leave any related suggestions/code/questions in the comments at the bottom.
- Create a MySQL table to store the tweets. The Twitter API has limits set on how often you can ping it. So, you'll need to store your tweets locally and update it periodically using a cron job. The first step in doing that is creating a place to store the data. Copy and paste the following MySQL code into phpMyAdmin (or whatever tool you use to connect to your MySQL server):
CREATE TABLE `twitter` ( `id` BIGINT UNSIGNED NOT NULL , `screen_name` VARCHAR( 255 ) NOT NULL , `time` BIGINT UNSIGNED NOT NULL , `text` VARCHAR( 255 ) NOT NULL , `hidden` CHAR( 1 ) NOT NULL , PRIMARY KEY ( `id` ) );
- Create a cron job that grabs the tweets from the Twitter API and stores it in your table. Create a PHP file (named /cron/twitter-update.php in this example) with the following code:
<?php require_once 'db-functions.inc.php' ; //custom database functions function saveTweets($screen_name) { global $link; $screen_name = dbEscape(strtolower(trim($screen_name))); if (!$screen_name) { echo "<p><strong>Error: No screen name declared.</strong></p>\n"; return false; } $row = dbGetRow("SELECT `id` FROM `twitter` WHERE `screen_name`='$screen_name' ORDER BY `id` DESC LIMIT 1"); $last_id = $row['id']; $url = "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=$screen_name" ; if ($last_id) { $url .= "&since_id=$last_id" ; } $ch = curl_init($url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE); $xml = curl_exec ($ch); curl_close ($ch); $affected = 0; $twelement = new SimpleXMLElement($xml); foreach ($twelement->status as $status) { $text = dbEscape(trim($status->text)); $time = strtotime($status->created_at); $id = $status->id; dbQuery("INSERT INTO `twitter` (`id`,`screen_name`,`time`,`text`,`hidden`) VALUES ('$id','$screen_name','$time','$text','n')"); $affected = $affected + dbAffectedRows(); } return "<p>".number_format($affected)." new tweets from $screen_name saved.</p>\n" ; } echo saveTweets('inkplant'); ?>
- Add the cron job to your crontab file. You need to let your server know how often to run this new file that you created. In the example below, it will run every 5 minutes. Go to your Unix shell and type crontab -e and then add the following line:
*/5 * * * * /usr/bin/php /cron/twitter-update.php
Note: The settings your server uses to run cron jobs can vary a lot. Check with your server admin for instructions specific to your machine if the example above doesn't work. - Pull the databased content to your web page. Place the following code within the body of your PHP page where you'd like to display the Twitter feed. Of course, you can customize here as much as you want...
<?php echo "<ul class=\"twitter_feed\">\n" ; $result = dbQuery("SELECT * FROM `twitter` WHERE `screen_name`='inkplant' AND `hidden` != 'y' ORDER BY `time` DESC LIMIT 10"); while ($row = dbGetRow($result)) { $text = stripslashes($row['text']); $time = $row['time']; echo " <li><span class=\"twitter_time\">".date('M j, Y, g:i a',$time)."</span> · $text</li>\n" ; } echo "</ul>\n" ; ?>
This post was published on Sunday, August 22nd, 2010 by Robert James Reese in the following categories: MySQL, PHP, Twitter. Before using any of the code or other content in this post, you must read and agree to our Terms & Conditions.
39 Comments
echo saveTweets('twitterfeed1');
echo saveTweets('twitterfeed2');
But, if you decide to make it automatic, I'd recommend just adding another MySQL query at the end of the saveTweets() function that deletes the previous tweets. That way, you make sure that you get the new ones before deleting the old.
$save = array();
$result = dbQuery("SELECT `id` FROM `twitter` WHERE `hidden` != 'y' ORDER BY `time` DESC LIMIT 20");
while ($row = dbGetRow($result)) {
$save[] = $row['id'];
}
dbQuery("DELETE FROM `twitter` WHERE `id` NOT IN ('".implode('','',$save)."')");
Double check that before you use it. I just wrote it and haven't tested it.
$save = array();
$result = dbQuery("SELECT `id` FROM `twitter` WHERE `screen_name`='$screenname' ORDER BY `time` DESC LIMIT 20");
while ($row = dbGetRow($result))
{
$save[] = $row['id'];
}
$savelist = implode(",", $save);
dbQuery("DELETE FROM `twitter` WHERE `screen_name`='$screenname' AND `id` NOT IN ('$savelist')");
*this one only saves the one latest tweet so it's good for periodic cleaning out of the db
Thanks for all your help!
I am getting this error.
Call to undefined function dbconnect()
I have tried a few different things but nothing seems to be working.
Thanks
Thanks in advance.
require_once './db-functions.inc.php';
And make sure that line is at the top of the code.
Thanks again in advance.
Everything work great now.
Thanks for all your help.
Thanks very much!
echo saveTweets('teamcoco');
Only change I made was to run the output through a few regular expressions to turn hastags, urls and @usernames into hyperlinks:
$text = preg_replace('/(https{0,1}://[w-./#?&=]*)/', '$1', $text);
$text = preg_replace('/@(w+)/', '@$1', $text);
$text = preg_replace('/s#(w+)/', ' #$1', $text);
Has this something to do with the way of authing?
Right now I am using wget and running a cron job. But it is for one twitter feed search.
I am using this :
wget -O /home/myusername/public_html/yahooapi/wget-twitter.xml -q -t 1 http://search.twitter.com/search.atom?q=LSU
But I don't want to do a seperate cronjob for each search it would kill my shared hosting.
So it would be great if I can do many searches for 1 cron job.
Do u think this is possible?
Thanks
Thanks!
$screen_name = trim(strip_tags($_GET['screen_name']));
echo saveTweets($screen_name);
Any idea? Do they need to be escaped or anything?
Great tutorial! I'm having a problem getting this running though.
Here are the errors that I'm getting:
Warning: SimpleXMLElement::__construct() [simplexmlelement.–construct]: Entity: line 85: parser error : Entity 'copy' not defined in /home/riktig/public_html/lanternclub.com/twitter_update.php on line 22
Warning: SimpleXMLElement::__construct() [simplexmlelement.–construct]: © 2011 Twitter in /home/riktig/public_html/lanternclub.com/twitter_update.php on line 22
Warning: SimpleXMLElement::__construct() [simplexmlelement.–construct]: ^ in /home/riktig/public_html/lanternclub.com/twitter_update.php on line 22
It seems to be having an issue with the SimpleXMLElement but I can't seem to figure this issue out.
Thanks for this - it was very useful.
Upon reading this I was wondering, is there a way of pulling all publicly available Tweets with a certain hashtag without using the Twitter API?
Leave a Comment