Loop through results for a form

I’m trying to get a form to show all of the results from a table in the database so that they can be updated at the same time but it’s only showing one result.

I’ve getting all of the entries using this:

$query="select country_id,cost,country.id,country.name from country, shipping where country_id=country.id and owner_id=".$_GET['id'];
  $shipping=dbselect( $query,"dbPublic" );

which does work, but when I try to create the form I only get the last entry.

if( is_array( $shipping ) ) { 
  foreach( $shipping as $key=>$value ) {
  $FORM[$formid]['field']['owner_id']['type']="hidden";
  $FORM[$formid]['field']['owner_id']['value']=$_GET['id'];
  $FORM[$formid]['field']['country_id']['type']="hidden";
  $FORM[$formid]['field']['country_id']['value']=$value['country_id'];
  $FORM[$formid]['field']['cost']['label']=$value['name'];
  $FORM[$formid]['field']['cost']['type']="text";
  $FORM[$formid]['field']['cost']['autofocus']=true;
  $FORM[$formid]['field']['cost']['err']['notempty']=true;
  } }

Does anybody have any idea what I’m doing wrong?

I shouldn’t be commenting here, but are you selecting from two different tables ‘shipping’ and ‘country’?

That happening because you assign values to the same variables on each iteration of foreach loop

The names of the country are stored in a different table to the costs so that’s why I’m calling two different tables. Thanks for pointing it out though as I have made that mistake in the past! :confused:

How would I change it so that the same values aren’t being called every time? I’ve added a new field to the query but don’t know who to get that into the form.

The query is now:

$query="select shipping.id as shipping_id,country_id,cost,country.id,country.name from country, shipping where country_id=country.id and owner_id=".$_GET['id'];
  $shipping=dbselect( $query,"dbPublic" );

But when I try to change a field name to m_“.$value[‘country_id’].” I get a syntax error

The problem is not in the query

Look at this sample code:

foreach($array as $key=>$value){
    $a = $value;
}

What will be $a equals to after that loop? We re-assign (rewrite) this variable on each iteration, so after the loop $a will contain the last $value, right? You’re doing the same thing.

For example:

