Paulund

Create A Weather Application With Google API Using PHP

As of August 2013 Google shut down it's weather API. The following tutorial will not work with the Google weather API but you can use the following code for another weather API that you find.

Google has a lot of APIs which any developer can use to add a bit more interaction to your application. Some of the APIs need an API key to access the data you want, but there are others which don't need any API key at all. Previous examples of using a Google API is getting the feedburner count using PHP. Today we are going to use another hidden Google API to get the weather for a certain area. The Google weather API allows you to send it a location from anywhere in the world and get the current weather and the future weather. In this tutorial you will learn how to create a quick and easy weather application in PHP using the Google Weather API. View the demo page to see what we are going to create.

Google Weather API

Google has loads of APIs you can use to get different data from the massive amount that Google can get a hold of. Click on the link below to view all the APIs you can use from Google. Google APIs You will see from this list that the Google Weather API isn't on here but that doesn't mean you can't use it. To get to the weather from Google just use the following URL.


http://www.google.com/ig/api?weather=$location

This will return an XML document with data about the location, current weather and future weather. Using PHP it's very easy to consume this data and use XPATH to get at the data you want. We want to get the current weather and the future weather. In PHP this is done with the code below.


$xml = simplexml_load_file('http://www.google.com/ig/api?weather='.urlencode($this->location_));

$this->current_ = $xml->xpath("/xml_api_reply/weather/current_conditions");

$this->future_ = $xml->xpath("/xml_api_reply/weather/forecast_conditions");

We know how to get at this data so we can then turn this into a PHP class, that we can use this data in our application.

Create Google Weather PHP Class

In this class we want to get the weather for a certain location and store the current and future nodes in a class property so we can get at this data later.

This will mean we will have 3 methods in the class. - Constructor - This will be sent the location and store this in a property, once we have the location variable we can then call the get weather method to get both the current and future weather.

  • Get Weather For Location - This will call the Google Weather API to get the weather and store the results in class properties.

  • Return Location - This will return the location sent to the class.


<?php

/**
 * PHP Class to get the current and future weather conditions
 * Created by: PaulUnd
 * http://www.paulund.co.uk
 */
class Google_Weather
{
	/**
	 * Class properties
	 */
	protected $location_ = false;
	protected $current_ = false;
	protected $future_ = false;
		
	/**
	 * Constructor for the Google_Weather class
	 */	
	public function __construct($location){
			
		//Location must not be empty	
		if($location != ""){
			$this->location_ = $location;
			$this->getWeather();	
		}		
	}
		
	/**
	 * Get the weather from the location in the form
	 */
	private function getWeather(){
		
		//If location is set
		if($this->location_){
			$xml = simplexml_load_file('http://www.google.com/ig/api?weather='.urlencode($this->location_));
			$this->current_ = $xml->xpath("/xml_api_reply/weather/current_conditions");
			$this->future_ = $xml->xpath("/xml_api_reply/weather/forecast_conditions");	
		}
	}
		
	/**
	 * Gets the current location
	 */
	public function getLocation(){
		return ucwords($this->location_);
	}
}
?>

Create Display Weather PHP Class

Now we have the PHP class to get the data we need to display this data to the visitor, for this we use another PHP class which inherits from the Google Weather class. This means that we have access all of the Google Weather class public and protected methods to display the data. In this class we want to be able to display both the current and the future weather, but we want to display them differently as the current weather is more important than the future weather. We would also want to choose how we display the temperature in either Fahrenheit or the Celsius. For this class we are going to use 4 methods: - Constructor - The constructor takes 2 parameters the location from the input and if we display Fahrenheit or Celsius.

  • Display Current Weather - Gets the current data and displays the weather.
  • Display Future Weather - Gets the future data and displays the weather.
  • Display Temperature - Converts the temperature and displays it in the future weather.

<?php
require_once 'google_weather.php';

class Display_Weather extends Google_Weather{
	
	private $temp = false;
	
