Jump to content

[SOLVED] Really strange behavior from foreach in PHP5


natbur

Recommended Posts

My site is running PHP5 and I'm getting some weird behavior from my foreach loop.

 

I have a form that users fill in data into text boxes and submit. An array is created from the text boxes(the print_r is below):

 

Array (
  [TextBox1] => Array ( 
                                [name] => TextBox1 
                                [value] => ...someText... 
                                [show] => 1 
                                [required] => 1 
                                [text] => ...enteredText1...
                               )
  [TextBox2] => Array ( 
                                [name] => TextBox2 
                                [value] => ...someMoreText... 
                                [show] => 1 
                                [required] => 1 
                                [text] => ...enteredText2...
                               )
  [TextBox3] => Array ( 
                                [name] => TextBox3 
                                [value] => ...evenMoreText... 
                                [show] => 1 
                                [required] => 1 
                                [text] => ...enteredText3...
                               )
  [TextBox4] => Array ( 
                                [name] => TextBox4 
                                [value] => ...LastBitOfText... 
                                [show] => 1 
                                [required] => 1 
                                [text] => ...enteredText4...
                               )
)

 

The loop that processes this array is:

 

foreach($TextBoxData as $text)
{
  if($text['text']!= "")
  {
    $msg .= "- In Response to: \n";
    $msg .= " ".filter_text($text['value'], "nohtml")." \n";
    $msg .= " - They said: \n";
    $msg .= " ".filter_text($text['text'], "nohtml")." \n";
    $msg .= "\n";
  }
}

 

the output i get is:

-In Resonse to:

...someText...

-They said:

...enteredText1...

 

-In Resonse to:

...someMoreText...

-They said:

...enteredText2...

 

-In Resonse to:

...evenMoreText...

-They said:

...enteredText3...

 

-In Resonse to:

...evenMoreText...

-They said:

...enteredText3...

 

It repeats the second to last, and omits the last completely.

if i change the loop to:

foreach($TextBoxData as &$text)

everything works correctly. I see this as a band-aid, and don't understand why I need to pass my array as a reference to get it to work. Also, I'd like to make this so that others can use this script as well, but PHP4 throws an error if you try to pass by reference in a foreach loop.

Sorry for the long post.  It appears to be the interaction between these two foreach loops.

<?php

$TextBoxData['TextBox1'] = Array ( 'name' => "TextBox1", 'value' => "Question1", 'show' => 1, 'required' => 1, 'text' => "Answer1" );
$TextBoxData['TextBox2'] = Array ( 'name' => "TextBox2", 'value' => "Question2", 'show' => 1, 'required' => 1, 'text' => "Answer2" );
$TextBoxData['TextBox3'] = Array ( 'name' => "TextBox3", 'value' => "Question3", 'show' => 1, 'required' => 1, 'text' => "Answer3" );
$TextBoxData['TextBox4'] = Array ( 'name' => "TextBox4", 'value' => "Question4", 'show' => 1, 'required' => 1, 'text' => "Answer4" );
echo "Vardump<br />";
var_dump($TextBoxData);
echo "<hr>Before first loop<br />";
print_r($TextBoxData);
//TextBoxes
foreach($TextBoxData as &$text)
{
if($text['required'] == 1 && $text['text'] == "")
{
	$text['missing'] = 1;
	$missing++;
}
}
echo "<hr>Before second loop<br />";
print_r($TextBoxData);

$first = 1;
foreach($TextBoxData as $text)
{
if($text['text'] != "")
{
	if($first == 1)
	{
		$msg .= "<br />Has the following additional information to share<br /><br />";
		$first = 0;
	}
	$msg .= "- In Response to: <br />";
	$msg .= "    {$text['value']} <br />";
	$msg .= " - They said : <br />";
	$msg .= "    {$text['text']} <br />";
}
}
echo $msg;
echo "<hr>After all loops<br />";
print_r($TextBoxData);
echo "<hr>Vardump<br />";
var_dump($TextBoxData);
?>

 

Vardump

array(4) { ["TextBox1"]=> array(5) { ["name"]=> string(8) "TextBox1" ["value"]=> string(9) "Question1" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer1" } ["TextBox2"]=> array(5) { ["name"]=> string(8) "TextBox2" ["value"]=> string(9) "Question2" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer2" } ["TextBox3"]=> array(5) { ["name"]=> string(8) "TextBox3" ["value"]=> string(9) "Question3" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer3" } ["TextBox4"]=> array(5) { ["name"]=> string(8) "TextBox4" ["value"]=> string(9) "Question4" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer4" } }


Before first loop

