Forum Moderators: coopster

Message Too Old, No Replies

offset error

how to guard myself

         

kumarsena

5:32 pm on Nov 26, 2004 (gmt 0)

10+ Year Member



i get the followng offset errorin a script,

how can i gurad myekf against such error? are there any often used methods to deal with array errors of such kind?

Notice: Undefined offset: 2 in c:\program files\easyphp1-7\www\earthsoul\includes\comment.php on line 32

kumar

dreamcatcher

5:44 pm on Nov 26, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can easily stop the error messages by setting your error reporting to:

error_reporting (E_ALL ^ E_NOTICE);

kumarsena

6:00 pm on Nov 26, 2004 (gmt 0)

10+ Year Member



tnx

ergophobe

8:26 pm on Nov 26, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I hope this doesn't sound sarcastic, but dreamcatcher's solution would be analgous to someone saying "An oil pressure warning light keeps going on in my car. How do I fix it?" and the mechanic says "If you pull out the fuse that runs the warning light, it will stop coming on."

True enough, but what you've done is disabled an important warning system in your car and you've done nothing to fix the root problem. The best way to fix undefined ofset problems is by keeping error reporting set to report all errors, and then to change your code so you do not attempt to access array elements that are out of bounds.

That begs the question of how to avoid out of bounds array elements. There are two main causes

1. loops that run through too many iterations.

So you have an array that goes from $array[0] to $array[10] but you run through the loop too many times. For example, you know the array in this example has 11 elements, so you have a for loop like this

for ($i=1; $i<=11; $i++)

Because arrays are zero-indexed, when you get to $array[$i] where $i = 11, you will be out of bounds. This is a logic error that needs to be fixed or your script will not run predictably.

2. undefined variables.

PHP allows you to create variables dynamically, so in effect you are allowed to declare a variable by simply assigning a value to it. In other words, you don't have to do something like

integer $x;

before you use a variable. This makes it easy to get sloppy and not assign values, just depending on PHP to give a zero value for any undefined variable. That's a dangerous practice. You should always make sure a variable has been defined before you try to use it. You can do things like this.

a. create a variable by assigning a default value.
$x['some_el'] = 0;
That goes at the top of the script, so the variable is never undefined.

b. check the element before using it

if (!empty($x['some_el'])) { do something}

c. a combination - if we don't have a special value for it, we use the default:

$x['some_el'] = (empty($some_el))? 0 : $some_el;

Cheers,

Tom

dreamcatcher

11:39 pm on Nov 26, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



An oil pressure warning light keeps going on in my car. How do I fix it?" and the mechanic says "If you pull out the fuse that runs the warning light, it will stop coming on."

