Forum Moderators: coopster

Message Too Old, No Replies

Undefined offset error: Please help!

Undefined offset problem in php

         

rafal2020

8:38 pm on Nov 24, 2008 (gmt 0)

10+ Year Member



Hello, I am getting this error.

Notice: Undefined offset: 139 in /var/www/vhosts/example.net/httpdocs/test2/locksmiths_ca.php on line 124

Here is my php code:

<?php

$col=0;
$rows=mysql_num_rows($result);
for ($i=0; $i<$rows; $i++) {
$arr[$i]=mysql_result($result,$i,$col);
}

$i=0;

// break array over rows
print '<table border=0 width=780 bgcolor=#FFFFFF>';
while($i <= count($arr)) {
// row of five items
print '<tr>';
for($r=1;$r<=4;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
print '<tr><td height=20></td></tr>';
print '</table>';
?>

Also, this error does not appear through my XAMPP localhost on a windows machine but only shows up the live server.

Can anyone please help?

[edited by: eelixduppy at 9:48 pm (utc) on Nov. 24, 2008]
[edit reason] exemplified [/edit]

cameraman

9:43 pm on Nov 24, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome to Webmaster World, rafal2020.

If you have a zero-based continguous array, the elements are 0-x. count($arr) will yield x + 1. This statement, then, will always produce that notice on its last pass:
while($i <= count($arr)) {

Remove the = sign.

rafal2020

10:16 pm on Nov 24, 2008 (gmt 0)

10+ Year Member



Thanks for the welcome, cameraman.

I tried that and still no dice?

cameraman

10:30 pm on Nov 24, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You need to check to make sure you're not running off the end of the array here:
for($r=1;$r<=4;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}

rafal2020

12:29 am on Nov 25, 2008 (gmt 0)

10+ Year Member



Yes this is exactly where the problem is.

print '<td>'. $arr[$i] .'</td>';

is on line 124.

Just to see what happened I tried:

print '<td>'. $arr[$i+1] .'</td>';

and got two errors.

and this:

print '<td>'. $arr[$i-1] .'</td>';

and also got two errors.
I'll try this when I go back to work tomorrow:

$rows=mysql_num_rows($result)-1;

eeek

2:19 am on Nov 25, 2008 (gmt 0)

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



while($i <= count($arr))

Why are you doing a count there? You already have the number in $rows.

while($i <= count($arr)) {
// row of five items
print '<tr>';
for($r=1;$r<=4;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}

You are incrementing $i five times for each row. But you only have $rows items in $arr. I'm guessing that what you really want to do is print an entire row from the database results, but you are only fetching the first column.

You should also to the printing inside the mysql fetch loop; there's no need to store the entire result set in memory and it's not good practice to do so unless you have a very good reason.

Simpler version:

while ($row=mysql_fetch_row($result) {
print("<tr>");
foreach ($row as $col) print("<td>$col</td>");
print("</tr>\n");
}

rafal2020

4:58 am on Nov 25, 2008 (gmt 0)

10+ Year Member



cameraman and eeek thanks for your time so far.

@eeek.
The point of this code is to pull 1 entry from a row in the table where the state = 'X'.

Specifically, each row in the db has a 'state', a 'town' and an 'url' column and other columns that are irrelevant.

I'm using:
SELECT url FROM table_name WHERE state='X' order by town

so I want to populate a table with only the 'url's in a certain state.

this loop:
while($i <= count($arr)) {
// row of five items
print '<tr>';
for($r=1;$r<=4;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}

will print 4 urls in one row and then create another and do the same until all the entries in the db are expired.

Or however many I specify in &r<=X;
($r=1;$r<=4;$r++)

The result looks like this:
URL1 URL2 URL3 URL4
URL5 URL6 URL7 URL8
and so on.

The problem is [I believe] that the count is always one higher than the number of rows which have the state I want.

I have to keep my result within a certain width. In this case 780px.

I think that your php will print one <tr> [table row] with all the entries in it? Am I correct?

cameraman

6:52 am on Nov 25, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



it's not good practice to do so
Could you point me at where to find that? I'm apparently not coming up with effective search terms. It would seem to me that it's a non-issue unless the data is rather large, and even when I'm not putting several datasets together or manipulating them in some way I'm using a template engine so it's going into memory anyway - I wonder if that statement was published some time ago when memory was much more expensive. Come to think of it, doesn't a server generally map a script's execution and output into memory space until the script finishes execution and it's time to transmit the document?

rafal2020, I think you may be running into cases where you have something other than multiples of 4 - you need to provide for the possibility of 1-3 empty table cells. Instead of doing inner loops, I generally make use of the modulus operator (and you can use your pre-existing counter for this):
$i = 0;
$cols = 4;
while {
if(!($i%$cols))
echo "<tr>\n";
echo "<td>$data</td>\n";
$i++;
if(!($i%$cols))
echo "</tr>\n";
} // EndWhile doing data
// Fill in blank cells:
if($i%$cols) {
while(($i++)%$cols)
echo "<td>&nbsp;</td>\n";
echo "</tr>\n";
} // EndIf need to fill in row

rafal2020

7:01 pm on Dec 2, 2008 (gmt 0)

10+ Year Member



Sorry for not responding for a while. This issue has been put to the side while some other stuff got done. Now that I am back to it I am getting an error with the syntax.

Parse error: syntax error, unexpected '{', expecting '(' in C:\xampp\htdocs\_test_pages\test_table3.php on line 26

This is the whole php I am running.

<?php
$con = mysql_connect("X", "X", "X");

$sql = "SELECT x FROM tableX WHERE state = 'XX' order by town;";
$result = mysql_db_query("X",$sql);
$data = mysql_db_query("X",$sql);

if (!$result ¦¦ mysql_num_rows($result) < 1) {

print mysql_error() . ' ERROR - SELECT note query failed! ';
}

// break array over rows
print '<div align=center>';
$i = 0;
$cols = 4;
while {
if(!($i%$cols)) {
echo "<tr>\n";
echo "<td>$data</td>\n";
$i++;
if(!($i%$cols))
echo "</tr>\n";
} // EndWhile doing data
// Fill in blank cells:
if($i%$cols) {
while(($i++)%$cols)
echo "<td>&nbsp;</td>\n";
echo "</tr>\n";
} // EndIf need to fill in row
print '</div>';
?>

Am I placing your code correctly?

rafal2020

7:36 pm on Dec 2, 2008 (gmt 0)

10+ Year Member



I figured it out! Thanks for all your help, this is my final code!

// get result into array
$col=0;
$rows=mysql_num_rows($result);
for ($i=0; $i<$rows; $i++) {
$arr[$i]=mysql_result($result,$i,$col);
}

// devide $rows by number of desired columns and round down
$rowdiv = floor($rows / 4);
//echo $rowdiv;
//print '<br />';

// get the remainder from $rowdivs
$remainder = $rows / 4 - floor($rows / 4);
//echo $remainder;
//print '<br />';

$lastrow = $remainder * 4;
//echo $lastrow;

$i=0;

// break array over rows
print '<div align=center>';
print '<table border=0 width=90\%>';
while($i <= $rowdiv * 4 -1) {
// row of four items
print '<tr>';
for($r=1;$r<=4;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
while($i <= $rows - $lastrow) {
// row of four items
print '<tr>';
for($r=1;$r<=$lastrow;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
print '</table>';
print '</div>';

jatar_k

7:41 pm on Dec 2, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



just a thought

if you have a large array you will be walking it twice which will always be slower than doing it in one pass right out of the db.

rafal2020

9:00 pm on Dec 2, 2008 (gmt 0)

10+ Year Member



@jatar_k: I don't know what you mean?

Please also be advised. This solution does not work with odd numbers?
It will cause an infinite loop to occur and the browser will crash.

Here is the code I am now using.

// get result into array
// warning do not set $mycols to an odd number
$mycols=4;
$rows=mysql_num_rows($result);
for ($i=0; $i<$rows; $i++) {
$arr[$i]=mysql_result($result,$i);
}

// devide $rows by number of desired columns and round down
$rowdiv = floor($rows / $mycols);

// get the remainder from $rowdiv
$remainder = $rows / $mycols - $rowdiv;

// determine the amount of entries in last row
$lastrow = $remainder * $mycols;

$i=0;

// break array over rows
print '<div align=center>';
print '<table border=0 width=528>';
while($i <= $rowdiv * $mycols -1) {
// row of five items
print '<tr>';
for($r=1;$r<=$mycols;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
while($i <= $rows - $lastrow) {
// row of five items
print '<tr>';
for($r=1;$r<=$lastrow;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
print '</table>';
print '</div>';

rafal2020

9:39 pm on Dec 2, 2008 (gmt 0)

10+ Year Member



OK. I found another problem. For states where the number is divisible by $mycols and has a remainder of 0 the last while loop also runs infinitely.

So I was able to fix that with an if...else

// get result into array
// warning do not set $mycols to an odd number
$mycols=4;
$rows=mysql_num_rows($result);
for ($i=0; $i<$rows; $i++) {
$arr[$i]=mysql_result($result,$i);
}

// devide $rows by number of desired columns and round down
$rowdiv = floor($rows / $mycols);
echo $rowdiv;
echo '<br />';

// get the remainder from $rowdiv
$remainder = $rows / $mycols - $rowdiv;
echo $remainder;
echo '<br />';

// determine the amount of entries in last row
$lastrow = $remainder * $mycols;
echo $lastrow;
echo '<br />';

$i=0;

// break array over rows
print '<div align=center>';
print '<table border=0 width=528>';
while($i <= $rowdiv * $mycols -1) {
// row of five items
print '<tr>';
for($r=1;$r<=$mycols;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
if ($lastrow == 0) {
print '</table>';
print '</div>';
} else {
while($i <= $rows - $lastrow) {
// row of five items
print '<tr>';
for($r=1;$r<=$lastrow;$r++) {
print '<td>'. $arr[$i] .'</td>';
$i++;
}
print '</tr>';
}
print '</table>';
print '</div>';
}

jatar_k

7:08 pm on Dec 4, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



you could try this code

[webmasterworld.com...]