473,398 Members | 2,120 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Nested foreach loop for array comparison driving me crazy.

2
Hi,

I'm new, so please let me know if any of my forum etiquette is wrong! Apologies for the fairly nondescript subject line, but I am being driven insane by it.

Anyhow, I have a form with multiple checkboxes that need to be sticky, so I check the checkbox $_POST array against the array of form elements using a nested foreach loop. The trouble is, that when the form is submitted, even though all the checked boxes are in the $_POST array, only the final matching checkbox is checked.

Hopefully, this code will help:

The data:

Expand|Select|Wrap|Line Numbers
  1. $areas = array("Brierley_Hill" => "Brierley Hill","Cradley_Heath" => "Cradley Heath",    "Dudley" => "Dudley" ,"Gornal" => "Gornal","Halesowen" => "Halesowen","Kingswinford" => "Kingswinford","Netherton" => "Netherton","Oldbury" => "Oldbury","Pensnett" => "Pensnett","Quarry_Bank" => "Quarry Bank","Rowley_Regis" => "Rowley Regis","Stourbridge" => "Stourbridge","Tipton" => "Tipton","Tividale" => "Tividale");
  2.  
The function to create the checkbox portion of the form:

Expand|Select|Wrap|Line Numbers
  1.  
  2. function doTownCheckBoxes($areas){
  3.  
  4.     foreach($areas as $value => $area){
  5.  
  6.         foreach($_POST['Towns'] as $town){
  7.  
  8.                         $checked = ($town==$value) ? "checked" : "";
  9.  
  10.         }
  11.  
  12.     $html.= '<li><input type="checkbox" name="Towns[]" value="'.$value.'" '.$checked.'> '.$area.'</li>';
  13.  
  14.     }
  15.  
  16.     return $html;
  17.  
  18. }
  19.  
  20.  
Now, I imagine there's some coding horrors in there (like cleaning and escaping the POST data before use, which I promise I'll do!), and if you could point them out to me, I'd be most grateful.

What it's supposed to do (in my mind) is loop thorough the whole of the $areas array, then for each entry, loop through the $_POST array, see if there's a match, write "checked" into the html and start again. However, it doesn't, and I don't understand why.

Any help would be very much appreciated.
Jan 30 '10 #1
2 4428
Atli
5,058 Expert 4TB
Hey.

The problem there is that you set the $checked variable for every loop, so if the first element in the $_POST array matches the current town, $checked is set accordingly. However, when the next element is checked, it won't match and the $checked variable is reset to be empty.

What you need to do is break out of the loop when a match is found, or otherwise prevent the iterations following a match from resetting the variable.

Consider this:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. function doTownCheckBoxes($areas)
  3. {
  4.     foreach($areas as $value => $area)
  5.     {
  6.         // This is a basic security measure, to prevent
  7.         // things like XSS. Most variables that are
  8.         // to be printed into a HTML page should be
  9.         // run through this function.
  10.         $value = htmlspecialchars($value, ENT_QUOTES, "UTF-8");
  11.         $area = htmlspecialchars($area, ENT_QUOTES, "UTF-8");
  12.  
  13.         // Reset $checked for each area. If you
  14.         // do not do this, the results of the previous
  15.         // iteration may "bleed" through.
  16.         $checked = "";
  17.  
  18.         foreach($_POST['Towns'] as $town)
  19.         {
  20.             if($town==$value)
  21.             {
  22.                 // Here the variable is only set if
  23.                 // there is a match. If there is not
  24.                 // a match, it is left unaltered.
  25.                 $checked = "checked";
  26.  
  27.                 // This breaks out of the current loop,
  28.                 // ending the look for matches.
  29.                 // We have already establised there is
  30.                 // a match. No need to go though the rest
  31.                 // of them.
  32.                 break;
  33.             }
  34.         }
  35.         $html.= '<li><input type="checkbox" name="Towns[]" value="'.$value.'" '.$checked.'> '.$area.'</li>';
  36.     }
  37.     return $html;
  38. }
  39. ?>
You could also use the in_array function to replace the inner foreach loop.
Expand|Select|Wrap|Line Numbers
  1. if(in_array($value, $_POST['Towns'])) 
  2. {
  3.     $checked = "checked";
  4. }
  5. else 
  6. {
  7.     $checked = "";
  8. }
  9. $html.= '<li><input type="checkbox" name="Towns[]" value="'.$value.'" '.$checked.'> '.$area.'</li>';
So you could reduce the entire thing down to just a few lines:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. function doTownCheckBoxes($areas)
  3. {
  4.     foreach($areas as $value => $area)
  5.     {
  6.         $value = htmlspecialchars($value, ENT_QUOTES, "UTF-8");
  7.         $area = htmlspecialchars($area, ENT_QUOTES, "UTF-8");
  8.  
  9.         $checked = (in_array($value, $_POST['Towns'])) ? "checked" : "";
  10.  
  11.         $html.= '<li><input type="checkbox" name="Towns[]" value="'.$value.'" '.$checked.'> '.$area.'</li>';
  12.     }
  13.     return $html;
  14. }
  15. ?>
Hope that helps :)
Jan 30 '10 #2
gomako
2
Thankyou very very much for your quick response, and taking the time to break it all down and comment it, I really appreciate it.

The in_array() function is a nice new function for me! There are so many useful functions out there, it will take a while to figure them out I think! It'll also save another loop of loops. :-)

I see now that the problem was in setting and resetting the $checked variable over and over. Thanks as well for the security pointers.
Jan 30 '10 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: Randell D. | last post by:
Folks, Ever since reading an interesting article in Linux Format on PHP whereby suggested code writing was made that could enhance performance on a server, I've started testing various bits of...
34
by: sushant | last post by:
hi all, suppose i have 2 loops one inside the other, like this 1) for(i=0;i<=100;i++) { for(j=0;j<=10;j++) { some code; }
4
by: V. Jenks | last post by:
What seems like a simple thing is apparently not so straightforward? I have a datalist. Inside of that datalist is an <itemtemplate> secion which contains other server controls such as a...
25
by: GY2 | last post by:
I writing some documentation and I want to describe a common code structure which is used to step through all the items in a collection (e.g. each file in a subdirectory) while applying more and...
1
by: levidicom | last post by:
foreach($test as $var1){ foreach($test2 as $var2) { echo '"var1: " . $var1 . "<br>"var2: " . $var2 . "<br> \n"'; }
1
by: levidicom | last post by:
foreach($test as $var1){ foreach($test2 as $var2) { echo '"var1: " . $var1 . "<br>"var2: " . $var2 . "<br> \n"'; }
1
by: TSmith | last post by:
Hey Y'all, I haven't programmed in PHP in quite a while. Could anyone help me with a foreach loop in a nested array? I have a function which returns $stock (for an online pricing catalog). ...
1
by: Perl Beginner | last post by:
I hope i can articulate this question properly. i have been trying to figure this out for over a week. I am comparing the contents of two files, but the comparison is done inside of a foreach...
5
by: Ivan S | last post by:
I'm using next snippet: $somearray = array(...); foreach($somearray as $item1) { foreach($item1 as $item2) { // ... do something ... } }
3
by: numlock00 | last post by:
I have a nested 'while' loop that won't repeat, no matter how many times the outer loop repeats. The outer loop reads through an array of elements; the inner loop Ithe 'while' loop) is supposed to...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.