«

»

Dec
22

My PHP Weather Script

I really enjoy playing around with PHP. Not only is it fun to test all kinds of script snippets, but if you have your own website, you can make it appear to your customers as if you’re updating your website on a daily basis.

I’m including a little PHP script I re-wrote based on the weather. If you follow closely, you’ll notice that I have different phrases based on the temperature outside. There are 3 things you need to do in order to get it up and running.

The first thing you’ll need to do is copy the below code and place it in a file called “weather_config.php”.

<?php

//USER CHANGEABLE VALUES
define('WEA_TIMEOUT', 5); //TIMEOUT IN SEC PER PARSE TRY

//National Oceanic and Atmospheric Administration (NOAA) XML Feed Base
define('WEA_BASE_SITE', 'http://www.weather.gov/data/current_obs/');

class WeatherLib
{
  var $xmlURL;
  var $xmlSite;
  var $elementArray;
  var $varCount;
  var $xml_parser;
  var $pauseHandler;
  var $mappingRef;
  var $error;
  
  function WeatherLib($site){
    if(!empty($site)){
      //INIT
      $this->loadMappings();
      $this->xmlSite=$site;
      $this->xmlURL = WEA_BASE_SITE . $this->xmlSite .'.xml';
      $this->varCount=0;
      $this->error='';
      
      //ATTEMPT PARSE
      if(!$this->parse()){
        return false;
      }  
    }
    else{
      $this->error='Site missing from WeatherInfo constructor';
      return false;
    }
    return true;
  }
  
  function loadMappings()
  {
    //DO NOT CHANGE
    //THIS IS THE ARRAY MAPPING
    //TO THE XML ELEMENTS
    $this->mappingRef=array(
      'WEA_LOCATION'=> 7,
      'WEA_LATITUDE'=> 9,
      'WEA_LONGITUDE'=> 10,
      'WEA_OBSERVATION_TIME'=> 11,
      'WEA_WEATHER_STRING'=> 13,
      'WEA_TEMP_F'=> 15,
      'WEA_TEMP_C'=> 16,
      'WEA_HUMIDITY'=> 17,
      'WEA_WIND_STRING'=> 18,
      'WEA_WIND_DIR'=> 19,
      'WEA_WIND_MPH'=> 21,
      'WEA_PRESSURE'=> 24,
      'WEA_DEWPOINT_F'=> 26,
      'WEA_DEWPOINT_C'=> 27,
      'WEA_HEATINDEX_F'=> 29,
      'WEA_HEATINDEX_C'=> 30,
      'WEA_WINDCHILL_F'=> 32,
      'WEA_WINDCHILL_C'=> 33,
      'WEA_VISIBILITY'=> 34,
      'WEA_ICON_BASE'=> 35,
      'WEA_ICON_FILE'=> 36);
  }
  
  function parse(){
    //SET PARSE DEPENDENT VARS
    $this->elementArray=array();
    $this->pauseHandler=false;

    //SET PARSER
    $this->xmlParser = xml_parser_create();
    xml_set_object($this->xmlParser,$this);
    xml_parser_set_option($this->xmlParser, XML_OPTION_CASE_FOLDING, true);
    xml_set_element_handler($this->xmlParser, "startElement", "endElement");
    xml_set_character_data_handler($this->xmlParser, "characterData");
    
    $data='';
    
    //USE FUNCTION file_get_contents TO OPEN XML FILE IF IT EXISTS, PHP >= 4.3
    if(function_exists('file_get_contents')){
      //TRY TO OPEN XML
      if(!$data=$this->getFileRecentPHP()){
        //IF IT FAILS, TRY AGAIN USING OTHER METHOD
        if(!$data=$this->getFileRecentPHP()){
          return false;
        }
        else{
          //SECOND TRY WORKED, CLEAR ERROR
          $this->error='';
        }
      }
    }
    else {
      //OLDER VERSION OF PHP, USING FOPEN INSTEAD
      //TRY TO OPEN XML
      if(!$data=$this->getFileOlderPHP()){
        //IF IT FAILS, TRY AGAIN
        if(!$data=$this->getFileOlderPHP()){
          return false;
        }
        else{
          //SECOND TRY WORKED, CLEAR ERROR
          $this->error='';
        }      
      }
    }

    //READY TO PARSE XML FILE
    if (!xml_parse($this->xmlParser, $data)){
      $this->error='XML Parser Error';
      return false;
    }  
  }
  
