Google Weather API Class

Most updated code is now on Github.

https://github.com/redinkdesign/Google-Weather-API

20 Responses to “Google Weather API Class”

  1. Ashwin Surajbali says:

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

  2. Matt says:

    Google recently changed their weather icons. If you use this script and notice that the icons aren’t showing up all you need to do is change line 115 to this:

    $return_array['current_conditions']['icon'] = $xml->weather->current_conditions->icon['data'];

    I guess it no longer requires that appended URL, I don’t use forecast on my website but you’ll probably have to change the icon line for that as well.

    $return_array['forecast'][$i]['icon'] = $data->icon['data'];

    Also thanks for the script Ashwin!

  3. admin says:

    Thanks Matt, I just realized this change today as well. I will update the code.

    Matt :
    Google recently changed their weather icons. If you use this script and notice that the icons aren’t showing up all you need to do is change line 115 to this:
    $return_array['current_conditions']['icon'] = $xml->weather->current_conditions->icon['data'];
    I guess it no longer requires that appended URL, I don’t use forecast on my website but you’ll probably have to change the icon line for that as well.
    $return_array['forecast'][$i]['icon'] = $data->icon['data'];
    Also thanks for the script Ashwin!

  4. Tomako says:

    what about this


    if ($diff <= 3600){ ….

    should be


    if ($diff cache_time){ ….

  5. Tomako says:

    if ($diff cache_time){

  6. Tomako says:

    if ($diff <= $this->cache_time){

    (dammend textprocessor)

  7. admin says:

    @Tomako

    Good catch! Code updated, thanks.

  8. Paulb says:

    @admin

    Would it be poss to help change it so i could use city name instead as im in the uk and we dont use zip code?

  9. Johnathan says:

    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?

  10. Ashwin Surajbali says:

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

  11. Johnathan says:

    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.

  12. César Couto says:

    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 :)

  13. Ashwin Surajbali says:

    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/

  14. Ashwin Surajbali says:

    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.

  15. 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;
    };
    };

    }

    }

    ?>

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

  17. 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');

    ?>

  18. Ashwin Surajbali says:

    This is great, thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>