	/**
	 * Constructor for displaying the weather
	 */	
	public function __construct($location, $temp){
		try {
			
			switch($temp){
				case "c":
				case "f":
					parent::__construct($location);
				 	$this->temp_ = $temp;
				break;
					
				default:
					throw new Exception("Temperature must be in either C or F.");
				break;
			}
		
		} catch (Exception $e)
		{
		    echo $e->getMessage(), "\n";
		}
	}

/**
	 * Display the current weather
	 */
	public function displayCurrentWeather(){
		if($this->current_ != FALSE){
			echo '<h2>Today In '. $this->getLocation().'The Weather Is:</h2>';
			echo '< img src="http://www.google.com/'.$this->current_[0]->icon['data'].'" alt="'.$this->getLocation().' Weather" />';
			echo '<h4>'. $this->current_[0]->condition['data'].'</h4>';
			echo '<p>The weather in <strong>'. $this->getLocation().'</strong> is currently <strong>'. $this->current_[0]->condition['data'].'</strong> with a temp of <strong>'. $this->current_[0]->temp_c['data'].'&deg;c ('. $this->current_[0]->temp_f['data'].'&deg;f)</strong></p>
			<p>The wind condition is currently <strong>'. $this->current_[0]->wind_condition['data'].'</strong></p>'; 
		} else {
			echo '<h2>Location not found</h2>';
		}
	}
	
	/**
	 * Display the future weather
	 */
	public function displayFutureWeather(){
		if($this->future_ != FALSE){
			foreach($this->future_ as $weather){
				echo '<div class="future_weather">';
					echo '<h2>'. $weather->day_of_week['data'].'</h2>';
					echo '< img src="http://www.google.com/'. $weather[0]->icon['data'].'" alt="'. $this->getLocation().' Weather" />';
					echo '<p>'. $weather->condition['data'].'</p>';
					echo '<p><strong>Low</strong> '. $this->getTemp($weather->low['data']).'<br/>
						<strong>High</strong> '. $this->getTemp($weather->high['data']).'</p>';
				echo '</div>';
			}
		}
	}
	
	/**
	 * Get the temperate and converts to either C or F
	 */
	private function getTemp($temperature){
		if($this->temp_ == "c"){
			return round(($temperature - 32) /1.8) . "&deg;c";
		} 
		
		return $temperature."&deg;f";
	}
?>

Create Form For Location Input

We want the visitors to be able to enter the location they want to search on, so we are going to create a form where the users can enter a location in the textbox and click a submit button.


<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
	<p><label for="location"><input type="text" id="location" name="location" placeholder="Enter your location" /></label></p>
	<input type="submit" value="Submit" name="submit" />
</form>

Putting It All Together

We have now created the PHP classes and the HTML form we can now put them all together on the page. We only want to get the location weather if the $_GET variable is set so we need some if statements to check this is set before we get the location weather.


if(isset($_GET['location'])){
	require_once './php/display_weather.php';
	$weather = new Display_Weather($_GET['location'], "c");	
}

<div class="weather_location">
	<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
		<p><label for="location"><input type="text" id="location" name="location" placeholder="Enter your location" /></label></p>
		<input type="submit" value="Submit" name="submit" />
	</form>
	<hr/>
</div>

<?php if(isset($_GET['location']) && $_GET['location'] != ""){  
	
	$weather->displayCurrentWeather(); 
	
	$weather->displayFutureWeather();

} ?>

The above code will display a form and on submitting the form will create the weather object and get the weather for the location. We can then display this weather by using the displayCurrentWeather() method and displayFutureWeather(). View the demo page to see what this will create. ## Expanding On The Tutorial

This tutorial teaches you how to create a weather application but it isn't complete and can be expanded on, depending on what you want from this. You can have to set to just one location for example if you are creating a website for an event then you only want to display the weather for the location of the event. For this you can remove the form and change the Google_Weather class to get the same location each time. Another option would be to display the weather for the location of the user. This is done by finding out where the visitor is and passing this location in to the Google Weather class. To get the location of the user you can use the IP address of the visitor to get their location, then every visitor that comes to your website will get the weather for their own location. How else would you expand this application?