foreach( $shipping as $key=>$value ) {
    $FORM[$formid]['field']['owner_id']['type']="hidden";

$formid doesn’t change inside the loop, so that means you’re assigning value to the same variable each time. To store values of all rows you should use additional arrays:

if( is_array( $shipping ) ) { 
    $FORM[$formid]['field']['owner_id']['type'][] ="hidden"; //note the brackets []
    $FORM[$formid]['field']['owner_id']['value'][] =$_GET['id'];
    $FORM[$formid]['field']['country_id']['type'][] ="hidden";
    //..and so on...

After that you will be able to get values for each row separately:

echo $FORM[$formid]['field']['owner_id']['type'][0]; //first row
echo $FORM[$formid]['field']['owner_id']['type'][1]; //second row

I’m sorry I don’t quite understand what you mean, I changed it to

 if( is_array( $shipping ) ) { 
  $FORM[$formid]['field']['owner_id']['type'][]="hidden";
  $FORM[$formid]['field']['owner_id']['value'][]=$_GET['id'];
  $FORM[$formid]['field']['country_id']['type'][]="hidden";
  $FORM[$formid]['field']['country_id']['value'][]=$value['country_id'];
  $FORM[$formid]['field']['cost']['label'][]=$value['name'];
  $FORM[$formid]['field']['cost']['type'][]="text";
  $FORM[$formid]['field']['cost']['autofocus'][]=true;
  $FORM[$formid]['field']['cost']['err']['notempty'][]=true;
   }

but that gave me an error:

Warning: htmlspecialchars() expects parameter 1 to be string, array given in /home/global_func.inc on line 99

Line 99 is:

function htmldisplay( $string ) {
    $string=htmlspecialchars( $string,ENT_COMPAT | ENT_IGNORE,"UTF-8" );
    return $string;
  }

That’s right, you get an error because each of your variables is array now.

For example, you can’t do

echo htmldisplay($FORM[$formid]['field']['owner_id']['type']);

anymore, because it contains a set of values now, instead of just one
You have to use loop to print each of that values:

foreach($FORM[$formid]['field']['owner_id']['type'] as $value){
    echo $value;
}

I’m still confused, sorry it’s been a long week!

I tried doing this

  if( is_array( $shipping ) ) { 
  $FORM[$formid]['field']['owner_id']['type'][]="hidden";
  $FORM[$formid]['field']['owner_id']['value'][]=$_GET['id'];
  $FORM[$formid]['field']['country_id']['type'][]="hidden";
  $FORM[$formid]['field']['country_id']['value'][]=$value['country_id'];
  $FORM[$formid]['field']['cost']['label'][]=$value['name'];
  $FORM[$formid]['field']['cost']['type'][]="text";
  $FORM[$formid]['field']['cost']['autofocus'][]=true;
  $FORM[$formid]['field']['cost']['err']['notempty'][]=true;
   }
  echo $FORM[$formid]['field']['owner_id']['type'][]="hidden";
  echo $FORM[$formid]['field']['owner_id']['value'][]=$_GET['id'];
  echo $FORM[$formid]['field']['country_id']['type'][]="hidden";
  echo $FORM[$formid]['field']['country_id']['value'][]=$value['country_id'];
  echo $FORM[$formid]['field']['cost']['label'][]=$value['name'];
  echo $FORM[$formid]['field']['cost']['type'][]="text";
  echo $FORM[$formid]['field']['cost']['autofocus'][]=true;
  echo $FORM[$formid]['field']['cost']['err']['notempty'][]=true;

as well as this:

  if( is_array( $shipping ) ) { 
  $FORM[$formid]['field']['owner_id']['type'][]="hidden";
  echo $FORM[$formid]['field']['owner_id']['type'][]="hidden";
  $FORM[$formid]['field']['owner_id']['value'][]=$_GET['id'];
  echo $FORM[$formid]['field']['owner_id']['value'][]=$_GET['id'];
  $FORM[$formid]['field']['country_id']['type'][]="hidden";
  echo $FORM[$formid]['field']['country_id']['type'][]="hidden";
  $FORM[$formid]['field']['country_id']['value'][]=$value['country_id'];
  echo $FORM[$formid]['field']['country_id']['value'][]=$value['country_id'];
  $FORM[$formid]['field']['cost']['label'][]=$value['name'];
  echo $FORM[$formid]['field']['cost']['label'][]=$value['name'];
  $FORM[$formid]['field']['cost']['type'][]="text";
  echo $FORM[$formid]['field']['cost']['type'][]="text";
  $FORM[$formid]['field']['cost']['autofocus'][]=true;
  echo $FORM[$formid]['field']['cost']['autofocus'][]=true;
  $FORM[$formid]['field']['cost']['err']['notempty'][]=true;
  echo $FORM[$formid]['field']['cost']['err']['notempty'][]=true;
   }

but all that gave me was hidden1hiddentext11

That’s leaving you a sitting duck for sql injection attack as you’re letting user submitted data near the database without escaping it. You should be using prepared statements when dealing with user submitted data and you need to be validating the user submitted data.

If the id is a numeric then you could do:

$id = (int) $_GET['id'];

That would typecast $id as a numeric, if the value for id in the $_GET array isn’t a numeric then $id will be 0. You then pass $id on for either more validation or to go into a prepared statement.

The query uses an old outdated join syntax, assuming country_id is a field in the shipping table:

$query = "
SELECT
      shipping.country_id
    , cost
    , country.id
    , country.name
FROM
    country
INNER JOIN
    shipping
        ON shipping.country_id = country.id
WHERE
    owner_id=".$_GET['id'];

Which tables are the fields cost and owner_id in, try and get into the habbit of qualifying all fields when dealing with joins. What code are you using to get the results set from the database?

It’s on a secure site that only a handful of people can access so I don’t know if I still need to change the $_GET[‘id’] although I am using this:

if( empty( $_GET['id'] ) || !ctype_digit( $_GET['id'] ) ) { $error++; }

Also the cost and owner_id are both in the shipping table.

So are you saying I should be using join instead of doing the way I’m doing it?

that doesn’t matter.

if you’re lazy on secure environments then chances are that it rubs off to unsafe environments as well.

it’s best to never “learn” bad practices to begin with.

That is very true, thanks for the advice - I’ll use your method.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.