Google Weather API Class

Pull weather data from Google’s weather API (http://www.google.com/ig/api?weather=10027). This class grabs the raw data (xml) and creates a nicely formatted associative array containing the weather information.

Download GoogleWeather.php

Example:

$w = new googleWeather();
$w->enable_cache = 1;
$w->cache_path = '/var/www/mysite.com/cache';
$ar_data = $w->get_weather_data(10027);
print_r($ar_data);
echo $ar_data['forecast'][0]['day_of_week'];

Source:

<?php

	/**
	 * Grabs weather data from Google.com's weather API and return a nicely formatted array
	 *
	 * @author Ashwin Surajbali
	 * @package Redink Design
	 * @version 0.9.2
	 *
	 * @example
	 * $w = new googleWeather();
	 * $w->enable_cache = 1;
	 * $w->cache_path = '/var/www/mysite.com/cache';
	 * $ar_data = $w->get_weather_data(10027);
	 * print_r($ar_data);
	 * echo $ar_data['forecast'][0]['day_of_week'];
	 *
	 * Requires PHP 5 or greater
	 *
	 */

	class googleWeather{

		/**
		 * Zipcode
		 *
		 * @var int
		 */
		public $zip;

		/**
		 * Disable or enable caching
		 *
		 * @var boolean
		 */
		public $enable_cache = 0;

		/**
		 * Path to your cache directory
		 * eg. /www/website.com/cache
		 *
		 * @var string
		 */
		public $cache_path = '';

		/**
		 * Cache expiration time in seconds
		 * Default: 3600 = 1 Hour
		 * If the cached file is older than 1 hour, new data is fetched
		 *
		 * @var int
		 */
		public $cache_time = 3600; // 1 hour

		/**
		 * Full location of the cache file
		 *
		 * @var string
		 */
		private $cache_file;

		/**
		 * Location of the google weather api
		 *
		 * @var string
		 */
		private $gweather_api_url = 'http://www.google.com/ig/api?weather=';

		/**
		 * Storage var for data returned from curl request to the google api
		 *
		 * @var string
		 */
		private $raw_data;

		/**
		 * Pull weather information for 'Zipcode' passed in
		 * If enable_cache = true, data is cached and refreshed every hour
		 * Weather data is returned in an associative array
		 *
		 * @param int $zip
		 * @return array
		 */
		public function get_weather_data($zip = 0){

			if ($zip == 0 || strlen($zip) < 5 || !is_numeric($zip)){
				die('Invalid zip code.');
			}else{
				$this->zip = $zip;
			}

			if ($this->enable_cache && !empty($this->cache_path)){
				$this->cache_file = $this->cache_path . '/' . $this->zip;
				return $this->load_from_cache();
			}

			// build the url
			$this->gweather_api_url = $this->gweather_api_url . $this->zip;

			if ($this->make_request()){

				$xml = new SimpleXMLElement($this->raw_data);

				$return_array = array();

				$return_array['forecast_info']['city'] = $xml->weather->forecast_information->city['data'];
				$return_array['forecast_info']['zip'] = $xml->weather->forecast_information->postal_code['data'];
				$return_array['forecast_info']['date'] = $xml->weather->forecast_information->forecast_date['data'];
				$return_array['forecast_info']['date_time'] = $xml->weather->forecast_information->current_date_time['data'];

				$return_array['current_conditions']['condition'] = $xml->weather->current_conditions->condition['data'];
				$return_array['current_conditions']['temp_f'] = $xml->weather->current_conditions->temp_f['data'];
				$return_array['current_conditions']['temp_c'] = $xml->weather->current_conditions->temp_c['data'];
				$return_array['current_conditions']['humidity'] = $xml->weather->current_conditions->humidity['data'];
				$return_array['current_conditions']['icon'] = 'http://www.google.com' . $xml->weather->current_conditions->icon['data'];
				$return_array['current_conditions']['wind'] = $xml->weather->current_conditions->wind_condition['data'];

				for ($i = 0; $i < count($xml->weather->forecast_conditions); $i++){
					$data = $xml->weather->forecast_conditions[$i];
					$return_array['forecast'][$i]['day_of_week'] = $data->day_of_week['data'];
					$return_array['forecast'][$i]['low'] = $data->low['data'];
					$return_array['forecast'][$i]['high'] = $data->high['data'];
					$return_array['forecast'][$i]['icon'] = 'http://img0.gmodules.com/' . $data->icon['data'];
					$return_array['forecast'][$i]['condition'] = $data->condition['data'];
				}

			}

			if ($this->enable_cache && !empty($this->cache_path)){
				$this->write_to_cache();
			}

			return $return_array;

		}

		private function load_from_cache(){

			if (file_exists($this->cache_file)){

				$file_time = filectime($this->cache_file);
				$now = time();
				$diff = ($now-$file_time);

				if ($diff <= 3600){
					return unserialize(file_get_contents($this->cache_file));
				}
			}

		}

		private function write_to_cache(){

			if (!file_exists($this->cache_path)){
				// attempt to make the dir
				mkdir($this->cache_path, 0777);
			}

			if (!file_put_contents($this->cache_file, serialize($return_array))){
				echo "<br />Could not save data to cache. Please make sure your cache directory exists and is writable.<br />";
			}
		}

		private function make_request(){

			$ch = curl_init();
			curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt ($ch, CURLOPT_URL, $this->gweather_api_url);
			curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
			curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
			$this->raw_data = curl_exec ($ch);
			curl_close ($ch);

			if (empty($this->raw_data)){
				return false;
			}else{
				return true;
			}

		}

	}

?>

All code is Copyright 2009 by Ashwin Surajbali (http://www.redinkdesign.net).

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of ERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You can view a copy of the GNU General Public Licsense at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.

    • Ashwin Surajbali
    • April 14th, 2009

    New revision added. Google’s ICON url changed and the code has been updated.

    • Erin
    • May 19th, 2009

    Thank you so much for sharing this script. Its awesome.

    • Ashwin Surajbali
    • May 20th, 2009

    Code updated again at line 123.

    Changed from

    $return_array['forecast'][$i]['icon'] = ‘http://img0.gmodules.com/ig/’ . $data->icon['data'];

    to

    $return_array['forecast'][$i]['icon'] = ‘http://img0.gmodules.com/’ . $data->icon['data'];

    Stop changing image paths google :)

    • Johnathan
    • June 23rd, 2009

    I’m looking to include a similar class in a personal project I’m working on (GNU License). What’s your license on this PHP Class?

    • Ashwin Surajbali
    • June 24th, 2009

    Hey, it would be GNU as well. I will update the post…thanks.

    • Johnathan
    • June 29th, 2009

    Great! I’ll drop you a line if/when my project gets completed.

    Thanks for your work on this. It’ll save me a good chunk of time.

    • César Couto
    • September 21st, 2009

    Hi there. I’m trying to find a code for a Portuguese city called “Ponta Delgada”. Since the script gets information by zip code and European zip codes are different, do you know how can i find a zip for a european country that works with google wheater api ?

    I’ve tryed using the yahoo zip code of my city but didn’t worked :)

    • Ashwin Surajbali
    • September 21st, 2009

    Hey, it supports a lot more functionality than I’ve included in this class. I will update it to accept the other features as soon as I get some free time. In the mean time, take a look at this blog

    http://blog.emerick.org/2008/05/07/google-weather-api-feed-documentation/

    • Ashwin Surajbali
    • June 2nd, 2009

    Looks good, thanks for the update :)

    Curl is a plugin you have to enable btw…but file_get_contents is good as well. If you use file_get_contents, you might want to set the user agent ini_set(“user_agent”, “Your browsername here”); just incase.

  1. With your code I had two problems: the cache enabled but no file, it does not return anything. So I have changed your example and the cache is handled by make_request(). The grabbing is made by file_get_contents() as I couldn’t find the curl thing. The other problem is your example doesn’t handle languages, so I’ve included in the get_weather_data() function as an optional parameter.


    < ?php

    /**
    * Grabs weather data from Google.com's weather API and return a nicely formatted array
    *
    * @author Ashwin Surajbali
    * @package Redink Design
    * @version 0.9.2
    *
    * @example
    * $w = new googleWeather();
    * $w->enable_cache = 1;
    * $w->cache_path = '/var/www/mysite.com/cache';
    * $ar_data = $w->get_weather_data(10027);
    * print_r($ar_data);
    * echo $ar_data['forecast'][0]['day_of_week'];
    *
    * Requires PHP 5 or greater
    *
    */

    class googleWeather{

    /**
    * Search Value
    *
    * @var str
    */
    public $search;

    /**
    * Disable or enable caching
    *
    * @var boolean
    */
    public $enable_cache = 0;

    /**
    * Path to your cache directory
    * eg. /www/website.com/cache
    *
    * @var string
    */
    public $cache_path = '';

    /**
    * Cache expiration time in seconds
    * Default: 3600 = 1 Hour
    * If the cached file is older than 1 hour, new data is fetched
    *
    * @var int
    */
    public $cache_time = 3600; // 1 hour

    /**
    * Full location of the cache file
    *
    * @var string
    */
    private $cache_file;

    /**
    * Location of the google weather api
    *
    * @var string
    */
    private $gweather_api_url = 'http://www.google.com/ig/api?hl=%s&weather=%s';

    /**
    * Storage var for data returned from curl request to the google api
    *
    * @var string
    */
    private $raw_data;

    /**
    * Pull weather information for 'Zipcode' or 'City' passed in
    * If enable_cache = true, data is cached and refreshed every hour
    * Weather data is returned in an associative array
    *
    * @param int $zip
    * @return array
    */
    public function get_weather_data($search, $lang="en"){
    $this->search = $search;

    if ($this->search == 0 || strlen($this->search) < 5 || !is_numeric($this->search)){
    $this->city = $this->search;
    } else {
    $this->zip = $this->search;
    };

    $this->cache_file = $this->cache_path . '/' . $this->search;

    // build the url
    $this->gweather_api_url = sprintf($this->gweather_api_url, $lang, urlencode($this->search));

    if ($this->make_request()){

    $xml = new SimpleXMLElement($this->raw_data);
    $return_array = array();

    $return_array['forecast_info']['city'] = $xml->weather->forecast_information->city['data'];
    $return_array['forecast_info']['zip'] = $xml->weather->forecast_information->postal_code['data'];
    $return_array['forecast_info']['date'] = $xml->weather->forecast_information->forecast_date['data'];
    $return_array['forecast_info']['date_time'] = $xml->weather->forecast_information->current_date_time['data'];

    $return_array['current_conditions']['condition'] = $xml->weather->current_conditions->condition['data'];
    $return_array['current_conditions']['temp_f'] = $xml->weather->current_conditions->temp_f['data'];
    $return_array['current_conditions']['temp_c'] = $xml->weather->current_conditions->temp_c['data'];
    $return_array['current_conditions']['humidity'] = $xml->weather->current_conditions->humidity['data'];
    $return_array['current_conditions']['icon'] = 'http://www.google.com' . $xml->weather->current_conditions->icon['data'];
    $return_array['current_conditions']['wind'] = $xml->weather->current_conditions->wind_condition['data'];

    for ($i = 0; $i < count($xml->weather->forecast_conditions); $i++){
    $data = $xml->weather->forecast_conditions[$i];
    $return_array['forecast'][$i]['day_of_week'] = $data->day_of_week['data'];
    $return_array['forecast'][$i]['low'] = $data->low['data'];
    $return_array['forecast'][$i]['high'] = $data->high['data'];
    $return_array['forecast'][$i]['icon'] = 'http://img0.gmodules.com/' . $data->icon['data'];
    $return_array['forecast'][$i]['condition'] = $data->condition['data'];
    }

    }

    return $return_array;

    }

    private function load_from_cache(){
    if ($this->enable_cache){
    if (file_exists($this->cache_file)){
    $file_time = filectime($this->cache_file);
    $now = time();
    $diff = ($now-$file_time);

    if ($diff < = 3600){
    return file_get_contents($this->cache_file);
    }
    }
    }
    }

    private function write_to_cache($data){
    if ($this->enable_cache) {
    if (!file_exists($this->cache_path)){
    // attempt to make the dir
    mkdir($this->cache_path, 0777);
    }
    if (!file_put_contents($this->cache_file, $data)){
    echo "
    Could not save data to cache. Please make sure your cache directory exists and is writable.
    ";
    }
    };
    }

    private function make_request(){
    /*
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_URL, $this->gweather_api_url);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $this->raw_data = curl_exec ($ch);
    curl_close ($ch);
    */

    $data = $this->load_from_cache();
    if (!empty($data)) {
    $this->raw_data=$data;
    return true;
    } else {
    $this->raw_data = file_get_contents($this->gweather_api_url);
    if (empty($this->raw_data)){
    return false;
    } else {
    $this->raw_data=str_replace('< ?xml version="1.0"?>', '< ?xml version="1.0" encoding="ISO-8859-1"?>', $this->raw_data);
    $this->write_to_cache($this->raw_data);
    return true;
    };
    };

    }

    }

    ?>

  2. Ah!!! and somthing else: in this Google API you can enter zips or citys, so I added the idea

  3. Using some of Tristan’s work, i modified the class so, from the original, it solves:

    • changed the old numeric-only zipcode var to a string var ($this->search), thus allowing the usage of google weahter’s supported search strings.
    • cache_time was not being considered in the code, now it is
    • added language support as a class property ($this->language)
    • cache file autogeneration using base64_encode to avoid encoding problems with filesystems
    • new class property ($this->cache_file_encoding) to set cache file encoding (defaults to ISO-8859-1)
    • moved the gweather icons url string to a class property ($this->gweather_icons_url) for faster modification and easier usage
    • filtered all vars used as url parameters using urlencode() function to avoid errors

    There it goes:


    < ?php

    /**
    * Grabs weather data from Google.com's weather API and return a nicely formatted array
    *
    * @author Ashwin Surajbali
    * @package Redink Design
    * @version 0.9.2
    *
    * @example
    * $w = new googleWeather();
    * $w->enable_cache = 1;
    * $w->cache_path = '/var/www/mysite.com/cache';
    * $ar_data = $w->get_weather_data(10027);
    * print_r($ar_data);
    * echo $ar_data['forecast'][0]['day_of_week'];
    *
    * Requires PHP 5 or greater
    *
    */

    class googleWeather{

    /**
    * Search string: zip code; city name; city name, state; city name, country; latitude/longitude or possibly other (Google dependant)
    *
    * @var string
    */
    public $search;

    /**
    * Language (examples: "en", "ca", "da", "de", "es", "fi", "fr", "it", "ja", "ko", "nl", "no", "pt-BR", "ru", "sv", "zh-CN", "zh-TW")
    *
    * @var string
    */
    public $language = '';

    /**
    * Disable or enable caching
    *
    * @var boolean
    */
    public $enable_cache = 0;

    /**
    * Path to your cache directory
    * eg. /www/website.com/cache
    *
    * @var string
    */
    public $cache_path = '';

    /**
    * Cache expiration time in seconds
    * Default: 3600 = 1 Hour
    * If the cached file is older than 1 hour, new data is fetched
    *
    * @var int
    */
    public $cache_time = 3600; // 1 hour

    /**
    * Full location of the cache file
    *
    * @var string
    */
    private $cache_file;

    /**
    * Cache file encoding
    *
    * @var string
    */
    private $cache_file_encoding = 'ISO-8859-1';

    /**
    * Location of the google weather api
    *
    * @var string
    */
    private $gweather_api_url = 'http://www.google.com/ig/api?weather=';

    /**
    * Location of the google weather icons
    *
    * @var string
    */
    private $gweather_icons_url = 'http://img0.gmodules.com';

    /**
    * Storage var for data returned from curl request to the google api
    *
    * @var string
    */
    private $raw_data;

    /**
    * Pull weather information for 'Search' passed in
    * If enable_cache = true, data is cached and refreshed every hour
    * Weather data is returned in an associative array
    *
    * @param int $search
    * @return array
    */
    public function get_weather_data($search = 0) {

    if (empty($search)) {
    die('You must provide one of the following: a zip code (10001); city name (Ontario), city name, state (Ontario,OR); city name, country (London,England); latitude/longitude(,,,30670000,104019996) or possibly other.');
    } else {
    $this->search = $search;
    }

    $this->cache_file = $this->cache_path . '/' . base64_encode($this->search);

    // build the url
    $this->gweather_api_url = $this->gweather_api_url . urlencode($this->search) . '&hl=' . urlencode($this->language);

    if ($this->make_request()) {

    $xml = new SimpleXMLElement($this->raw_data);

    $return_array = array();

    $return_array['forecast_info']['city'] = $xml->weather->forecast_information->city['data'];
    $return_array['forecast_info']['zip'] = $xml->weather->forecast_information->postal_code['data'];
    $return_array['forecast_info']['date'] = $xml->weather->forecast_information->forecast_date['data'];
    $return_array['forecast_info']['date_time'] = $xml->weather->forecast_information->current_date_time['data'];

    $return_array['current_conditions']['condition'] = $xml->weather->current_conditions->condition['data'];
    $return_array['current_conditions']['temp_f'] = $xml->weather->current_conditions->temp_f['data'];
    $return_array['current_conditions']['temp_c'] = $xml->weather->current_conditions->temp_c['data'];
    $return_array['current_conditions']['humidity'] = $xml->weather->current_conditions->humidity['data'];
    $return_array['current_conditions']['icon'] = 'http://www.google.com' . $xml->weather->current_conditions->icon['data'];
    $return_array['current_conditions']['wind'] = $xml->weather->current_conditions->wind_condition['data'];

    for ($i = 0; $i < count($xml->weather->forecast_conditions); $i++) {
    $data = $xml->weather->forecast_conditions[$i];
    $return_array['forecast'][$i]['day_of_week'] = $data->day_of_week['data'];
    $return_array['forecast'][$i]['low'] = $data->low['data'];
    $return_array['forecast'][$i]['high'] = $data->high['data'];
    $return_array['forecast'][$i]['icon'] = $this->gweather_icons_url . '/' . $data->icon['data'];
    $return_array['forecast'][$i]['condition'] = $data->condition['data'];
    }

    }

    return $return_array;

    }

    private function load_from_cache() {

    if ($this->enable_cache) {
    if (file_exists($this->cache_file)) {
    $file_time = filectime($this->cache_file);
    $now = time();
    $diff = ($now-$file_time);
    if ($diff < = $this->cache_time) {
    return file_get_contents($this->cache_file);
    }
    }
    }

    }

    private function write_to_cache() {

    if ($this->enable_cache) {
    if (!file_exists($this->cache_path)) {
    // attempt to make the dir
    mkdir($this->cache_path, 0777);
    }
    if (!file_put_contents($this->cache_file, $this->raw_data)) {
    echo "

    Could not save data to cache. Please make sure your cache directory exists and is writable.

    ";
    }
    }

    }

    private function make_request() {

    $data = $this->load_from_cache();
    if (!empty($data)) {
    $this->raw_data=$data;
    return true;
    } else {
    $this->raw_data = file_get_contents($this->gweather_api_url);
    if (empty($this->raw_data)) {
    return false;
    } else {
    $this->raw_data=str_replace('< ?xml version="1.0"?>', '< ?xml version="1.0" encoding="'.$this->cache_file_encoding.'"?>', $this->raw_data);
    $this->write_to_cache();
    return true;
    }
    }

    }

    }

    ?>

    Usage example:


    < ?php

    // google weather
    require_once('php/google_weather_cache.php');
    $w = new googleWeather();
    $w->language = 'ca';
    $w->enable_cache = 1;
    $w->cache_path = '/absolute/path/to/google_weather_cache/';
    $w->cache_file_encoding = 'UTF-8';
    $weather_data = $w->get_weather_data('Barcelona');

    ?>

    • Ashwin Surajbali
    • October 6th, 2009

    This is great, thank you!

  1. No trackbacks yet.