Gearside Creative
Thursday, April 24, 2014 Shortest / Longest
Dawn
Sunrise
Noon
Sunset
Dusk
1:49am
featured-weather

Make It Rain & Let It Snow: Query Weather with PHP

Let’s face it: most back-end programmers aren’t typically the kind of people to “make it rain” in da club, but don’t let that ruin your life. I’m here to dry your tears and show you how you can have your website reflect the current conditions outside. Please note that I could have made a joke about how programmers never go outside, but I took the higher road.

In this tutorial, we’re going to find an XML feed from weather.gov and pull the current conditions from it. Then, we’ll use a PHP switch to determine which background-image div to show. We’ll further that by using another PHP switch in a CSS file to determine the intensity of that weather condition (That’s right, PHP inside CSS- the way a badass works).

Internet Explorer 8 and below do not support the CSS3 opacity property. You would need to use the older filter property to make it work.

Step One

Figure out what city you want to query the weather from. To obtain the XML file for that location go to http://w1.weather.gov/xml/current_obs/ and select the state, then on the next page click the “XML” button next to the city of your choosing. Keep this URL handy because we’ll be punching it into a PHP variable later.

Step Two

I chose to add the weather code to the footer of my website since the homepage header and subpage header is different. I would recommend taking this into consideration and doing the same for yours. Once you know where you want to put it, add the following code:

<div id="bgimgweather">
    <?php
        $url = 'http://w1.weather.gov/xml/current_obs/KSYR.xml';
        $xml = simplexml_load_file($url);
        $currentweather = $xml->weather;
        //$currentweather = "Light Rain";
    ?>
</div>

Replace the URL above with the URL of your own XML file! What the code above does is pull the “Weather” part of the XML file and injects the string from it into the variable “currentweather”. That last commented line will be used for debugging so you can control the weather to test graphics and CSS later.

Step Three

Now we’re going to add the logic. A switch is a sort of shorthand if/else statement. It works amazing when want multiple conditions to have the same function. In this case we are going to see if the variable “currentweather” contains any particular words that we want to apply graphics to. For example, words like “Rain”, “Drizzle”, and “Showers” are going to produce the rain.gif image. Paste this switch after your comment but before the closing tag for PHP:

switch (true) {
    case stristr( $currentweather, "Thunderstorm" ):
        echo '<div class="bgimgrain"></div>';
        echo '<div class="bgimgstorm"></div>';
        break;
    case stristr( $currentweather, "Snow" ):
        echo '<div class="bgimgsnow"></div>';
        break;
    case stristr( $currentweather, "Rain" ):
    case stristr( $currentweather, "Drizzle" ):
    case stristr( $currentweather, "Hail" ):
    case stristr( $currentweather, "Showers" ):
        echo '<div class="bgimgrain"></div>';
        break;
    case stristr( $currentweather, "Fog" ):
    case stristr( $currentweather, "Haze" ):
    case stristr( $currentweather, "Smoke" ):
        echo '<div class="bgimgfog"></div>';
        break;
    default:
        //Do Nothing
    break;
 }

Each case queries the current weather condition for the case-sensitive string inside the quotes. If it finds that word, it returns true and echos the <div> with a class that we’ll use to select with CSS to input the background-image. If it doesn’t find any of the words we’ve chosen, it assumes it’s sunny and doesn’t do anything. Makes sense, right? If you want to know any other words that weather.gov uses for it’s conditions, check out this very useful page!

Step Four

We’re going to make a CSS file that has a .php extension (SEE UPDATE BELOW). I’d recommend using this as a second stylesheet instead of altering your main CSS file. Make a weather.php file (or name it however you like) and make this your first line:

<?php header ("Content-type: text/css"); ?>

That is the magical line that makes this a stylesheet. Make sure you link this file from your header (Do this like you would any other stylesheet, just instead of “…style.css” it’ll be “…weather.php”). Now let’s style those divs with some CSS. Many of these options are going to depend on your specific usage, so you’ll need to change the properties to suit your own needs. First the container:

