Problem with nested foreach loops

Hi everyone,

can someone please help me with the following: I am displaying the values from two select menus, and the value of the second select menu needs to be displayed in the output of the first select menu.

The results would look like this:

Amy’s computer store ($key1)
Location: Chicago ($value1)
Stock: 5 computers ($value2)

Jack’s computer store ($key1)
Location: New York ($value1)
Stock: 3 computers ($value2)

Thank you in advance.


if (isset($_POST['stores'])){
foreach($_POST['stores'] as $key1 => $value1 ) {

echo ''.$key1.'<br>'.$value1.' ';

}
}

if (isset($_POST['computers'])){
foreach($_POST['computers'] as $key2 => $value2 ) {

echo $value2;
}
}

Can you expand more on the source of the variables $key1, $value1 and $value2? Have they come from a HTML <select> clause or from a query, or elsewhere? Perhaps post the code, and say what’s going wrong.

Also those foreach() loops aren’t nested - you would need to have one within the other for them to be nested. Perhaps that’s the issue - if you’ve done a query, maybe the pseudo-code should be something like


foreach computer-store
   display store information
   display location information
   foreach computer in computer-store
      count computer
      end foreach
   display stock of computers
end foreach

Hi again droopsnoot,

thanks for assisting me with this!

This is how the source code looks like. I’m looping out a certain user’s stores and the store’s stock of computers - this is just a silly example. I used location in my original example but number of employees is more appropriate.

<select name="employees[amy store]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>

<select name="computers[amy store]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>

<select name="employees[jack store]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>

<select name="computers[jack store]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>

The code on the receiving page will print out:

Amy's computer store ($key1)
Number of employees ($value1)

Jack's computer store ($key1)
Number of employees ($value1)

Stock: 5 computers ($value2)
Stock: 3 computers ($value2)

but I’m trying to get this result:

Amy's computer store ($key1)
Number of employees ($value1)
Number of computers ($value2)

Jack's computer store ($key1)
Number of employees ($value1)
Number of computers ($value2)

Thank you.

Hi everyone,

I’m still stuck big time!

All of the select menus belong to a certain computer store, so I’m trying to print out all of that store’s values - in such a way that the information is grouped together. I tried the following but I don’t know beforehand which store’s select menus will be selected. Must I use a while loop?

Please advise. Thanks!

if (isset($_POST['employees']['amy store']) OR $_POST['computers']['amy store']){

  echo ''.$_POST['employees']['amy store'].' employees';
  echo'<br>';
   echo ''.$_POST['computers']['amy store'].' computers';


 echo '<br>';
}

It’s a little hard to follow where info is coming from or what you are trying to do but I’ll give you this sample which might help.

<?php
// Going on the assumption that you are getting info from database table.  Fields store, employees, computers.
$stores = array(
	"store" => array("Amy","Jack","Joe"),
	"employees" => array(3,4,6),
	"computers" => array(2,3,5)
);

//echo "<pre>";
//print_r($stores);
//echo "</pre>";

$display = "";
$display .= "<form action=\\"\\" method=\\"post\\">\\r";
foreach($stores['store'] as $k => $v){

$display .= "<div style=\\"float:left; text-align:center; padding:5px;\\">\\r";

	// Set some variables
	$Name = "{$stores['store'][$k]}";
	$StoreName = "$Name's Store";
	$num_employees = "{$stores['employees'][$k]}";
	$num_computers = "{$stores['computers'][$k]}";
	
	$display .= "<b>$StoreName</b><br />\\r";
	$display .= "Employees <select name=\\"employees[$Name]\\">\\r";
	for($x=0;$x<=$num_employees;$x++){
		$display .= "<option value=\\"$x\\">$x</option>\\r";
	}
	$display .= "</select><br />\\r";
	
	$display .= "Computers <select name=\\"computers[$Name]\\">\\r";
	for($c=0;$c<=$num_computers;$c++){
		$display .= "<option value=\\"$c\\">$c</option>\\r";
	}
	$display .= "</select><br />\\r";
	$display .= "</div>\\r";
	
}

$display .= "<div style=\\"clear:both;\\"></div>\\r";
$display .= "<input type=\\"submit\\" value=\\"Show\\" />\\r";

$display .= "</form>\\r";

//Show POST results
if(isset($_POST['employees'])){
	foreach($_POST['employees'] as $name => $employees){
		$computers = $_POST['computers'][$name];
		$display .= "<p>$name's computer store<br />
		Number of employees: $employees<br />
		Number of computers: $computers</p>\\r";
	}
}
?>
<html>
<body>
<?php
if(isset($display)){ echo $display; }
?>
</body>
</html>

The results are like this.

Amy’s computer store
Number of employees: 2
Number of computers: 1

Jack’s computer store
Number of employees: 3
Number of computers: 2

Joe’s computer store
Number of employees: 5
Number of computers: 4

Hi Drummin,

thank you so much! :slight_smile:

