Tanoru Posted March 5, 2010 Share Posted March 5, 2010 Hi Im a total amateur at PHP : ) Ive created a script that pulls weather data from a website. $get_dundee = file_get_contents('http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=IDUNDEE2'); $find_temp_dundee = strpos($get_dundee, '<temp_c>'); $temp_dundee = substr($get_dundee, $find_temp_dundee, 20); $get_status_dundee = file_get_contents('http://www.wunderground.com/global/stations/03163.html'); $find_status_dundee = strpos($get_status_dundee, '<div class="b" style="font-size: 14px;">'); $status_dundee = substr($get_status_dundee, $find_status_dundee, 60); echo $temp_dundee; echo $status_dundee; This works but I was wondering if there is a way to make it work faster / more seamlessly. Link to comment Share on other sites More sharing options...
0 +Dick Montage Subscriber² Posted March 5, 2010 Subscriber² Share Posted March 5, 2010 Well, you are accessing a fully rendered page - is there not a webservice you could use to query instead? Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 5, 2010 Author Share Posted March 5, 2010 Do you mean beause I am accessing this page http://www.wunderground.com/global/stations/03163.html The other link is an XML file but it doesn't have the information I want. Link to comment Share on other sites More sharing options...
0 +Dick Montage Subscriber² Posted March 5, 2010 Subscriber² Share Posted March 5, 2010 OK, just looked and yes, the XML doesn't contain the textual description of the weather (eg. "Partly cloudy")... So why not grab BOTH from the HTML page? It does contain the text as well as the temperature...? Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 5, 2010 Author Share Posted March 5, 2010 I've decided to use the Yahoo weather API instead It vies links such as this - http://weather.yahooapis.com/forecastrss?w=18637&u=c Um would it be possible for someone to write me an example of how I would get each piece of data individually in 2 variables. Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 5, 2010 Author Share Posted March 5, 2010 I've decided to use the Yahoo weather API instead It uses links such as this - http://weather.yahooapis.com/forecastrss?w=18637&u=c Can someone please help me on this, I have no idea how to do this and I've been trying for ages now. And please don't link a tutorial, I learn better from a working example : ) Link to comment Share on other sites More sharing options...
0 AnthonySterling Posted March 5, 2010 Share Posted March 5, 2010 I don't about faster, or even simpler, but... Actually, I cant really think of why I did it this way. :blush: function get_yahoo_weather($code, $units = 'c', $endpoint = 'http://weather.yahooapis.com/forecastrss'){ $xml = new SimpleXMLElement( sprintf( '%s?w=%s&u=%s', $endpoint, $code, $units ), null, true ); if(false === ($xml instanceof SimpleXMLElement)){ return false; } $nodes = array( array( 'xpath' => '//yweather:location/@city', 'attribute' => 'city', 'name' => 'city' ), array( 'xpath' => '//yweather:condition/@text', 'attribute' => 'text', 'name' => 'status' ), array( 'xpath' => '//yweather:condition/@temp', 'attribute' => 'temp', 'name' => 'temp' ) ); $return = array(); foreach($nodes as $node){ $result = array_shift( $xml->xpath($node['xpath']) ); $return[$node['name']] = (string)$result[$node['attribute']]; } return $return; } print_r( get_yahoo_weather( '18637' ) ); /* Array ( [city] => Dundee [status] => Partly Cloudy [temp] => 8 ) */ Strange, my enter key isn't working on Neowin! Weird indeed. The code highlighting is pretty poor too whilst I'm whining! :p Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 5, 2010 Author Share Posted March 5, 2010 Ok thanks for that but can you please include how to print out individual parts of the array : ) The output currently is : Array ( [city] => Dundee [status] => Partly Cloudy [temp] => 8 ) How would I print out Partly Cloudy and 8? Link to comment Share on other sites More sharing options...
0 Mouldy Punk Posted March 6, 2010 Share Posted March 6, 2010 Something along the lines of: $weather = get_yahoo_weather('18637'); echo $weather['status']; echo $weather['temp']; Untested, but should work with the above function. Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 6, 2010 Author Share Posted March 6, 2010 @ Mouldy That gives me the temperature again =) Link to comment Share on other sites More sharing options...
0 boogerjones Posted March 6, 2010 Share Posted March 6, 2010 @ Mouldy That gives me the temperature again =) Yeah, 'cause that's exactly what you asked for. You really need to learn the absolute basics of PHP. We're talking about simple array access here. Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 7, 2010 Author Share Posted March 7, 2010 @ boogerjones I agree but I find reading tutorials sometimes really not helpful, I learn how to do it best when it's done and I can see exactly what syntax is used. I'm not lazy it's just how I learn things :) Link to comment Share on other sites More sharing options...
0 Mouldy Punk Posted March 7, 2010 Share Posted March 7, 2010 Wait...I'm confused. You asked how to output something like "Partly Cloudy and 8" and the code I posted does that. What's the problem exactly? @ boogerjones I agree but I find reading tutorials sometimes really not helpful, I learn how to do it best when it's done and I can see exactly what syntax is used. I'm not lazy it's just how I learn things :) Very few people can learn how to program from reading alone. The idea of tutorials isn't to just read them. You have to do them too. If you're not doing tutorials and instead skim-read them and expect to be spoon-fed the exact syntax to do exactly what you want, I'd say that is pretty lazy. The non-lazy way would be to do a few tutorials, then apply what you've learnt into different situations that better fit exactly what you want to do. Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 7, 2010 Author Share Posted March 7, 2010 @ Mouldy Everyone is entitled to their opinion =) Sorry for not making this clearer. What I want is to print out the status of the weather, for example Cloudy or something like that. Then with an if statement I'll use that information to change an image (pretty sure I can do this myself). The problem is that I'm not sure as to how to get a variable to equal the status. I'm not exactly sure what to look for in terms of tutorials either, what would you call it. Trying to learn :) Link to comment Share on other sites More sharing options...
0 Leonick Posted March 7, 2010 Share Posted March 7, 2010 Ok, I haven't tried... but you say you want to print out the status of the weather, the code posted earlier should print put the status Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 7, 2010 Author Share Posted March 7, 2010 Yes it does, and I tried playing around with it but couldn't get it too print JUST the status. Link to comment Share on other sites More sharing options...
0 Leonick Posted March 7, 2010 Share Posted March 7, 2010 You want to get the status for Dundee? If so, on the page it says this... Current Conditions: Clear, 2 C You want to get only the "Clear" from the current conditions? Link to comment Share on other sites More sharing options...
0 zivan56 Posted March 7, 2010 Share Posted March 7, 2010 Best way is ultimately caching the data and updating it when needed. Think about how much work that file_get_contents does (establish TCP connection, send request, wait for response, reply and close connection). The simplest thing to do is to store that file you are retrieving locally, and reading from it instead of the site. Then, when a set amount of time passes, it will re-download that data and replace the file with new contents. This will make it run at the current speed for the unlucky person who gets there when an update is needed, but the rest will be blazing fast. Link to comment Share on other sites More sharing options...
0 Tanoru Posted March 8, 2010 Author Share Posted March 8, 2010 @ Zivan How would I do that, I didn't know PHP would do that Link to comment Share on other sites More sharing options...
0 Leonick Posted March 8, 2010 Share Posted March 8, 2010 @ Zivan How would I do that, I didn't know PHP would do that Here is a rather simple example, read the comments and I think you should understand, I am no expert, there might be a lot better ways to do this but I am pretty happy with the results. Although, one might want to update the status more than once an hour, yahoo update their conditions far more often than that <?php $file_lastupdate = fopen("lastupdate.txt", "r+"); //opens the file lastupdate.txt and makes it accesable trough $file_lastupdate $file_weathercache = fopen("weathercache.txt", "r+"); //opens the file weathercache.txt and makes it accesable trough $file_weathche.txt $lastupdate = file_get_contents("lastupdate.txt"); //gets the contents of the fie lastupdate and saves the contents to $lastupdate if(date(H)>$lastupdate) //compares the current hour to the one saved in the file lastupdate.txt, if the current hour is higher the cache will be updated { $update_yahoo_weather = file_get_contents('http://weather.yahoo.com/scotland/tayside/dundee-18637/'); //gets the contents form yahoos servers $find_forecast = strpos($update_yahoo_weather, '<div id="yw-cond">')+18; //finds where on the site the content we want, the current conditions, start $find_status_end = strpos($update_yahoo_weather, '</div>', $find_forecast); //find where the crrent condition end $status_length = $find_status_end - $find_forecast; //calculates the length of the current conditions fwrite($file_weathercache, substr($update_yahoo_weather, $find_forecast, $status_length)); //uses the conditons starting position and length to get the current conditions from yahoo and save them to our local cache file fwrite ($file_lastupdate, date(H)); //writes the current hour to the files lastupdate.txt } $weathercache = file_get_contents("weathercache.txt"); //gets the content of the cachefile and savs to $weathercache echo $weathercache; //types out the cached conditions ?> Make sure you create the two files needed on the server first since this script wont do that for your. If you want to know more about what PHP can do with files on the server take a look here http://www.w3schools.com/php/php_ref_filesystem.asp Link to comment Share on other sites More sharing options...
0 Gocom Posted March 8, 2010 Share Posted March 8, 2010 Here is a rather simple example, read the comments and I think you should understand, I am no expert, there might be a lot better ways to do this but I am pretty happy with the results. Although, one might want to update the status more than once an hour, yahoo update their conditions far more often than that Closing the file with fclose could be smart. With file_get_contents can be expected possible timeout problems. Either setting timeout or using curl is almost must if the script is called from the public page directly. The updating could be done with cronjob, leaving only showing to the public page, that removes all the problems. Also, then using timeout settings is way safer and won't crash the accessed side of the site. Making better "spireding" with cURL don't have effect either and can be freely used. Link to comment Share on other sites More sharing options...
0 Leonick Posted March 8, 2010 Share Posted March 8, 2010 you mean i should have flcose() at the end of the script?? ok, well i am kinda new to using files too, kinda assumed the would be like the connection to a database and be closed automatically at the end of the script Link to comment Share on other sites More sharing options...
0 Tom Bonez Posted March 8, 2010 Share Posted March 8, 2010 Here's what I'd do (using curl): First create a simple function in another php file and use an include statement in the file(s) you wish to use it (I like to keep things clean and simple), here's a simple function I created. function weatherCapture() { $ch = curl_init("http://weather.yahooapis.com/forecastrss?w=18637&u=c"); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); $result = curl_exec ($ch); $data = strstr($result, '<?'); $xml = new SimpleXMLElement($data); return $xml; } Then I'd use a few simple lines of code to select which information I'd want to be pulled from Yahoo and echo this info $weather = weatherCapture(); $currentCondition = $weather->xpath("//yweather:condition"); $currentDescription = $currentCondition[0]["text"]; $currentTemperature = $currentCondition[0]["temp"]; $currentCode = $currentCondition[0]["code"]; echo "<p>$currentDescription</p>"; //This echos the current weather (sunny, cloudy, etc.) echo "<p>$currentTemperature</p>"; //This echos the current temperature (3, 8, etc.) echo "<img src=\"http://l.yimg.com/a/i/us/we/52/$currentCode.gif\" />"; //This uses the given code tag to use the correct Yahoo image This is just a small example I put together, obviously there are many ways this can be done and much more can be done with the API, if you seek anymore help or other suggestions, just ask :) Link to comment Share on other sites More sharing options...
Question
Tanoru
Hi Im a total amateur at PHP : )
Ive created a script that pulls weather data from a website.
$get_dundee = file_get_contents('http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=IDUNDEE2'); $find_temp_dundee = strpos($get_dundee, '<temp_c>'); $temp_dundee = substr($get_dundee, $find_temp_dundee, 20); $get_status_dundee = file_get_contents('http://www.wunderground.com/global/stations/03163.html'); $find_status_dundee = strpos($get_status_dundee, '<div class="b" style="font-size: 14px;">'); $status_dundee = substr($get_status_dundee, $find_status_dundee, 60); echo $temp_dundee; echo $status_dundee;This works but I was wondering if there is a way to make it work faster / more seamlessly.
Link to comment
Share on other sites
22 answers to this question
Recommended Posts