#bgimgcontainer {position: absolute; width: 100%; height: 670px; top: 0; z-index: 5; overflow: hidden; border: 1px solid red;}

Move this one around however you like. I’m positioning absolutely because I’m calling the markup from my footer. At the very least, you’ll need to position it relatively since it will have a child that is positioned absolute. I’ve also added a red border to the div so you can see where it shows up if something doesn’t work. One of my favorite CSS tips that a buddy of mine showed me was to troubleshoot with HTML color names so they can be located and removed/changed after solving.

Step Five

Now to stylize the four individual weather divs. You probably won’t need to make too many adjustments to these properties. Paste this code beneath the above CSS line from the last step:

.bgimgstorm {position: absolute; top: 0; background: url('img/weather/storm.gif') repeat left top; width: 100%; height: 100%; opacity: 0.2;}
.bgimgsnow {background: url('img/weather/snow.gif') repeat left top; width: 100%; height: 100%;}
.bgimgrain {background: url('img/weather/rain.gif') repeat left top; width: 100%; height: 100%;}
.bgimgfog {background: url('img/weather/fog.png') repeat-x left top; width: 100%; height: 100%;}

Fairly simple stuff here, just adding some background-image graphics and repeating them across the entire parent div. You may need to play around with the positioning of the fog.png since it is the only one that doesn’t repeat vertically and should be pinned to the bottom. If you were worried that I wasn’t going to supply the animated weather graphics, fear not: here is a .zip archive with four image files to upload to your server.

If you are going to make your own animated weather .gifs here is a quick tip: your layers need to be at 100% opacity because you need to save out using transparent backgrounds! Otherwise you’ll get all sorts of annoying artifacts. We’re going to change the opacity using CSS, so don’t worry about it looking too harsh.

Step Six

Let’s add another switch inside of your weather.php file (the stylesheet you made in step four). This is going to act exactly like the switch that determines which graphic to use, but this time we want to change the intensity. Paste the following code at the bottom of the file:

<?php
    $url = 'http://w1.weather.gov/xml/current_obs/KSYR.xml'; 
    $xml = simplexml_load_file($url);

    $currentweather = $xml->weather;
    //$currentweather = "Light Rain";
    switch (true) {
        case stristr( $currentweather, "Light" ):
        case stristr( $currentweather, "Drizzle" ):
            echo '.bgimgfog {opacity: 0.3;} ';
            echo '.bgimgrain {opacity: 0.04;} ';
            echo '.bgimgsnow {opacity: 0.04;} ';
            echo '/*' . $currentweather . '*/';
            break;
        case stristr( $currentweather, "Heavy" ):
        case stristr( $currentweather, "Thunderstorm" ):
            echo '.bgimgfog {opacity: 0.9;} ';
            echo '.bgimgrain {opacity: 0.1;} ';
            echo '.bgimgsnow {opacity: 0.2;} ';
            echo '/*' . $currentweather . '*/';
            break;
        default:
            echo '.bgimgfog {opacity: 0.5;} ';
            echo '.bgimgrain {opacity: 0.07;} ';
            echo '.bgimgsnow {opacity: 0.08;} ';
            echo '/* ' . $currentweather . ' */';
            break;
        }
?>

Be sure to change the URL for the XML file to be the same as the one in your original! This time, we’re looking for words like “Light” or “Heavy” and we’re changing the opacity of the div to match. In each, we’re echoing the currentweather string in a comment after in case you need to troubleshoot later on.

If it isn’t currently raining or snowing in Syracuse, so you can’t see what the animation looks like, click here for a hard-coded example of snow.

That should do it! Play around with the different opacity settings to work better with the background you’re using it on. Please comment with some links where you’re using this code! I’d love to see the different implementations of this. Also, I’d love to hear how you’ve modified the code to make it better or further customize it!

*Update December 7, 2013: To improve page load time (by reducing requests), instead of making the weather.php file, simply place that section into your head styles.


Comments