#native_company# #native_desc#
#native_cta#

Incorporate Weather Data into Your PHP Web Apps

By PHP Builder Staff
on September 27, 2011

Science fiction writer R.A.J. Phillips recurring character Kelvin R. Throop once wondered aloud, “Isn’t it interesting that the same people who laugh at science fiction listen to weather forecasts and economists?” To be sure, weather forecasting seems a mad science of sorts, yet many of us tend to obsessively monitor the latest prognostications, with a sizeable segment of the population even considering the ritual to be a hobby of sorts. Regardless of whether you consider the weather to be an obsession or nuisance, there are plenty of opportunities to incorporate weather-related data into your Web application.

The Services_Weather Package

The Services_Weather PEAR Package offers what is perhaps the easiest way to begin retrieving weather-related data. Plugging into multiple freely available weather-oriented Web services, you can choose to retrieve weather data from respected institutions such as NOAA and The Weather Channel (at the time of this writing support for a third Web service provided by CapeScience was also provided, however the service seems to be entirely offline).

You can install Services_Weather via PEAR. To do so, open up a terminal window and execute the following command:

$ pear install --alldeps Services_Weather

Additionally, although the documentation doesn’t mention it, you’ll also need to install the XML_Serializer PEAR package. This package is currently only available in beta format, meaning you’ll need to append -beta onto the end of the package name when installing it:

sudo pear install XML_Serializer-beta
...
install ok: channel://pear.php.net/XML_Parser-1.3.4
install ok: channel://pear.php.net/XML_Serializer-0.20.2

Once installed, it’s just a matter of knowing what API methods are available (you can consult a complete list within the Services_Weather package’s documentation). Let’s continue by exploring The Weather Channel’s Web service.

Retrieving Weather Data from Weather.com

Head over to The Weather Channel website and create an account which provides you access to the XML data feed. Registration is free and only takes a moment. You’ll receive a confirmation e-mail which contains a partner ID and license key which we’ll subsequently use to connect to the Web service. Be sure to read the terms of use included with the confirmation e-mail as the terms are surprisingly onerous even given the current sea of ridiculous user agreements.

Once you have the partner ID and license key, you can connect to the service using the following code:

require_once "Services/Weather.php";

$options = array ();

$weather = Services_Weather::service('Weatherdotcom', $options);
$weather->setAccountData('1234567890', 'secret'); 

To keep things simple, I’ve opted to not include any of the many options useful for debugging, passing account credentials, caching, and setting other characteristics. These options aren’t well documented, however you can find them by perusing the Weather.php class found in the Services_Weather package.

Once connected, you can request a five-day forecast be returned for a specific location. Unfortunately, it’s not possible to simply identify a location by its zip code or city; instead you need to use a special identifier. For instance, I live in downtown Columbus, Ohio. The Weather.com code for this location is USOH0212. You can determine what location IDs are available for a specific city via the searchLocation() method:

$locations = $weather->searchLocation('Columbus, Ohio');
var_dump($locations);

Executing this snippet produces the following list of five locations:

array
  'USOH0212' => string 'Columbus, OH' (length=12)
  'USOH0213' => string 'Columbus Grove, OH' (length=18)
  'USOH0214' => string 'Columbus/Bolton Field, OH' (length=25)
  'USOH0215' => string 'Columbus/OSU Arpt, OH' (length=21)
  'USOH0216' => string 'Columbus/Rickenbacker ANGB, OH' (length=30)

With the desired location in hand, you can use the getForecast() method to retrieve the forecast:

$forecast = $weather->getForecast('USOH0212');

Among other data, the getForecast() call will return the five-day forecast, with each day including the following data:

array
  'temperatureHigh' => float 84
  'temperatureLow' => float 65
  'sunrise' => string '6:45 AM' (length=7)
  'sunset' => string '20:26 PM' (length=8)
  'day' => 
    array
      'condition' => string 'Partly Cloudy' (length=13)
      'conditionIcon' => string '30' (length=2)
      'wind' => float 4
      'windGust' => float 0
      'windDegrees' => string '206' (length=3)
      'windDirection' => string 'SSW' (length=3)
      'precipitation' => string '10' (length=2)
      'humidity' => string '43' (length=2)
  'night' => 
    array
      'condition' => string 'Mostly Clear' (length=12)
      'conditionIcon' => string '33' (length=2)
      'wind' => float 3
      'windGust' => float 0
      'windDegrees' => string '190' (length=3)
      'windDirection' => string 'S' (length=1)
      'precipitation' => string '20' (length=2)
      'humidity' => string '70' (length=2)

Of course, you’ll want to format this data in an eye-appealing format, so let’s iterate over the contents to display the daytime low and high temperature:

$date = new DateTime("today");

foreach ($forecast['days'] AS $day) {

  printf("%s
", $date->add(new DateInterval('P1D'))->format("F j, Y")); printf("Daytime Low: %s
", $day['temperatureLow']); printf("Daytime High: %s", $day['temperatureHigh']); }

Executing this snippet produces the following output:

August 18, 2011
Daytime Low: 65
Daytime High: 84

August 19, 2011
Daytime Low: 65
Daytime High: 86

August 20, 2011
Daytime Low: 63
Daytime High: 86

August 21, 2011
Daytime Low: 70
Daytime High: 87

August 22, 2011
Daytime Low: 69
Daytime High: 84

Converting Measurement Units

The Services_Weather package offers several helper methods useful for converting between various measurement formats. For instance you can convert from Fahrenheit to Celsius using the convertTemperature() method, as demonstrated here:

echo $weather->convertTemperature($day['temperatureLow'], 'f', 'c');

Other conversion methods provide you with the ability to easily convert pressure, speed, and distance, in addition to calculate the dew point, humidity and wind chill. See the documentation for all of the details.

About the Author

Jason Gilmore is founder of the publishing, training, and consulting firm WJGilmore.com. He is the author of several popular books, including “Easy PHP Websites with the Zend Framework”, “Easy PayPal with PHP”, and “Beginning PHP and MySQL, Fourth Edition”. Follow him on Twitter at @wjgilmore.