I have a cron that pulls an xml api from a gaming website.
Cron then tears the data apart and places the information into the proper section of database. The code was written by someone else in 2010 or 2011. I have been trying to bread new life to old script since orignal writer has not kept the code up to date. When i run my cron i recieve the following error.
key1
Warning: min() [function.min]: Array must contain at least one element in /home3/banumren/public_html/ratter/ratter/cron.php on line 95
Warning: max() [function.max]: Array must contain at least one element in /home3/banumren/public_html/ratter/ratter/cron.php on line 95
[ 0 ] (0 %) - 0 / 0 (beforeRefID: )
* [cachedUntil=2014-05-15 01:19:46 (time-api-taken: 2014-05-15 01:04:46]) ]
wallet.dates = ( to )
The line in question :
<br> * wallet.dates = ( ".$dates1[ min($dates) ]." to ".$dates1[ max($dates) ]." ) \n<br>\n
The whole section of code is as follows.
}
$cachedUntil = (string)$wallet_xml->cachedUntil;
$currentTime = (string)$wallet_xml->currentTime;
print "<b>".$corpName." [ $corpId ] ($corpTax %) "." - $add_wallet_rows / $cnt (beforeRefID: {$beforeRefID}) </b>
<i> <br> * [cachedUntil={$cachedUntil} (time-api-taken: {$currentTime}]) ]
<br> * wallet.dates = ( ".$dates1[ min($dates) ]." to ".$dates1[ max($dates) ]." ) \n<br>\n
</i> ";
$ret = array(
'min' => null, //#min( $RefIDs ) ,
'max' => null, //#max( $RefIDs ) ,
'cnt' => count($RefIDs) ,
'currentTime' => (string)$wallet_xml->currentTime ,
'cachedUntil' => $cachedUntil ,
);
if( $ret['cnt'] ) {
$ret['min'] = min( $RefIDs );
$ret['max'] = max( $RefIDs );
}
return $ret;
}
Any ideas as to what could be causing the error? It seems the cron is pulling the api as it has the time values for cached until and current time. The code worked without issues in 2011, Im a novice at php and not sure if there have been any changes to php in the past few years.
could this be the culprit?
$cnt = 0;
$RefIDs = null;
$dates = $dates1 = array();
foreach( (array)#$xml['row'] as $row ) {
$cnt++;
Removed (array) and no longer receive the error. Now on to another line. at line 180 of 202 so hopefully will have it bug free soon.
Error at line 180 was a missing function from function php.
[14-May-2014 21:33:50] PHP Fatal error: Call to undefined function clear_directory_files_older()
Fixed the error by adding code below to functions.php
function clear_directory_files_older($directory,$older_sec,$ext='*') {
$glob = $directory."*.{$ext}";
$removed = 0;
$array = glob( $glob );
foreach( $array as $file ) {
$filemtime = filemtime($file);
if( $filemtime < ( time()-$older_sec ) ) {
// print "\n<br>OLD => ".( $file ); print "<br>".date('r',$filemtime);
#unlink( $file );
$removed++;
} else {
// print "\n<br>NEW => ".( $file );
}
}
return $removed;
In fixing the new error on 180 the original error returned on line 95
After more searching I walked into the cache folder to have a look around. Seems the issue with the error is the API on the website has changed so much i was not pulling any valid data. After update to the API address cron is now pulling data and updating the cache files correctly. Error no longer occurs.
Related
This question already has an answer here:
PCRE2 Regex error escape sequence is invalid in character class
(1 answer)
Closed 2 years ago.
Our website with error turned on (plugin activated):
Example URLs with error:
https://www.live-karikaturen.ch/downloads/1-august-fahnen-schwingen-nationalfeiertag-schweiz/
https://www.live-karikaturen.ch/webshop-gratisbilder-free-cartoon-comic-images/
https://www.live-karikaturen.ch/downloads/auto-suv-autofan-abgase-umweltverschmutzung/
UPDATE INCOMPATIBILITY: I updated from a very old PHP version to 7.4
I use this EXTREMLY important plugin, which is horrible outdated (4 years last Update):
https://wordpress.org/support/plugin/creative-commons-configurator-1/
Now I get this error and I think it's maybe very easy to solve, but I know almost nothing about PHP, but I try to learn it a bit, so thank you very much in advance.
ERROR:
*
Warning: preg_match_all(): Compilation failed: escape sequence is
invalid in character class at offset 18 in
/home/clients/f9abb707fe4ac1215fe0f0a9c0b0ae21/www.live-karikaturen-ch/wp-content/plugins/creative-commons-configurator-1/creative-commons-configurator-1.php
on line 821
I copy the code from the .php file here
CODE:This is line 821:
if ( ! preg_match_all( $pattern_images_no_caption, $post_content, $matches ) ) {
return $post_content;
}
CODE From line 803 - 828 (don't know who to copy the line numbers):
function bccl_separate_licensing_on_images_without_caption( $post_content ) {
// Plugin options
$options = get_option('cc_settings');
if ( $options === false || $options['cc_enable_individual_media_licensing'] == '0' ) {
return $post_content;
}
$post = get_queried_object();
if ( apply_filters('bccl_exclude_license', false, $post) ) {
return $post_content;
}
// Pattern that matches images without caption
//$pattern_images_no_caption = '#<p>[\s\R]*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>[\s\R]*(<img [^>]+>)#';
$pattern_images_no_caption = apply_filters('bccl_pattern_match_images_without_caption' , $pattern_images_no_caption);
**if ( ! preg_match_all( $pattern_images_no_caption, $post_content, $matches ) ) {
return $post_content;
}**
//var_dump($matches[1]);
// Iterate over the found images and add licensing metadata
foreach ( $matches[1] as $image_html ) {
Is there a simple way how to fix this error?
THANK YOU VERY MUCH FOR YOUR ANSWER & HELP!
THAAAANK you very much, you are AMAZING! :) I tried it out and it works, at least there is no error anymore.
FIRST
I am just not sure which version of the corrected code I should take. I guess Nr. 1 is ok, without []. That mean, as Toto wrote above I replaced [\s\R] with a simple \s.
Nr. 1.) without []
//$pattern_images_no_caption = '#\s*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>\s*(<img [^>]+>)#';
Nr. 2.) with []
//$pattern_images_no_caption = '#<p>[\s]*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>[\s]*(<img [^>]+>)#';
SECOND
I searched the whole creative-commons-configurator.php plugin code for \R and found further in line 979 this:
$parts = preg_split('#\R#u', $attach`enter code here`ment_data);
All lines together of this part are this:
// Attachment ID
// Unfortunately, WP does not provide enough information in order to determine the attachment ID
// So, first collect all the audio/video media file URLs in $attachments_urls
$attachments_data = get_post_meta( $post->ID, 'enclosure', false );
//var_dump($attachments_data);
$attachments_urls = array();
foreach ( $attachments_data as $attachment_data ) {
$parts = preg_split('#\R#u', $attachment_data);
$attachments_urls[] = $parts[0];
}
//var_dump($attachments_urls);
// Then check which media file URL exists in the $atts array so as to
// determine which attachment we are processing currently.
$atts_values = array_values($atts);
//var_dump($atts_values);
// Find the URL of the attachment we are processing
$current_attachment_url = '';
foreach ( $attachments_urls as $attachment_url) {
if ( in_array($attachment_url, $atts_values) ) {
$current_attachment_url = $attachment_url;
break;
}
}
QUESTION: In the moment I don't get any error, but I wonder if this will produce one and I have to delete or replace the "evil" \R?
I am having the foreach loop that will run minimum 2000 loops
foreach ($giftCardSchemeData as $keypreload => $preload) {
for ($i=0; $i <$preload['quantity'] ; $i++) {
$cardid = new CarddetailsId($uuidGenerator->generate());
$cardnumber = self::getCardNumber();
$cardexistencetype = ($key == "giftCardSchemeData") ? "Physical" : "E-Card" ;
$giftCardSchemeDataDb = array('preload' => array('value' => $preload['value'], 'expirymonths' => $preload['expiryMonths']));
$otherdata = array('cardnumber' => $cardnumber, 'cardexistencetype' => $cardexistencetype, 'isgiftcard' => true , 'giftcardamount' => $preload['value'],'giftCardSchemeData' => json_encode($giftCardSchemeDataDb), 'expirymonths' => $preload['expiryMonths'], 'isloyaltycard' => false, 'loyaltypoints' => null,'loyaltyCardSchemeData' => null, 'loyaltyRedeemAmount' => null, 'pinnumber' => mt_rand(100000,999999));
$output = array_merge($data, $otherdata);
// var_dump($output);
$carddetailsRepository = $this->get('oloy.carddetails.repository');
$carddetails = $carddetailsRepository->findByCardnumber($cardnumber);
if (!$carddetails) {
$commandBus->dispatch(
new CreateCarddetails($cardid, $output)
);
} else {
self::generateCardFunctionForErrorException($cardid, $output, $commandBus);
}
}
}
Like above foreach I am having totally 5 of them. When I call the function each time the 5 foreach runs and then return the response. It take more time and the php maximum execution time occurs.
Is there a any way to send the response and then we could run the foreach in server side and not creating the maximum execution time issue.Also need an optimization for the foreach.
Also In symfony I have tried the try catch method for the existence check in the above code it return the Entity closed Error. I have teprorily used the existence check in Db but need an optimization
There seems to be a lot wrong (or to be optimized) with this code, but let's focus on your questions:
First I think this code shouldn't be in code that will be triggered by a visitor.
You should seperate 2 processes:
1. A cronjob that runs that will generate everything that must be generated and saved that generated info to a database. The cronjob can take as much time as it needs. Look at Symfony's console components
2. A page that displays only the generated info by fetching it from the database and passing it to a Twig template.
However, looking at the code you posted I think it can be greatly optimized as is. You seem to have a foreach loop that fetches variable data, and in that you have a for-loop that does not seem to generate much variability at all.
So most of the code inside the for loop is now being executed over and over again without making any actual changes.
Here is a concept that would give much higher performance. Ofcourse since I don't know the actual context of your code you will have to "fix it".
$carddetailsRepository = $this->get('oloy.carddetails.repository');
$cardexistencetype = ($key == "giftCardSchemeData") ? "Physical" : "E-Card";
foreach ($giftCardSchemeData as $keypreload => $preload) {
$cardnumber = self::getCardNumber();
$carddetails = $carddetailsRepository->findByCardnumber($cardnumber);
$giftCardSchemeDataDb = array('preload' => array('value' =>
$preload['value'], 'expirymonths' => $preload['expiryMonths']));
$otherdata = array('cardnumber' => $cardnumber, 'cardexistencetype' =>
$cardexistencetype, 'isgiftcard' => true , 'giftcardamount' =>
$preload['value'],'giftCardSchemeData' =>
json_encode($giftCardSchemeDataDb), 'expirymonths' =>
$preload['expiryMonths'], 'isloyaltycard' => false, 'loyaltypoints' =>
null,'loyaltyCardSchemeData' => null, 'loyaltyRedeemAmount' => null,
'pinnumber' => 0);
$output = array_merge($data, $otherdata);
for ($i=0; $i <$preload['quantity'] ; $i++) {
$cardid = new CarddetailsId($uuidGenerator->generate());
$output['pinnumber'] = mt_rand(100000,999999);
if (!$carddetails) {
$commandBus->dispatch(
new CreateCarddetails($cardid, $output)
);
} else {
self::generateCardFunctionForErrorException($cardid, $output, $commandBus);
}
}
}
Also: if in this code you are triggering any database inserts or updates, you don't want to trigger them each iteration. You will want to start some kind of database transaction and flush the queries each X iterations instead.
I am trying to create RRD graphs with the help of PHP in order to keep track of the inoctets,outoctets and counter of a server.
So far the script is operating as expected but my problems comes when I am trying to produce 2 or more separate graphs. I am trying to produce (hourly, weekly , etc) graphs. I thought by creating a loop would solve my problem, since I have split the RRA in hours and days. Unfortunately I end up having 2 graphs that updating simultaneously as expected but plotting the same thing. Has any one encounter similar problem? I have applied the same program in perl with RRD::Simple,where is extremely easy and everything is adjusted almost automatically.
I have supplied under a working example of my code with the minimum possible data because the code is a bit long:
<?php
$file = "snmp-2";
$rrdFile = dirname(__FILE__) . "/snmp-2.rrd";
$in = "ifInOctets";
$out = "ifOutOctets";
$count = "sysUpTime";
$step = 5;
$rounds = 1;
$output = array("Hourly","Daily");
while (1) {
sleep (6);
$options = array(
"--start","now -15s", // Now -10 seconds (default)
"--step", "".$step."",
"DS:".$in.":GAUGE:10:U:U",
"DS:".$out.":GAUGE:10:U:U",
"DS:".$count.":ABSOLUTE:10:0:4294967295",
"RRA:MIN:0.5:12:60",
"RRA:MAX:0.5:12:60",
"RRA:LAST:0.5:12:60",
"RRA:AVERAGE:0.5:12:60",
"RRA:MIN:0.5:300:60",
"RRA:MAX:0.5:300:60",
"RRA:LAST:0.5:300:60",
"RRA:AVERAGE:0.5:300:60",
);
if ( !isset( $create ) ) {
$create = rrd_create(
"".$rrdFile."",
$options
);
if ( $create === FALSE ) {
echo "Creation error: ".rrd_error()."\n";
}
}
$t = time();
$ifInOctets = rand(0, 4294967295);
$ifOutOctets = rand(0, 4294967295);
$sysUpTime = rand(0, 4294967295);
$update = rrd_update(
"".$rrdFile."",
array(
"".$t.":".$ifInOctets.":".$ifOutOctets.":".$sysUpTime.""
)
);
if ($update === FALSE) {
echo "Update error: ".rrd_error()."\n";
}
$start = $t - ($step * $rounds);
foreach ($output as $test) {
$final = array(
"--start","".$start." -15s",
"--end", "".$t."",
"--step","".$step."",
"--title=".$file." RRD::Graph",
"--vertical-label=Byte(s)/sec",
"--right-axis-label=latency(min.)",
"--alt-y-grid", "--rigid",
"--width", "800", "--height", "500",
"--lower-limit=0",
"--alt-autoscale-max",
"--no-gridfit",
"--slope-mode",
"DEF:".$in."_def=".$file.".rrd:".$in.":AVERAGE",
"DEF:".$out."_def=".$file.".rrd:".$out.":AVERAGE",
"DEF:".$count."_def=".$file.".rrd:".$count.":AVERAGE",
"CDEF:inbytes=".$in."_def,8,/",
"CDEF:outbytes=".$out."_def,8,/",
"CDEF:counter=".$count."_def,8,/",
"COMMENT:\\n",
"LINE2:".$in."_def#FF0000:".$in."",
"COMMENT:\\n",
"LINE2:".$out."_def#0000FF:".$out."",
"COMMENT:\\n",
"LINE2:".$count."_def#FFFF00:".$count."",
);
$outputPngFile = rrd_graph(
"".$test.".png",
$final
);
if ($outputPngFile === FALSE) {
echo "<b>Graph error: </b>".rrd_error()."\n";
}
} /* End of foreach function */
$debug = rrd_lastupdate (
"".$rrdFile.""
);
if ($debug === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
var_dump ($debug);
$rounds++;
} /* End of while loop */
?>
A couple of issues.
Firstly, your definition of the RRD has a step of 5seconds and RRAs with steps of 12x5s=1min and 300x5s=25min. They also have a length of only 60 rows, so 1hr and 25hr respectively. You'll never get a weekly graph this way! You need to add more rows; also the step seems rather short, and you might need a smaller-step RRA for hourly graphs and a larger-step one for weekly graphs.
Secondly, it is not clear how you're calling the graph function. You seem to be specifying:
"--start","".$start." -15s",
"--end", "".$t."",
"--step","".$step."",
... which would force it to use the 5s interval (unavailable, so the 1min one would always get used) and for the graph to be only for the time window from the start to the last update, not a 'hourly' or 'daily' as you were asking.
Note that the RRA you have defined do not define the time window of the graph you are asking for. Also, just because you have more than one RRA defined, it doesnt mean you'll get more than one graph unless oyu call the graph function twice with different arguments.
If you want a daily graph, use
"--start","end - 1 hour",
"--end",$t,
Do not specify a step as the most appropriate available will be used anyway. For a daily graph, use
"--start","end - 1 day"
"--end",$t,
Similarly, no need to specify a step.
Hopefully this will make it a little clearer. Most of the RRD graph options have sensible defaults, and RRDTool is pretty good at picking the correct RRA to use based on the graph size, time window, and DEF statements.
Thanks in advance for your time and effort. This is my first script with PHP and RRD's. While I was writing a short program for SNMP I came across with RRD a powerful tool for graphical output. I tried to wright a short operating script to imitate the output of a graph. I read as much as possible documentations regarding RRD from the official page and tried to add them to my PHP code. I have found some functions while I was trying to debug my code which are showing that my data are coming in normally and cased on reference as expected. Sample provided under:
["last_update"]=>
int(1396917542)
["ds_cnt"]=>
int(3)
["ds_navm"]=>
array(3) {
[0]=>
string(10) "ifInOctets"
[1]=>
string(11) "ifOutOctets"
[2]=>
string(9) "sysUpTime"
}
["data"]=>
array(3) {
[0]=>
string(4) "1405"
[1]=>
string(4) "1219"
[2]=>
string(4) "1893"
}
}
Based on function:
"$debug = rrd_lastupdate (
"".$rrdFile.""
);"
I am having difficulties to understand since the input is coming correctly and there is not print error displayed while compiling my code why I do not get any output?
I have included my working code as example for possible reproduction and better understanding of my error.
<?php
// rrdtool info /var/www/snmp.rrd Debugging command
while (1) {
sleep (1);
$file = "snmp";
$rrdFile = dirname(__FILE__) . "/".$file.".rrd";
$in = "ifInOctets";
$out = "ifOutOctets";
$count = "sysUpTime";
$options = array(
"--start","now -10s", // Now -10 seconds (default)
"--step", "10", // Step size of 300 seconds 5 minutes
"DS:".$in.":COUNTER:20:U:U",
"DS:".$out.":COUNTER:20:U:U",
"DS:".$count.":COUNTER:20:U:U",
/* DS:ds-name:DST:dst arguments
(DST: GAUGE, COUNTER, DERIVE, and ABSOLUTE):heartbeat:min:max
heartbeat: in case that there is not input up to 600 seconds
then the input will characterised as undefined (blank)
Based on Nyquist rate (Fs >= 2 * Fmax) 300 (step) 600 (heartbeat)
32-bit = 2^32-1 = 4294967295 (counter ticks)
64-bit = 2^64-1 = 18446744073709551615 (counter ticks)
64-bit counter (caution!!!) different oid's
*/
"RRA:MIN:0.5:10:300",
"RRA:MIN:0.5:20:600",
"RRA:MAX:0.5:10:300",
"RRA:MAX:0.5:20:600",
"RRA:AVERAGE:0.5:10:300",
"RRA:AVERAGE:0.5:20:600",
/* RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows
xff range: 0-1 (exclusive) defines the allowed number of unknown
*UNKNOWN* PDPs to the number of PDPs in the interval. Step defines
how many of those data points are used to build consolidated data.
rows defines how many data values are kept in an RRA.
*/
);
//create rrd file
$create = rrd_create(
"".$rrdFile."",
$options
);
if ($create === FALSE) {
echo "Creation error: ".rrd_error()."\n";
}
$ifInOctets = rand(0, 1500); // ifInOctets (OID: 1.3.6.1.2.1.2.2.1.10)
$ifOutOctets = rand(0, 2500); // ifOutOctets (OID: 1.3.6.1.2.1.2.2.1.16)
$sysUpTime = rand(0, 2000); // sysUpTime (OID: 1.3.6.1.2.1.1.3)
$t = time();
//update rrd file
$update = rrd_update(
"".$rrdFile."",
array(
/* Update database with 3 values
based on time now (N:timestamp) */
"".$t.":".$ifInOctets.":".$ifOutOctets.":".$sysUpTime.""
)
);
if ($update === FALSE) {
echo "Update error: ".rrd_error()."\n";
}
$start = "now";
$title = "Hourly Server Data";
$final = array(
"--start","".$start." -10s",
"--step","10",
"--title=".$title."",
"--vertical-label=Bytes/sec",
"--lower-limit=0",
//"--no-gridfit",
"--slope-mode",
//"--imgformat","EPS",
"DEF:".$in."_def=".$file.".rrd:".$in.":AVERAGE",
"DEF:".$out."_def=".$file.".rrd:".$out.":AVERAGE",
"DEF:".$count."_def=".$file.".rrd:".$count.":AVERAGE",
"CDEF:inbits=".$in."_def,8,*",
"CDEF:outbits=".$out."_def,8,*",
"CDEF:counter=".$count."_def,8,*",
/* "VDEF:".$in_min."=inbits,MINIMUM",
"VDEF:".$out_min."=outbits,MINIMUM",
"VDEF:".$in_max."=inbits,MAXIMUM",
"VDEF:".$out_max."=outbits,MAXIMUM",
"VDEF:".$in_av."=inbits,AVERAGE",
"VDEF:".$out_av."=outbits,AVERAGE", */
"COMMENT:\\n",
"LINE:".$in."_def#FF00FF:".$in."",
"GPRINT:inbits:LAST:last \: %6.2lf %SBps",
"COMMENT:\\n",
"LINE:".$out."_def#0000FF:".$out."",
"GPRINT:outbits:LAST:last \: %6.2lf %SBps",
"COMMENT:\\n",
"LINE:".$count."_def#FFFF00:".$count."",
"GPRINT:counter:LAST:last\: %6.2lf %SBps",
"COMMENT:\\n",
);
// graph output
$outputPngFile = rrd_graph(
"".$file.".png",
$final
);
if ($outputPngFile === FALSE) {
echo "<b>Graph error: </b>".rrd_error()."\n";
}
/* Returns the first data sample from the
specified RRA of the RRD file. */
$result = rrd_first (
$rrdFile,
$raaindex = 0
);
if ($result === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
/* Returns the UNIX timestamp of the most
recent update of the RRD database. */
$last = rrd_last (
$rrdFile
);
if ($last === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
$info = rrd_info (
"".$rrdFile.""
);
if ($info === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
/* Gets array of the UNIX timestamp and the values stored
for each date in the most recent update of the RRD database file. */
$debug = rrd_lastupdate (
"".$rrdFile.""
);
if ($debug === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
var_dump ($debug);
/* $version = rrd_version ( );
echo "This is the version ".$version."\n"; */
} // End of while condition
?>
There are a lot of issues in your code.
Firstly, your RRD file is apparently re-created in every iteration of your While loop! This will overwrite the previous loop's update.
Secondly, although you create the RRD with a step size of 10, you are not doing a sleep(10) at the end of each update loop. You cannot update the RRD more frequently than the Step size.
Thirdly, you have used a COUNTER type for the DS, which assumes an constantly increasing count. However your test data are random numbers and so not increasing. A decrease may be taken as a counter wraparound, so a huge number, which is outside the valid range for your DS - and hence an Unknown is stored.
Fourthly, you need to have two consecutive updates for a Counter to have a valid rate; you are overwriting your RRD file each iteration and so never manage to get this.
Fifthly, your smallest RRA being defined has a COunt of 10; this means you need 10 data points to make a single consolidated pointin the RRA. With a Step of 10sec, this means you need to run for 110sec (11 updates) before you even have a single data point to plot. You should probably try adding a Count 1 RRA.
And finally, your graph is being requested for a 10 second time window. This is less than one RRA sample. Remember, you r Step is 10s and your smallest RRA is count=10, so a consolidated step of 100s.
I suggest you fix the loop so that the create comes outside; make the sleep equivalent to the RRD step; add a Count 1 AVG RRA; and make your graph request for a longer time window.
I have a php script that interacts with the google weather api.Everything works ok, but if I test it with a false location like "blahblah" I get a slew of errors in the browser despite having some validation in my script. The php code is as follows:
<?php
function googleWeather($location){
$url = "http://www.google.com/ig/api?weather=" . urlencode($location);
$xml = simplexml_load_file($url);
$current_conditions = $xml->xpath("/xml_api_reply/weather/current_conditions");
$temp_c = $current_conditions[0]->temp_c['data'];
$temp_f = $current_conditions[0]->temp_f['data'];
$result = sprintf("Current temperature is %s° Celsius %s° Fahrenheit",$temp_c,$temp_f);
return $result;
}
$loc = "blahblah";
$goog = googleWeather($loc);
if($goog == false){
echo "An error occurred";
}
else{
echo $goog;
}
?>
The error that is rendered in the browser is as follows:
( ! ) Notice: Undefined offset: 0 in C:\wamp2\www\phpAcademy\GoogleWeatherApi\TMP5c2a1z4emd.php on line 11
Call Stack
# Time Memory Function Location
1 0.1086 370080 {main}( ) ..\TMP5c2a1z4emd.php:0
2 0.1086 370184 googleWeather( ) ..\TMP5c2a1z4emd.php:23
( ! ) Notice: Trying to get property of non-object in C:\wamp2\www\phpAcademy\GoogleWeatherApi\TMP5c2a1z4emd.php on line 11
Call Stack
# Time Memory Function Location
1 0.1086 370080 {main}( ) ..\TMP5c2a1z4emd.php:0
2 0.1086 370184 googleWeather( ) ..\TMP5c2a1z4emd.php:23
( ! ) Notice: Undefined offset: 0 in C:\wamp2\www\phpAcademy\GoogleWeatherApi\TMP5c2a1z4emd.php on line 12
Call Stack
# Time Memory Function Location
1 0.1086 370080 {main}( ) ..\TMP5c2a1z4emd.php:0
2 0.1086 370184 googleWeather( ) ..\TMP5c2a1z4emd.php:23
( ! ) Notice: Trying to get property of non-object in C:\wamp2\www\phpAcademy\GoogleWeatherApi\TMP5c2a1z4emd.php on line 12
Call Stack
# Time Memory Function Location
1 0.1086 370080 {main}( ) ..\TMP5c2a1z4emd.php:0
2 0.1086 370184 googleWeather( ) ..\TMP5c2a1z4emd.php:23
Google returns the following for an invalid location
<xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0"><problem_cause data=""/></weather></xml_api_reply>
This xml doesnt have the element "current_conditions" inside "weather". Thats casusing the error.
Check if exists then proceed which can be done with some thing like
if($current_conditions){
// you code here
} else {
return false;
}
I replaced blahblah with real city and it started to work.
Probably you enter your city address with wrong syntax.
Try to change your location, for example Zurich
The errors are pretty self-explanatory, $current_conditions doesn't contain what you think it does:
$current_conditions = $xml->xpath("/xml_api_reply/weather/current_conditions");
$temp_c = $current_conditions[0]->temp_c['data'];
// ^^^ undefined index
$temp_f = $current_conditions[0]->temp_f['data'];
// ^^^ Trying to access property of non object
You are not validating the result of $current_conditions:
if (is_array($current_conditions) && isset($current_conditions[0]))
{
$temp_c = $current_conditions[0]->temp_c['data'];
$temp_f = $current_conditions[0]->temp_f['data'];
}
Furthermore, you may need to validate the existence of the object properties, as well as the existence of the data key in those properties:
if (is_array($current_conditions) && isset($current_conditions[0]))
{
$cur = $current_conditions[0];
if (isset($cur->temp_c) && isset($cur->temp_c['data']))
{
$temp_c = $cur->temp_c['data'];
}
if (isset($cur->temp_f) && isset($cur->temp_f['data']))
{
$temp_f = $cur->temp_f['data'];
}
}
This is quite verbose, but to be absolutely sure to avoid these notices - it's what you have to do. You can and should turn off error reporting once you go live with your application. Notices are meant to help you debug code, if you understand how they're being generated and can safely ignore them, it may be OK.
And, if you feel confident that you know the API will return FALSE for an invalid query, just check if $current_conditions === FALSE and you can skip all the extra validation.