Array ( [TextBox1] => Array ( [name] => TextBox1 [value] => Question1 [show] => 1 [required] => 1 [text] => Answer1 ) [TextBox2] => Array ( [name] => TextBox2 [value] => Question2 [show] => 1 [required] => 1 [text] => Answer2 ) [TextBox3] => Array ( [name] => TextBox3 [value] => Question3 [show] => 1 [required] => 1 [text] => Answer3 ) [TextBox4] => Array ( [name] => TextBox4 [value] => Question4 [show] => 1 [required] => 1 [text] => Answer4 ) )


Before second loop

Array ( [TextBox1] => Array ( [name] => TextBox1 [value] => Question1 [show] => 1 [required] => 1 [text] => Answer1 ) [TextBox2] => Array ( [name] => TextBox2 [value] => Question2 [show] => 1 [required] => 1 [text] => Answer2 ) [TextBox3] => Array ( [name] => TextBox3 [value] => Question3 [show] => 1 [required] => 1 [text] => Answer3 ) [TextBox4] => Array ( [name] => TextBox4 [value] => Question4 [show] => 1 [required] => 1 [text] => Answer4 ) )

Has the following additional information to share

 

- In Response to:

Question1

- They said :

Answer1

- In Response to:

Question2

- They said :

Answer2

- In Response to:

Question3

- They said :

Answer3

- In Response to:

Question3

- They said :

Answer3


After all loops

Array ( [TextBox1] => Array ( [name] => TextBox1 [value] => Question1 [show] => 1 [required] => 1 [text] => Answer1 ) [TextBox2] => Array ( [name] => TextBox2 [value] => Question2 [show] => 1 [required] => 1 [text] => Answer2 ) [TextBox3] => Array ( [name] => TextBox3 [value] => Question3 [show] => 1 [required] => 1 [text] => Answer3 ) [TextBox4] => Array ( [name] => TextBox3 [value] => Question3 [show] => 1 [required] => 1 [text] => Answer3 ) )


Vardump

array(4) { ["TextBox1"]=> array(5) { ["name"]=> string(8) "TextBox1" ["value"]=> string(9) "Question1" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer1" } ["TextBox2"]=> array(5) { ["name"]=> string(8) "TextBox2" ["value"]=> string(9) "Question2" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer2" } ["TextBox3"]=> array(5) { ["name"]=> string(8) "TextBox3" ["value"]=> string(9) "Question3" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer3" } ["TextBox4"]=> &array(5) { ["name"]=> string(8) "TextBox3" ["value"]=> string(9) "Question3" ["show"]=> int(1) ["required"]=> int(1) ["text"]=> string(7) "Answer3" } }

Try to change 1st foreach loop (ones with reference &$test)

<?php

$TextBoxData['TextBox1'] = Array ( 'name' => "TextBox1", 'value' => "Question1", 'show' => 1, 'required' => 1, 'text' => "Answer1" );
$TextBoxData['TextBox2'] = Array ( 'name' => "TextBox2", 'value' => "Question2", 'show' => 1, 'required' => 1, 'text' => "Answer2" );
$TextBoxData['TextBox3'] = Array ( 'name' => "TextBox3", 'value' => "Question3", 'show' => 1, 'required' => 1, 'text' => "Answer3" );
$TextBoxData['TextBox4'] = Array ( 'name' => "TextBox4", 'value' => "Question4", 'show' => 1, 'required' => 1, 'text' => "Answer4" );
echo "Vardump<br />";
var_dump($TextBoxData);
echo "<hr>Before first loop<br />";
print_r($TextBoxData);
//TextBoxes
foreach($TextBoxData as $key => $text) {
if($text['required'] == 1 && $text['text'] == "") {
	$TextBoxData[$key]['missing'] = 1;
	$missing++;
}
}

echo "<hr>Before second loop<br />";
print_r($TextBoxData);

$first = 1;
foreach($TextBoxData as $text) {
if($text['text'] != "") {
	if($first == 1) {
		$msg .= "<br />Has the following additional information to share<br /><br />";
		$first = 0;
	}
	$msg .= "- In Response to: <br />";
	$msg .= "    {$text['value']} <br />";
	$msg .= " - They said : <br />";
	$msg .= "    {$text['text']} <br />";
}
}
echo $msg;
echo "<hr>After all loops<br />";
print_r($TextBoxData);
echo "<hr>Vardump<br />";
var_dump($TextBoxData);
?>

In order to get PHP4 compatibility I ended up having to give up on the foreach with references anyway, which was the problem.  But before doing so, I found that if I unset the temporary variable after the first foreach ran, everything worked correctly.

//TextBoxes
foreach($TextBoxData as &$text)
{
  if($text['required'] == 1 && $text['text'] == "")
  {
     $text['missing'] = 1;
     $missing++;
  }
}
unset($text)

the PHP4 compatible version of the function is

//TextBoxes
foreach($TextBoxData as $key => $text)
{
if($text['required'] == 1 && $text['text'] == "")
{
	$TextBoxData[$key]['missing'] = 1;
	$missing++;
}
}

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.