  //USE FUNCTION file_get_contents TO OPEN XML FILE IF IT EXISTS, PHP >= 4.3
  function getFileRecentPHP()
  {
    $data='';
    //SET TIMEOUT
    ini_set('default_socket_timeout', WEA_TIMEOUT);  
    //RETRIEVE FILE
    if(!$data=file_get_contents($this->xmlURL)){
      $this->error='XML Parser Error: file_get_contents of ' . $this->xmlURL . ' failed.';
      return false;
    }
    return $data;
  }
  
  //USE FUNCTION FOPEN FOR OLDER PHP VERSIONS OR IF OTHER FUNCTION DOESN'T WORK
  function getFileOlderPHP()
  {
    $data='';
    //RETRIEVE FILE
    if($dataFile = @fopen($this->xmlURL, "r" )){
      while (!feof($dataFile)) {
        $data.= fgets($dataFile, 4096);
      }
      fclose($dataFile);
    }
    else{
      $this->error='XML Parser Error: fopen of ' . $this->xmlURL . ' failed.';
      return false;
    }
    return $data;
  }
  
  function startElement($parser, $name, $attrs){
    //SPECIAL CASE, ELEMENT DOESNT PARSE CORRECTLY -DONT HANDLE
    if(strtolower($name)=='pressure_string'){ $this->pauseHandler=true; }
  }
  
  function endElement($parser, $name){
    //SPECIAL CASE, ELEMENT DOESNT PARSE CORRECTLY -START HANDLING AGAIN
    if(strtolower($name)=='pressure_string'){ $this->pauseHandler=false; }
  }
  
  function characterData($parser, $data) {
    if($this->pauseHandler==false){
      $data=trim($data);
      if(!empty($data)){
        $this->elementArray[$this->varCount]=$data;
        $this->varCount++;
      }
    }
  }
  
  //RETRIEVE ERROR TEXT
  function getError(){ return $this->error; }
  function get_error(){ return $this->error; }
  function hasError(){ if(!empty($this->error)){ return true; } return false; }
  function has_error(){ if(!empty($this->error)){ return true; } return false; }
  
  //USER FUNCTIONS TO RETRIEVE WEATHER INFO
  function get_location(){ return $this->elementArray[$this->mappingRef['WEA_LOCATION']]; }
  function get_latitude(){ return $this->elementArray[$this->mappingRef['WEA_LATITUDE']]; }
  function get_longitude(){ return $this->elementArray[$this->mappingRef['WEA_LONGITUDE']]; }
  function get_observation_time(){ return $this->elementArray[$this->mappingRef['WEA_OBSERVATION_TIME']]; }
  function get_weather_string(){ return $this->elementArray[$this->mappingRef['WEA_WEATHER_STRING']]; }
  function get_temp_f(){ return $this->elementArray[$this->mappingRef['WEA_TEMP_F']]; }
  function get_temp_c(){ return $this->elementArray[$this->mappingRef['WEA_TEMP_C']]; }
  function get_humidity(){ return $this->elementArray[$this->mappingRef['WEA_HUMIDITY']]; }
  function get_wind_string(){ return $this->elementArray[$this->mappingRef['WEA_WIND_STRING']]; }
  function get_wind_dir(){ return $this->elementArray[$this->mappingRef['WEA_WIND_DIR']]; }
  function get_wind_mph(){ return $this->elementArray[$this->mappingRef['WEA_WIND_MPH']]; }
  function get_pressure(){ return $this->elementArray[$this->mappingRef['WEA_PRESSURE']]; }
  function get_dewpoint_f(){ return $this->elementArray[$this->mappingRef['WEA_DEWPOINT_F']]; }
  function get_dewpoint_c(){ return $this->elementArray[$this->mappingRef['WEA_DEWPOINT_C']]; }
  function get_heatindex_f(){ return $this->elementArray[$this->mappingRef['WEA_HEATINDEX_F']]; }
  function get_heatindex_c(){ return $this->elementArray[$this->mappingRef['WEA_HEATINDEX_C']]; }
  function get_windchill_f(){ return $this->elementArray[$this->mappingRef['WEA_WINDCHILL_F']]; }
  function get_windchill_c(){ return $this->elementArray[$this->mappingRef['WEA_WINDCHILL_C']]; }
  function get_visibility(){ return $this->elementArray[$this->mappingRef['WEA_VISIBILITY']]; }
  function get_icon_base(){ return $this->elementArray[$this->mappingRef['WEA_ICON_BASE']]; }
  function get_icon_file(){ return $this->elementArray[$this->mappingRef['WEA_ICON_FILE']]; }
  function get_icon(){ return $this->get_icon_base().$this->get_icon_file(); }  
}
?>