LOL! Only last week I said to my brother who`s a mechanic..."I have a warning light that keeps coming on on my dashboard, can you take the bulb out?"

No offence taken Tom. I understand what you are saying, but sometimes a quick fix is best.

:)

RedScourge

1:32 am on Nov 27, 2004 (gmt 0)

10+ Year Member



hey, ive got a question for ya guys...what does it mean when you get an offset error, then fix it by adding '' around the thing like ['thing'] and then all od a sudden you get "Undefined index: thing" after doing that?

im trying to install an open source game called 'promisance' i got from sourceforge, on a php 4.3.x apache server.

i can get most other php stuff to work fine, not this however, its full of stupid indexes and offset problems. few of these do this to me, but some of them do.

heres the sample code:

function saveUserData (&$user, $data)
{
global $playerdb, $lockdb;
if ($lockdb)
return;
$items = explode(" ",$data);
$update = "";
$i = 0;
while ($tmp = $items['$i++']) //here
{
$data = $user[$tmp];
if (is_numeric($data))
$update .= "$tmp='$data'";
else
{
sqlQuotes($data);
$update .= "$tmp='$data'";
}
if ($items['$i']){ //here
$update .= ",";
}
}
if (!mysql_query("UPDATE $playerdb SET $update WHERE num=$user[num];"))//DOESNT WORK!
print "FATAL ERROR: Failed to update player data $update for user #$user[num]!<!--prob1--><BR>\n";
}

when i have the '' around the '$i' values, the if at the bottom here fails to work too.

Salsa

2:40 am on Nov 27, 2004 (gmt 0)

10+ Year Member



The undefined offset means that the numerical index called for doesn't exist.

By putting quotes around it, you simply changed it to an associative index, which also doesn't exist.

From looking at the code you posted, you might expect to get undefined offsets when you

explode(" ",$data)
if there are spaces at the beginning or end of $data, or where it contains double spaces.

To get rid of possible white space at the ends, use

trim($data)
before exploding it.

To get rid of double spaces within $data, you might try something like

str_replace('__',' ',$data)
. If there are triple+ spaces, however, you'd have to repeat this. (Important: '__' means two spaces--extra spaces are removed when posting here.)

To see if this is even a problem, what you might do first is a test of $data to see if/how many double spaces it contains with

substr_count($data,'__')
. And if it is a problem, you could do something like:

while (substr_count($data,'__') > 0) str_replace('__',' ',$data);

Also, to your mysql_query(), I'd add the bold, below:

if (!mysql_query("UPDATE $playerdb SET $update WHERE num=$user[num];"))//DOESNT WORK! 
print "FATAL ERROR: Failed to update player data $update for user #$user[num]! [b]MySQL says : ".mysql_error()."[/b] <!--prob1--><BR>\n";

...so you know more about why it's failing.

I hope this helps.

RedScourge

2:51 am on Nov 27, 2004 (gmt 0)

10+ Year Member



awesome thanks, i hardly understand this code, but so far what ive seen when making it print the value of $update is theres no spaces, apparently, unless there is one at the end or beginning i didnt notice.

im sure this will help though, the mysql error thing i should have thought of on my own but im glad you did too. so thanx!

Salsa

3:17 am on Nov 27, 2004 (gmt 0)

10+ Year Member



When you print $update, is it an HTML output? HTML will also display only one of multiple spaces. Look at the HTML source to see the real output. And when you echo out $update, do it something like:

echo "\$update = '$update'<br>\n";

The '$update' part of it will put the variable in single quotes so you can see if there is a space at beginning or end.

Also, I meant to mention before that all of the ['$i'] indexes are numerical, so they should be [$i]. This might not cause a fatal error, but eliminating the '' is surely better..

RedScourge

4:57 am on Nov 27, 2004 (gmt 0)

10+ Year Member



yeah, i still get a pile of offset errors now, but they dont seem to do anything but make errors in my logfiles, i took the '' out like i thought it should be, and i also determined there was a mysql error that was causing the problem, it was only when i had the '' around the $i than the $update value didnt work. now the only offset errors i am getting are with the [$i] lines now, but as i said it doesnt seem to be doing anything wrong, so i dont know.

as for what $update contains, i get a bunch of username='x',password='x',id='x' etc, i dont think theres any spaces in that at all, if there are they are on the ends, and i used trim as you suggested to make sure theres no extra whitespace on the ends like that.

thanks for your suggestions, i still cant get the ofset erros to go away but i can live with em.

Salsa

6:13 am on Nov 27, 2004 (gmt 0)

10+ Year Member



Well, I misspoke. It's not $update that I wanted you to echo to see possible spaces, it was $data:

echo "\$data = '$data'<br>\n";

That's the variable that's being exploded to create the $items array. I got it right in my first post, but I slipped up on the next one. $update is the variable that results from the processing in the while loop.

But, that wasn't my only error. The reason I suspected spaces as the culprit behind the undefined offsets was that the boundry for the call to explode is a space. Meaning, if there are two spaces together, there would be nothing between them. However, it now seems that those "nothings" would create empty strings, not undefined offsets. So, I'm not sure what's going on here.

If you want to take a look inside the $items array, after the explode function try this:

?><pre><? print_r($items)?></pre><?

g'nite