o0110o
February 14, 2010, 3:31pm
1
Hi, I've been working on a PHP script which is "supposed" to find an individuals weather based on their geolocation. This script uses "shell_exec".
I have checked my syntax and it is correct, but there is still something missing; for when I call on the script using:
<form action='/weather.php' method='get'><br>
<input type='submit' name='submit' value='Check'><br>
</form>
I get a blank page
Here is my script:
<?php
function getWeather() {
$ip = $_SERVER['REMOTE_ADDR'];
$geo = shell_exec("/usr/bin/curl -s api.hostip.info/get_html.php?ip=$ip | /usr/bin/sed -e '1d;3d' -e's|C.*:||' -e's/...\(.*\)/\1/' -e's|-|%2d|' -e's/ /%20/' -e\s/'/%27/'");
$getAddress = "http://www.google.com/ig/api?weather=$geo";
$xml_str = file_get_contents($getAddress,0);
$xml = new SimplexmlElement($xml_str);
$count = 0;
echo '<div id="weather">';
foreach($xml->weather as $item) {
foreach($item->current_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->condition['data'];
echo $new->temp_f['data'];
echo $new->temp_c['data'];
echo $new->humidity['data'];
echo $new->wind_condition['data'];
echo '</div>';
}
foreach($item->forecast_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->day_of_week['data'];
echo $new->condition['data'];
echo $new->low['data'];
echo $new->high['data'];
echo '</div>';
}
}
echo '</div>';
}
getWeather();
?>
I'm a bit of a noob when it comes to this, so any help would be greatly appreciated. Thanks.
Jared
Neo
February 14, 2010, 8:54pm
2
A blank page when calling a PHP script often means a fatal PHP error.
What does your PHP error log file say?
---------- Post updated at 01:54 ---------- Previous update was at 01:43 ----------
Also.....
I would not use PHP shell exec to execute cURL. I would use the normal PHP cURL function.
o0110o
February 16, 2010, 1:14pm
3
[RESOLVED]
I ended up getting this script to work with
file_get_contents and preg_match instead of cURL and SED.
Thanks for your help
Neo
February 16, 2010, 1:25pm
4
Normally when people post here and then they solve their problem, they post back with the solution, so others can benefit.
This is the second post of yours I have seen where you simply post back, "Problem Solved, Thanks!"
This is not the way to thank people. The proper way to thank the community is to post back your working code, the solution, so others can benefit.
Please post your working code. Thanks.
o0110o
February 16, 2010, 1:39pm
5
neo:
Normally when people post here and then they solve their problem, they post back with the solution, so others can benefit.
This is the second post of yours I have seen where you simply post back, "Problem Solved, Thanks!"
This is not the way to thank people. The proper way to thank the community is to post back your working code, the solution, so others can benefit.
Please post your working code. Thanks.
Well I WAS going to post the polished script under a different title because the script no longer uses "shell_exec()" , but I have no problem posting the WIP for now, so here it is:
<?php
function getWeather($ip=false) {
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip = $_SERVER['REMOTE_ADDR'];
}
$url = "http://api.hostip.info/get_html.php?ip=$ip";
$geo = file_get_contents($url);
if( preg_match('/City: (.*)\nIP:/', $geo, $matches) ){
$results = $matches[1];
}else{
$results = 'getLocation failure';
}
$location = urlencode($results);
$getAddress = "http://www.google.com/ig/api?weather=$location";
$xml_str = file_get_contents($getAddress,0);
$xml = new SimplexmlElement($xml_str);
$count = 0;
echo '<div id="weather">';
foreach($xml->weather as $item) {
foreach($item->forecast_information as $new) {
echo $new->city['data'];
}
foreach($item->current_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->condition['data'];
echo $new->temp_f['data'];
echo $new->temp_c['data'];
echo $new->humidity['data'];
echo $new->wind_condition['data'];
echo '</div>';
}
foreach($item->forecast_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->day_of_week['data'];
echo $new->condition['data'];
echo $new->low['data'];
echo $new->high['data'];
echo '</div>';
}
}
echo '</div>';
}
getWeather();
?>
Now maybe you can help me "beautify" the final output?
I would like for this to look nice for people and right now it's messy
See here:
http://thefeedcast.net/knooph.com/x/weather.php
Thanks again
Neo
February 16, 2010, 1:58pm
6
Well, first of all, you will get much faster performance if you use the PHP function cURL() and not get_file_contents().
Here are some sample benchmarks from stackoverflow, file_get_contents VS CURL, what has better performance?
That's a huge difference.
FWIW, I always use curl() and not get_file_contents().
o0110o
February 16, 2010, 2:04pm
7
neo:
Well, first of all, you will get much faster performance if you use the PHP function cURL() and not get_file_contents().
Here are some sample benchmarks from stackoverflow, file_get_contents VS CURL, what has better performance?
That's a huge difference.
FWIW, I always use curl() and not get_file_contents().
Nice, curl() sounds good. So how would I implement curl()?
Do I just replace "get_file_contents" with "curl()"?
Neo
February 16, 2010, 2:16pm
8
You can visit the PHP man page for curl() there are plenty of examples.
You can also see my recent blog post where I implement curl in an example bit of code to check for a file in a failover scenario:
[PHP] Web Failover Code Using cURL and Shared Memory | The UNIX and Linux Forums Blog
o0110o
February 16, 2010, 2:55pm
9
Thanks!
---------- Post updated at 04:25 PM ---------- Previous update was at 04:07 PM ----------
o0110o:
Thanks!
So I take it I somehow have to replace get_file_contents with something like this:
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "$ip");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
Forgive me for I am trying, LOL
Neo
February 16, 2010, 3:06pm
10
No, you need to send a URL to curl() as a argument, not an IP address.
From my example in the blog post:
define('HEARTBEAT', 'myCDNexample.com/heartbeat.html');
curl_setopt($ch, CURLOPT_URL, HEARTBEAT);
o0110o
February 16, 2010, 3:27pm
11
neo:
No, you need to send a URL to curl() as a argument, not an IP address.
From my example in the blog post:
define('HEARTBEAT', 'myCDNexample.com/heartbeat.html');
curl_setopt($ch, CURLOPT_URL, HEARTBEAT);
This works:
<?php
function getWeather() {
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip = $_SERVER['REMOTE_ADDR'];
}
$url = "http://api.hostip.info/get_html.php?ip=$ip";
define('LOCALE', $url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, LOCALE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
$geo = curl_exec($ch);
curl_close($ch);
if( preg_match('/City: (.*)\nIP:/', $geo, $matches) ){
$results = $matches[1];
}else{
$results = 'getLocation failure';
}
$location = urlencode($results);
$getAddress = "http://www.google.com/ig/api?weather=$location";
$xml_str = file_get_contents($getAddress,0);
$xml = new SimplexmlElement($xml_str);
$count = 0;
echo '<div id="weather">';
foreach($xml->weather as $item) {
foreach($item->forecast_information as $new) {
echo $new->city['data'];
}
foreach($item->current_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->condition['data'];
echo $new->temp_f['data'];
echo $new->temp_c['data'];
echo $new->humidity['data'];
echo $new->wind_condition['data'];
echo '</div>';
}
foreach($item->forecast_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->day_of_week['data'];
echo $new->condition['data'];
echo $new->low['data'];
echo $new->high['data'];
echo '</div>';
}
}
echo '</div>';
}
getWeather();
?>
Have I missed anything?
Neo
February 16, 2010, 3:50pm
12
Yes,
First of all, PHP define() is used for constants, not variables, so you can't use a variable to define a constant
Second, you are still using get_file_content() in another part of the script to get the contents of a URL. Change that to another curl() call. Maybe you can create a small function?
Remember, define() is only for constants. In my script, my URL is a constant, yours is a variable so you should not use define(). My code is example code and my example uses a constant, but your code uses a variable. (Hint: pass $url to curl(), not LOCALE).
---------- Post updated at 20:50 ---------- Previous update was at 20:40 ----------
For example.....
define('HOSTIP_QUERY', 'http://api.hostip.info/get_html.php?ip=');
// blah blah
$url = HOSTIP_QUERY.$ip;
curl_setopt($ch, CURLOPT_URL, $url);
define() statements (for constants) should be at the top of the script, or in a config file you read when the script start
o0110o
February 16, 2010, 4:55pm
13
neo:
Yes,
First of all, PHP define() is used for constants, not variables, so you can't use a variable to define a constant
Second, you are still using get_file_content() in another part of the script to get the contents of a URL. Change that to another curl() call. Maybe you can create a small function?
Remember, define() is only for constants. In my script, my URL is a constant, yours is a variable so you should not use define(). My code is example code and my example uses a constant, but your code uses a variable. (Hint: pass $url to curl(), not LOCALE).
---------- Post updated at 20:50 ---------- Previous update was at 20:40 ----------
For example.....
define('HOSTIP_QUERY', 'http://api.hostip.info/get_html.php?ip=');
// blah blah
$url = HOSTIP_QUERY.$ip;
curl_setopt($ch, CURLOPT_URL, $url);
define() statements (for constants) should be at the top of the script, or in a config file you read when the script start
This works:
<?php
define('QUERY_0', 'http://api.hostip.info/get_html.php?ip=');
define('QUERY_1', 'http://www.google.com/ig/api?weather=');
function getWeather() {
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip = $_SERVER['REMOTE_ADDR'];
}
$url0 = QUERY_0.$ip;
$ch0 = curl_init();
curl_setopt($ch0, CURLOPT_URL, $url0);
curl_setopt($ch0, CURLOPT_HEADER, 0);
curl_setopt($ch0, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch0, CURLOPT_FAILONERROR, TRUE);
$geo = curl_exec($ch0);
curl_close($ch0);
if( preg_match('/City: (.*)\nIP:/', $geo, $matches) ){
$results = $matches[1];
}else{
$results = 'getLocation failure';
}
$location = urlencode($results);
$url1 = QUERY_1.$location;
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, $url1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch1, CURLOPT_FAILONERROR, TRUE);
$xml_str = curl_exec($ch1);
curl_close($ch1);
$xml = new SimplexmlElement($xml_str);
echo '<div id="weather">';
foreach($xml->weather as $item) {
foreach($item->forecast_information as $new) {
echo $new->city['data'];
}
foreach($item->current_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->condition['data'];
echo $new->temp_f['data'];
echo $new->temp_c['data'];
echo $new->humidity['data'];
echo $new->wind_condition['data'];
echo '</div>';
}
foreach($item->forecast_conditions as $new) {
echo '<div class="weatherIcon">';
echo '<img src="http://www.google.com/' .$new->icon['data'] . '"/><br/>';
echo $new->day_of_week['data'];
echo $new->condition['data'];
echo $new->low['data'];
echo $new->high['data'];
echo '</div>';
}
}
echo '</div>';
}
getWeather();
?>
So how would I format the layout of the output page? See here:
Link Removed.
I just want to organize it better and label the output text (ie. Humidity, Conditions,Wind, etc...
Neo
February 16, 2010, 5:06pm
14
No idea.... I don't see any output from here.....
o0110o
February 16, 2010, 5:15pm
15
I just updated the URL to the demo. Try it now
Neo
February 16, 2010, 5:43pm
16
Hahahah.... enjoy styling.
Thread closed. (link removed)
Open another thread if you need scripting help.