RSS Valid
XHTML Valid
CSS Valid

Last.fm Widget With PHP

Wednesday, April 9th, 2008

Had a couple people suggest that I do a write up on how one might create a simple Last.fm widget with PHP. I’ll walk you through how I created the badge on typeoneerror. First of all, start by heading over to Audoscrobbler’s web services listings. Here you’ll find the XML files you need to get your playlist information. I’m currently pulling “recenttracks” so we’ll use that as an example. Under User Profile Data, click the XML link for “Recent Tracks.” To get your feed, just replace the user name with your last.fm username:

http://ws.audioscrobbler.com/1.0/user/YOUR_USER_NAME/recenttracks.xml

First thing we want to do is get the XML content from last.fm. You can either download this XML and update it manually or you could do something like use PHP’s curl method to do it. I use a cron job that runs a few times a day to pull the content down automatically. Here’s something like what my PHP (version 4) file the cron job is running looks like:

// -- cron.last.fm.php

// -- what playlist to get
$url = "http://ws.audioscrobbler.com/1.0/user/typeoneerror/recenttracks.xml";

// -- where to save it (this will need to be a writable folder ... 775 probably)
$filename = "/PATH/TO/WRITABLE/FOLDER/recenttracks.xml";

// -- get the content
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$data = curl_exec($ch);
curl_close($ch);

// -- write the content to the file
$fp = fopen($filename, 'w');
fwrite($fp, $data);
fclose($fp);

I have this all separated into functions, but it’s probably easier to see it all at once here. When this (or similar) file is run, the xml is saved locally as /WHEREEVER/THAT/WRITABLE/FOLDER/WAS/recenttracks.xml. Now I need to parse and display it. For parsing XML, I utilized miniXML.

// -- require the minixml class
require_once 'minixml/minixml.inc.php';

// -- what is the root node of the XML feed?
$lfmElement = "recenttracks";

// -- I only wanted to show 5 recent tracks
$show = 5;

// -- create xml structure
$xml = new MiniXMLDoc();

// -- for displaying the track num
$count = 0;

// -- try to parse it
if(!$xml->fromFile("/PATH/TO/WRITABLE/FOLDER/recenttracks.xml")) {
	// -- couldn't generate from file
} else {
	// -- get the root node
	$parent = $xml->getElement($lfmElement);
	
	// -- get the children of 'recenttracks'
	$list = $parent->getAllChildren();
	
	// -- display as list
	echo "<ul>\n";
	foreach ($list as $i => $child) {
		$item = array();
		$count++;
		if ($i>=$show) continue;
		$item['song'] = ucwords($child->getElement('name')->getValue());
		$item['url'] = $child->getElement('url')->getValue();
		$item['artist'] = ucwords($child->getElement('artist')->getValue());
		
		$item['display']  = '<span class="lastfm_count">' . $count . ".&nbsp;&nbsp;</span>\n";
		$item['display'] .= '<span class="lastfm_artist">' . $item['artist'] . "</span>\n - ";
		$item['display'] .= '<span class="lastfm_song">' . $item['song'] . "</span>\n";
		
		// -- echo out the track data here
		echo "<li>" . $item['display'] . "</li>";
	}
	echo "</ul>\n";
}

Basically, the above code loops through the XML and displays some of the data in a list. This can be a resource hog if you’re not careful! I also used this within the context of a smarty template. It parses the feed right around the same time the cron job is run and then uses smarty’s built in caching to generate a cached template. That way, until the next time the cron job is run, users will get the cached version.

Anyway, the possibilities for curling data are endless. It’s nice to avoid hitting those services too hard though, so instead of a direct fopen of xml, use curl instead. Instead of curling it every time, create a cron job to handle the curl periodically instead of hitting the service on every page load. And think about using a caching system like smarty for good measure as well.

One Response to "Last.fm Widget With PHP"

  1. Mark Eagleton says:
    April 10th, 2008 at 2:13 pm

Leave a Reply

Availability

We'd love to hear about your project! Please see the services and contact sections for more information or for work inquiries.