It is working as I had hoped it would work. You’ve put a lot of effort into your example, so thank you again.

Just when I think that I’ve reached a dead-end there’s someone on these forums who’s willing to help me out, which is a relief otherwise this website would never get finished.

Hi again Drummin,

sorry to bother, but if you or someone else has a moment, could you please have a look at my validation code?

The stores and associated select menus are dynamically generated. In order to proceed to the next page, the two select menus of at least one store need to be selected. The code I have works, but only when I select the menus of the last generated store. I also need to test the actual sending of the values to the other page.

I hope you can help me… thanks!


if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors = array();
	
foreach($_POST['employees'] as $k => $v){
if($_POST['employees'][$k] == 0 ){
$employees = FALSE;
$errors['employees'] = 'Please select the number of employees.';
}
else {
    $employees = filter_var($_POST['employees'][$k], FILTER_SANITIZE_STRING);
    }
}

foreach($_POST['computers'] as $k2 => $v2){
if($_POST['computers'][$k2] == 0 ){
$computers = FALSE;
$errors['computers'] = 'Please select the number of computers.';
}
else {
    $computers = filter_var($_POST['computers'][$k2], FILTER_SANITIZE_STRING);
    }
}
	

	
if ($employees && $computers) {
header("location: page2.php");
exit ();	
}

}

Well lets sort a few things out. There’s a big loophole in your logic here, but some pointers:

#1: We dont need 2 foreach loops.


foreach($_POST['employees'] as $k => $v){ 

#2: The number of employees entered is now $v, so we dont need to look it up again.


if($_POST['employees'][$k] == 0 ){ 

=>

if($v == 0 ){ 

#3: Check both conditions simultaneously; either combine both into one (losing precision on the error), or stack and negate the ifs.


if($v == 0 || $_POST['computers'][$k] == 0){ 

(Loses precision; note that we can reference the other section of the array by the same key.)


if($v == 0 ){ $errors[] = "Please select the number of employees for ".$k; continue; }
if($_POST['computers'][$k] == 0) { $errors[] = "Please select the number of computers for ".$k; continue; }

(Using continue; breaks the current execution of the loop and goes for the next value.)

However; what you’re (currently) REALLY intending to do is replace this whole code with this instead:


if(isset($_POST['employees']) && array_sum($_POST['employees']) != 0 && array_sum($_POST['computers']) != 0) {
  header('Location: page2.php');
  exit();
}

or, if the need is for specificity:


if(isset($_POST['employees'])) {
  if (array_sum($_POST['employees']) == 0) { exit("Please enter at least 1 store's employees.");
  if (array_sum($_POST['computers']) == 0) { exit("Please enter at least 1 store's computers.");
  header('Location: page2.php');
  exit("Redirecting you");
}

Thank you for your help StarLion. :slight_smile:

Do you know what I can do about the following?

Each store has 2 select menus and both need to have a value other than 0 before the page can be redirected. At the moment redirection will occur if one store’s employee menu is selected and another store’s computers menu is selected.

Thanks!

Ok…


if(isset($_POST['employees']) && count(array_intersect_keys(array_filter($_POST['employees']),array_filter($_POST['computers']))) > 0) {

Thanks, let me try that out.

Thank you for your assistance, it is working.

When I first tried it out there was an error because the function should be array_intersect_key and not array_intersect_keys.

Sorry to bother again :rolleyes: but I’m still having a few issues with the code.

Both select menus of any given stores need to have positive values(a positive integer), before the form can be submitted. At present I can submit the form when both of storeA’s select menus have positive values, while only the first select menu of storeB has a positive value. I hope that makes sense!

I appreciate your assistance!

Thanks.

You keep changing your requirements.

Spell out ALL of your requirements, and we may be able to help you.

Hi StarLion,

You keep changing your requirements.

Spell out ALL of your requirements, and we may be able to help you.

Sorry about that, but I’m designing my first website, so I don’t know beforehand what will or won’t work. I’ll have to try something out and if there are problems, look for a solution. I apologise if I inconvenience anyone.

Well you came in and said “In order to proceed to the next page, the two select menus of at least one store need to be selected”, so you were given code that checked to make sure that at least one of each were selected. Then you came back and said “Each store has 2 select menus and both need to have a value other than 0 before the page can be redirected. " so that combined with the first statement is that at least 1 store has both employees and computers. Then you’ve come back and said " I’m still having a few issues with the code.”

You arnt having issues with the code, you’re having issues with you havent figured out what you actually want the form to DO. You havent done the pre-code work of figuring out what it is you want. You can make the code do (just about) anything… as long as you’ve planned ahead.

Fine, if anyone wishes to help me with this then please let me know. I don’t have any other requirement at present.

Thank you in advance.

Both select menus of any given stores need to have positive values(a positive integer), before the form can be submitted. At present I can submit the form when both of storeA’s select menus have positive values, while only the first select menu of storeB has a positive value.