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.

Link to comment
Share on other sites

Can you write a short script that replicates this behaviour?  Or does it only occur in that particular situation?  If you can, show us var_dump($TextBoxData), and tell us the exact version of php you are using.

Link to comment
Share on other sites

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" } }

Link to comment
Share on other sites

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);
?>

Link to comment
Share on other sites

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++;
}
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.