Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

multiple foreach

Posted on 2012-08-26
22
Medium Priority
?
358 Views
Last Modified: 2012-08-28
what is the best way to run multiple foreach statements that would work for 2-20 foreach statements for example? I can't get it to work by doing something like this:

 foreach ($_POST['proddate'] as $proddate_insert) {

                                foreach ($_POST['tankno'] as $tankno_insert) {

                                                foreach ($_POST['primeactual'] as $primeactual_insert) {

so I assume there must be a better way?
Thanks.
0
Comment
Question by:jonofat
  • 11
  • 7
  • 3
  • +1
22 Comments
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 38334237
Can you please do this for us:

echo '<pre>'; var_dump($_POST);

Then post the output from that in the code snippet.  Once we see what the post array looks like we can help.

It would also be useful to post the URL of the page that has the HTML form (or just post the HTML form itself).

Thanks, ~Ray
0
 
LVL 20

Expert Comment

by:Mark Brady
ID: 38334240
Doing more than about 2 levels of foreach() can get confusing. I would do it using a normal for loop. First check to see if each of the posted items are set.

<?php

$proddate_insert = isset($_POST['proddate']) ? $_POST['proddate'] : null;
$tankno_insert = isset($_POST['tankno']) ? $_POST['tankno'] : null;
$primeactual_insert = isset($_POST['primeactual']) ? $_POST['primeactual'] : null;

if (!is_null($proddate) && !is_null($tankno_insert) && !is_null($primeactual_insert)) {
    // now we have checked everything you can start your outer loop...
    for ($i = 0; $i < count($proddate); $i ++) {
        // inner loop
        
        for ($j = 0; $j < count($tankno_insert); $j ++) {
            // another inner loop
            
            for ($k = 0; $k < count($primeactual_insert); $j ++) {
            // another inner loop
            
            }
        }
    }

}


?>

Open in new window


You can also do a foreach loop inside a normal for loop or vice-versa.
0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38334245
If you are collecting information in a 'record' type of way - i.e several inputs make up a record and you have multiple records, then naming your inputs as arrays is probably the way to go. Have a look at the code below - it groups each record into an array, so you can just foreach $_POST['record'] and grab the correct values.

<?php var_dump($_POST) ?>

<form method="post" action="">
	<input type="text" name="record[1][proddate]" />
	<input type="text" name="record[1][tankno]" />
	<input type="text" name="record[1][primeactual]" />
	<br />
	
	<input type="text" name="record[2][proddate]" />
	<input type="text" name="record[2][tankno]" />
	<input type="text" name="record[2][primeactual]" />
	<br />

	<input type="text" name="record[3][proddate]" />
	<input type="text" name="record[3][tankno]" />
	<input type="text" name="record[3][primeactual]" />
	<br />

	<input type="text" name="record[4][proddate]" />
	<input type="text" name="record[4][tankno]" />
	<input type="text" name="record[4][primeactual]" />
	<br />

	<input type="submit" name="submit" value="Go" />
</form>

<?php if (!empty($_POST)): ?>
<?php foreach ($_POST['record'] as $record): ?>
<ul>
	<li>Prod Date: <?php echo $record['proddate'] ?></li>
	<li>Tank No: <?php echo $record['tankno'] ?></li>
	<li>Prime Actual: <?php echo $record['primeactual'] ?></li>
</ul>
<?php endforeach; ?>
<?php endif; ?>

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:jonofat
ID: 38336096
Hi

The output for the code you asked me to use is:

array (size=10)
  'proddate' => string '2012-08-27' (length=10)
  'tankno' => string '504248' (length=6)
  'primeactual' =>
    array (size=5)
      0 => string '5' (length=1)
      1 => string '4' (length=1)
      2 => string '3' (length=1)
      3 => string '2' (length=1)
      4 => string '1' (length=1)
  'tcactual' =>
    array (size=5)
      0 => string '10' (length=2)
      1 => string '9' (length=1)
      2 => string '8' (length=1)
      3 => string '7' (length=1)
      4 => string '6' (length=1)
  'CHA' => string 'yes' (length=3)
  'CORr' => string 'yes' (length=3)
  'LEE' => string 'yes' (length=3)
  'DAN' => string 'yes' (length=3)
  'MON' => string 'yes' (length=3)
  'button' => string 'Submit' (length=6)


The foreach I have that works is:

foreach($_POST['primeactual'] as $pa) {
	 echo $pa . "<br />";

Open in new window


but I can't get it to work for the other fields, only using it once.


The form code is:

<form id="form1" name="form1" method="POST">
  <table width="1300" border="0" align="left" cellpadding="0" cellspacing="0">
    <tr>
      <td colspan="13" align="center" class="qualitytitles">&nbsp;</td>
    </tr>
    <tr>
      <td align="center" class="box"><strong>Date:</strong></td>
      <td align="center" class="box"><strong>Prod No.</strong></td>
      <td align="center" class="box"><strong>Job No.</strong></td>
      <td align="center" class="box"><strong>System</strong></td>
      <td align="center" class="box"><strong>Colour</strong></td>
      <td align="center" class="box"><strong>Prime Target</strong></td>
      <td align="center" class="box">Prime Actual</td>
      <td align="center" class="box"><strong>T/C Target</strong></td>
      <td align="center" class="box">T/C Actual</td>
      <td align="center" class="box">Prime</td>
      <td align="center" class="box">Astress</td>
      <td colspan="2" align="center" class="box">Final Coat</td>
    </tr>
    <?php do { ?>
      <tr>
        <td align="center" class="box"><span class="qualitytitles">
          <input name="proddate" type="text" id="proddate" value="<?php echo date("Y-m-d"); ?>" size="10" />
        </span></td>
        <td align="center" class="box"><label for="tankno"></label>
          <input name="tankno" type="text" id="tankno" value="<?php echo $row_Recordset1['tankno']; ?>" size="6" /></td>
        <td align="center" class="box"><?php echo $row_Recordset1['jobno']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['paintsystem']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['colour']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['primerconsumption']; ?></td>
        <td align="center" class="box"><label for="primeactual[]"></label>
        <input name="primeactual[]" type="text" id="primeactual[]" size="3" /></td>
        <td align="center" class="box"><?php $tex = $row_Recordset1['hempatexconsumption'];
$thane = $row_Recordset1['hempthaneconsumption'];
$sys =  $row_Recordset1['paintsystem'];
if ( $sys == 'Hempatex' ) {
	echo $tex;
} else {
	echo $thane;
} ?>
          &nbsp;</td>
        <td align="center" class="box"><input name="tcactual[]" type="text" id="tcactual[]" size="3" /></td>
        <td align="center" class="box">CHA
          <input name="CHA" type="checkbox" id="CHA" value="yes" />
          | COR
          <input name="CORr" type="checkbox" id="CORr" value="yes" />
          <label for="CHA"></label>
          <label for="CHA">| REID
            <input name="REID" type="checkbox" id="REID" value="yes" />
            | ROY
            <input name="ROY" type="checkbox" id="ROY" value="yes" />
          </label></td>
        <td align="center" class="box">LEE
          <input name="LEE" type="checkbox" id="LEE" value="yes" />
          | MANIS
          <input name="MANIS" type="checkbox" id="MANIS" value="yes" />
          <label for="LEE"></label>
          <label for="LEE"></label></td>
        <td align="center" class="box">DAN
          <input name="DAN" type="checkbox" id="DAN" value="yes" />
          <label for="DAN"></label>
          | MON
          <input name="MON" type="checkbox" id="MON" value="yes" />
          <label for="DAN"></label>
          | LES
          <input name="LES" type="checkbox" id="LES" value="yes" />
          <label for="DAN"></label>
          | MAR
          <input name="MAR" type="checkbox" id="MAR" value="yes" />
          <label for="DAN"></label></td>
        <td align="center" class="box">&nbsp;</td>
      </tr>
      <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
<tr>
      <td colspan="13" align="center" class="box"><input type="submit" name="button" id="button" value="Submit" /></td>
    </tr>
  </table>
</form>

Open in new window

0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38336126
The problem you're having is because most of your form inputs aren't named using an array, so you will only ever get one value back. If you have 5 fields all called 'proddate' you will still only get one value back.

As I said in my previous post, you need to name all of your fields as an array, and then you can loop through each record. Have a read through my first comment and adjust your field names. You can then get all the values you need by looping through just 1 array :)
0
 

Author Comment

by:jonofat
ID: 38336149
Hi ChrisStanyon

I am not sure if your method will work because I won't always have that number of text fields. The number of text fields is dependent on how many records are available from the database. So, tomorrow there might be 8 text fields. So, I am not sure your method would still work?

Yes, you are right about the form inputs, they are all meant to have [] next the form name ie:

<input name="proddate[]" type="text" id="proddate[]" value="<?php echo date("Y-m-d"); ?>" size="10" />
0
 

Author Comment

by:jonofat
ID: 38336188
Okay, so I got it to echo everything I input but it seems really cumbersome. Surely there is a neater way?

foreach($_POST['primeactual'] as $pa) {
	 echo $pa . "<br />";
	}
	foreach($_POST['tcactual'] as $ta) {
	 echo $ta . "<br />";
	}
	foreach($_POST['proddate'] as $pd) {
	 echo $pd . "<br />";
	}
	foreach($_POST['tankno'] as $tn) {
	 echo $tn . "<br />";
	}
	foreach($_POST['CHA'] as $cha) {
	 echo $cha . "<br />";
	}

Open in new window

0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38336221
My method will work no matter how many text fields you have - that's the point. You can set the array key dynamically using a simple counter ($i)

Here's a very trimmed down version of your looping code with named arrays:
<?php $i=0; do { ?>
<tr>
     <td><input type="text" name="record[<?php echo $i ?>][prodDate]" value="" /></td>
     <td><input type="text" name="record[<?php echo $i ?>][tankNo]" value="" /></td>
     <td><input type="text" name="record[<?php echo $i ?>][primeActual]" value="" /></td>
</tr>
<?php $i++; } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>

Open in new window

You can then loop through your data like so:

foreach ($_POST['record'] as $data) {
    echo $data['prodDate'];
    echo $data['tankNo'];
    echo $data['primeActual'];
}

Open in new window

0
 
LVL 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 400 total points
ID: 38336282
Experiment with this simplified example.  You may find the data easier to understand if we strip it down to just a few moving parts.
http://www.laprbass.com/RAY_temp_jonofat.php

<?php // RAY_temp_jonofat.php
error_reporting(E_ALL);
echo "<pre>";

var_dump($_POST);

$form = <<<ENDFORM
<form method="post">
Thing:
<input name="thing" />

Boxes:
<input type="checkbox" name=boxes[] value="A" />A
<input type="checkbox" name=boxes[] value="B" />B
<input type="checkbox" name=boxes[] value="C" />C

Named:
<input type="checkbox" name=boxes[X] />X
<input type="checkbox" name=boxes[Y] />Y
<input type="checkbox" name=boxes[Z] />Z

<input type="submit" />
</form>
ENDFORM;

echo $form;

Open in new window

Once you see what that does, try adding in a foreach() loop right after the var_dump().

HTH, ~Ray
0
 

Author Comment

by:jonofat
ID: 38336351
Okay, so I noticed that if you didn't give the checkbox a value it still shows that you checked it but just says "on". But the value seems to be in the brackets [x] [y] as opposed to it being blank like the others []

But then for the second set of check boxes you wouldn't be able to use

foreach ($_POST['boxes'] as $box) {
      echo $box;

because the value isn't just boxes[]

I tried what ChrisStanyon said by doing a foreach something like this:

foreach ($_POST['boxes'] as $data) {
      echo $data['X'];
        echo $data['Y'];
        echo $data['Z'];

but it didn't show any results?
0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38336436
If you've tried my code and it doesn't work then you're doing something wrong!

Try posting your code, or at least a simplified version of it.
0
 

Author Comment

by:jonofat
ID: 38336506
Okay, I am starting to get this. Have to leave now but will try again tomorrow.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 38338921
Add this one, wonderful statement to the top of all your scripts.  It will save you from many man-months of wasted time!

error_reporting(E_ALL);

0
 

Author Comment

by:jonofat
ID: 38339637
Thanks for the tip Ray, I have done so now :)

Okay, so, I have done this but it would seem that if I don't check a checkbox, I get errors. I will never check all the checkboxes but I need the options there. I don't know how to sort that out and I also want to insert all these records into the database. At the moment I have:

if (isset($_POST['Submit'])) { }
foreach ($_POST['record'] as $data) {
    echo $data['prodDate'] . "<br />";
	echo $data['tankno'] . "<br />";
	echo $data['primeactual'] . "<br />";
	echo $data['tcactual'] . "<br />";
	echo $data['CHA'] . "<br />";
	echo $data['COR'] . "<br />";
	echo $data['REID'] . "<br />";
	echo $data['ROY'] . "<br />";
	echo $data['LEE'] . "<br />";
	echo $data['MANIS'] . "<br />";
	echo $data['DAN'] . "<br />";
	echo $data['MON'] . "<br />";
	echo $data['LES'] . "<br />";
	echo $data['MAR'] . "<br />";
    
}

Open in new window


And then the form which I seem to have made a mess of :

<form id="form1" name="form1" method="POST">
  <table width="1300" border="0" align="left" cellpadding="0" cellspacing="0">
    <tr>
      <td colspan="13" align="center" class="qualitytitles">&nbsp;</td>
    </tr>
    <tr>
      <td align="center" class="box"><strong>Date:</strong></td>
      <td align="center" class="box"><strong>Prod No.</strong></td>
      <td align="center" class="box"><strong>Job No.</strong></td>
      <td align="center" class="box"><strong>System</strong></td>
      <td align="center" class="box"><strong>Colour</strong></td>
      <td align="center" class="box"><strong>Prime Target</strong></td>
      <td align="center" class="box">Prime Actual</td>
      <td align="center" class="box"><strong>T/C Target</strong></td>
      <td align="center" class="box">T/C Actual</td>
      <td align="center" class="box">Prime</td>
      <td align="center" class="box">Astress</td>
      <td colspan="2" align="center" class="box">Final Coat</td>
    </tr>
    <?php $i=0; do { ?>
      <tr>
        <td align="center" class="box"><span class="qualitytitles">
          <input name="record[<?php echo $i ?>][prodDate]" value="<?php echo date("Y-m-d"); ?>" />
        </span></td>
        <td align="center" class="box"><label for="tankno[]"></label>
          <input name="record[<?php echo $i ?>][tankno]" value="<?php echo $row_Recordset1['tankno']; ?>" size="6" /></td>
        <td align="center" class="box"><?php echo $row_Recordset1['jobno']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['paintsystem']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['colour']; ?></td>
        <td align="center" class="box"><?php echo $row_Recordset1['primerconsumption']; ?></td>
        <td align="center" class="box"><label for="primeactual[]"></label>
        <input name="record[<?php echo $i ?>][primeactual]" size="3" /></td>
        <td align="center" class="box"><?php $tex = $row_Recordset1['hempatexconsumption'];
$thane = $row_Recordset1['hempthaneconsumption'];
$sys =  $row_Recordset1['paintsystem'];
if ( $sys == 'Hempatex' ) {
	echo $tex;
} else {
	echo $thane;
} ?>
          &nbsp;</td>
        <td align="center" class="box"><input name="record[<?php echo $i ?>][tcactual]" size="3" /></td>
        <td align="center" class="box">CHA
          <input name="record[<?php echo $i ?>][CHA]" type="checkbox" value="yes" />
          | COR
          <input name="record[<?php echo $i ?>][COR]" type="checkbox" value="yes" />
          <label for="CHA"></label>
          <label for="CHA">| REID
            <input name="record[<?php echo $i ?>][REID]" type="checkbox" value="yes" />
            | ROY
            <input name="record[<?php echo $i ?>][ROY]" type="checkbox" value="yes" />
        </label></td>
        <td align="center" class="box">LEE
          <input name="record[<?php echo $i ?>][LEE]" type="checkbox" value="yes" />
          | MANIS
          <input name="record[<?php echo $i ?>][MANIS]" type="checkbox" value="yes" />
          <label for="LEE"></label>
          <label for="LEE"></label></td>
        <td align="center" class="box">DAN
          <input name="record[<?php echo $i ?>][DAN]" type="checkbox" value="yes" />
          <label for="DAN"></label>
          | MON
          <input name="record[<?php echo $i ?>][MON]" type="checkbox" value="yes" />
          <label for="DAN"></label>
          | LES
          <input name="record[<?php echo $i ?>][LES]" type="checkbox" value="yes" />
          <label for="DAN"></label>
          | MAR
          <input name="record[<?php echo $i ?>][MAR]" type="checkbox" value="yes" />
          <label for="DAN"></label></td>
        <td align="center" class="box">&nbsp;</td>
      </tr>
      <?php $i++; } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
<tr>
      <td colspan="13" align="center" class="box"><input type="hidden" name="MM_insert" value="form1" />        <input type="submit" name="button" id="button" value="Submit" /></td>
    </tr>
  </table>
</form>

Open in new window

0
 

Author Comment

by:jonofat
ID: 38339645
Doing something like this isn't going to work as I can't put $data for all the values...

$insertSQL = "INSERT INTO actualproduction(proddate, tankno, primeactual, tcactual, CHA, COR, REID, ROY, LEE, MANIS, DAN, MON, LES, MAR) VALUES ($data, $data)";

Open in new window


So, I'm a bit stuck :(
0
 
LVL 45

Accepted Solution

by:
Chris Stanyon earned 1600 total points
ID: 38340259
OK. A few points. When you submit a checkbox, it only exists in the POST array if the checkbox is ticked. If it isn't ticked, then it doesn't exist so unless you check for that you will get errors - use the isset function.

Secondly, your Insert statement should be inserting the values, not the array. Use sprintf to generate your SQL statement and the execute that.

Thirdly, in your code, you are checking if POST['submit'] is set but then doing nothing - { }. The foreach loop needs to go inside of the braces, not after them.

Have a look at this code, and ask if you have any questions.

error_reporting(E_ALL);
ini_set('display_errors', 1);

if (!empty($_POST)) {
	foreach ($_POST['record'] as $data) {
		$insertSQL = sprintf(
		"INSERT INTO actualproduction (proddate, tankno, primeactual, tcactual, CHA, COR, REID, ROY, LEE, MANIS, DAN, MON, LES, MAR) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
			$data['prodDate'],
			$data['tankno'],
			$data['primeactual'],
			$data['tcactual'],
			(isset($data['LEE'])) ? $data['LEE'] : "Not Set",
			(isset($data['COR'])) ? $data['COR'] : "Not Set",
			(isset($data['REID'])) ? $data['REID'] : "Not Set",
			(isset($data['ROY'])) ? $data['ROY'] : "Not Set",
			(isset($data['LEE'])) ? $data['LEE'] : "Not Set",
			(isset($data['MANIS'])) ? $data['MANIS'] : "Not Set",
			(isset($data['DAN'])) ? $data['CAN'] : "Not Set",
			(isset($data['MON'])) ? $data['MON'] : "Not Set",
			(isset($data['LES'])) ? $data['LES'] : "Not Set",
			(isset($data['MAR'])) ? $data['MAR'] : "Not Set"
		);
		
		echo $insertSQL;
		//execute your sql statement here
	}                                            
};

Open in new window

0
 

Author Comment

by:jonofat
ID: 38340291
ChrisStanyon, you are a legend!! :)

That works beautifully. Okay, I have bought myself a PHP book to try and get away from relying on dreamweaver which can only do so much but I just have one question.

I thought ('%s','%s') was a dreamweaver thing but I see you are also using it. So, how do you know when to use that and when not to use it and how do you know when to use sprintf?

Thanks again for your help.
0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38340322
Pleased you got it working. You're right to move away from Dreamweaver - it's terrible at creating code, and often bloats it into meaningless garbage. Write your own code from scratch - you'll learn a lot quicker and have much cleaner, faster code :)

sprintf returns a formatted string, and % acts as a placeholder. %s indicates a string while %d acts as a place holder for an integer. There are others..

echo sprintf("There are %d monkeys in the %s", 4, "trees");
There are 4 monkeys in the trees

$num = 7;
$place = "zoo";
echo sprintf("There are %d monkeys in the %s", $num, $place);
There are 7 monkeys in the zoo

Here's the man page for it: http://php.net/manual/en/function.sprintf.php
0
 

Author Comment

by:jonofat
ID: 38340341
Great, thanks for the help!
0
 

Author Comment

by:jonofat
ID: 38340361
I forgot something... I want to ask another question but it is related to this. I am going to post a new question, please check it out if you can.
0
 
LVL 45

Expert Comment

by:Chris Stanyon
ID: 38340370
No worries. Once you've posted it, post a link to it here. I'll get notified then :)
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The title says it all. Writing any type of PHP Application or API code that provides high throughput, while under a heavy load, seems to be an arcane art form (Black Magic). This article aims to provide some general guidelines for producing this typ…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

564 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question