Now that you’ve got your weather_config.php file, you’ll want to create another file called “weather.php” and place the following code inside.


<?php

include_once('phpweatherlib.php');

$displayWeather=true;

$weatherLib=new WeatherLib('KVBT');
if($weatherLib->has_error())
{
  echo "ERROR: ".$weatherLib->get_error();
  $displayWeather=false;
}
?>

<?php if($displayWeather==true){ ?>

<P>
Currently in Bella Vista, it's <?php echo $weatherLib->get_weather_string(); ?> and <?php echo $weatherLib->get_temp_f(); ?> ºF.
<P>


<?php

$time = date('G', strtotime('-1 hour'));

   if ($weatherLib->get_temp_f() > "95" and $weatherLib->get_temp_f() < "105") {
      echo "I think we should enjoy a nice glass of iced tea... indoors!";
    }
  
   elseif ($weatherLib->get_temp_f() > "85" and $weatherLib->get_temp_f() < "96") {
      echo "It's getting a little warm outside.";
    }

   elseif ($weatherLib->get_temp_f() > "75" and $weatherLib->get_temp_f() < "86") {
      echo "This is beautiful weather!";
    }

   elseif ($weatherLib->get_temp_f() > "65" and $weatherLib->get_temp_f() < "76") {
      echo "This is some pretty nice weather";
    }

   elseif ($weatherLib->get_temp_f() > "55" and $weatherLib->get_temp_f() < "66") {
      echo "It's a little cool outside";
    }

   elseif ($weatherLib->get_temp_f() > "45" and $weatherLib->get_temp_f() < "56") {
      echo "It's a little nippy outside, so I'd suggest a coat.";
    }

   elseif ($weatherLib->get_temp_f() > "35" and $weatherLib->get_temp_f() < "46") {
      echo "It's pretty cold outside, so I'd suggest a heavier coat.";
    }

   elseif ($weatherLib->get_temp_f() > "25" and $weatherLib->get_temp_f() < "36") {
      echo "It's freezing outside!";
    }

   elseif ($weatherLib->get_temp_f() > "15" and $weatherLib->get_temp_f() < "26") {
      echo "It's below freezing, so make sure the animals are in and the plants are covered.";
    }

   elseif ($weatherLib->get_temp_f() > "5" and $weatherLib->get_temp_f() < "16") {
      echo "It's just plain cold outside! I suggest a cup of hot chocolate!";
    }

     else {
      echo "";
    }
?>

<?php } //END IF ?>

The code above will get the weather for Bella Vista, Arkansas. If you’d like to personalize it a little, and I’m sure not everyone reading this lives in Bella Vista, keep on reading…

Before you create the Weather Lib Object you must find the call letters to the NOAA weather reporting station that you wish to reference. Visit the NOAA’s National Weather Service page to find the appropriate weather station. Click here to go. Click the “Select a State” drop down and then click Find. A list of results for that state will be shown followed by four uppercase call letters (example KJFK, KJAN, etc.)

Now you can create the WeatherLib object in your source code (weather.php). Create an object by assigning a variable to a new instance of the WeatherLib object with the call letters as the only argument to the object constructor.

If you have any problems, just let me know… we’ll get it working for ya!

Leave a Reply