Using SimpleXML to get Weather Data from Yahoo!

Posted by Beau on Saturday, July 31st, 2010 at 4:51 pm

One of my clients is a baker, and the weather data is very important to him. Things like weather conditions and temperature affect buying patterns, and things like humidity affect water saturation in recipes. So, obviously, collecting the weather data for him to store so he can predict and refine his production was a goal of ours. I’d read a post on CSS Tricks in the past that showed how to collect weather information from Yahoo! Weather’s RSS API. I used his code as a base for creating a class so that I could collect the data we needed as an object. Read on for the code.

Below is the entirety of the class. You can paste it directly where you want to use it, but I like to keep my classes in their own file. I named mine “weather.class.php,” for example. I’m making the assumption you know a little bit of PHP.

/************************************************
/ Class: WeatherData
/ Author: Beau Watson
/ Version: 1.1
/ Description: Uses the Yahoo Weather RSS API to get
/  weather info for US cities by zip code
/ Special Thanks: Navarr Barnier (tech.navarr.me)
/************************************************/
class WeatherData
{
private $url; //variable to store our url
private $cond; //variable to store our condition
private $temp; //variable to store our temperature
private $humidity; //variable to store our humidity
private $units; //variable so we can set units f=farenheit, c=celsius
private $data; //array to hold our weather data from Yahoo
private $matches; //array to hold our regex matches
private $xml; //variable to hold the xml data from the RSS feed
private $item; //variable to hold the node we're looking at

//Constructor intializes properties of the class
//pass it a zip code, you can also define units
//defaults to farenheit, but pass in c for celsius
public function __construct( $zip, $units = "f")
{
if($this->units != "c"){
$this->units = "f";
}

//set the url given the things passed into the constructor
$this->url       = 'http://weather.yahooapis.com/forecastrss?p='.$zip.'&u='.$units;
//open the file
$this->xml = file_get_contents($this->url);
//reead it using SimpleXML
$this->xml = simplexml_load_string($this->xml);
//we grab the channel node using simpleXML
$this->item = $this->xml->channel[0]->item[0];
//here we set the namespace we're looking for using yahoo's spec
$yweather = $this->item->children("http://xml.weather.yahoo.com/ns/rss/1.0");
//we have to redeclare a second namespace to use since yahoo's API sticks the
//  humidity data that we need in a different tag
$yweather2 = $this->xml->channel->children("http://xml.weather.yahoo.com/ns/rss/1.0");
//we grab all of the attributes of the yweather tag for the conditions
$attr = $yweather->condition->attributes();
//we grab the temp attribute and set the temperature property
$this->temp     = $attr["temp"];
//we grab the condition type and set the property
$this->cond     = $attr["text"];
//we use our attribute finder and our other namespace to get
// the atmosphere tag, where we get the humidity data
$attr = $yweather2->atmosphere->attributes();
//set the humidity property
$this->humidity  = $attr["humidity"];

}

//magic function for setting variables
public function __set($var, $val)
{
$this->$var = $val;
}

//magic function for returning variables
public function __get($var)
{
return $this->$var;
}

}

Using the class in your scripts (assuming you put it in its own file):

//include the file using whatever name you gave it
include_once("weather.class.php");

//create a new weather object
//make sure you pass in a zip code
//if you want to specify units, pass in "c" as a string for celsius
// units default to farenheit
$weather = new WeatherData($zipcode, $units);

//to access the members, call them like so
$weather->cond; //for the condition, eg "Sunny"
$weather->temp; //for the temperature
$weather->humidity; //for the humidity

Since I only needed these three aspects of the weather, that’s all I bothered to include in the class. If you need more data, you can ask me and I can help you figure it out. There are many ways you could implement this class in your work as well, but I’ll save those ideas for another post.

Special thanks to my buddy, Navarr Barnier, for helping me integrate SimpleXML with this class.

This entry was posted on Saturday, July 31st, 2010 at 4:51 pm and is filed under PHP. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply