ID: 9369
Updated by: andi
Reported By: [EMAIL PROTECTED]
Old-Status: Open
Status: Closed
Bug Type: Scripting Engine problem
PHP Version: 4.0.4pl1
Assigned To: 
Comments:

Fixed in CVS. Thanks for the report.

Previous Comments:
---------------------------------------------------------------------------

[2001-04-05 21:39:00] [EMAIL PROTECTED]
I've tested against 
  - PHP4.0.5RC1 Windows/Apache SAPI
  - PHP4.0.5RC6 Linux/Apache SAPI

It's still there.

I think this bug is better to be fixed soon, even if this is a programmer's error. For 
example, if user change HTML form values from array to sclar and forgot to change PHP 
code, programmers are crueless what's wrong. If PHP could issue warning, it would be 
easy to find problem.

Please let me know if you don't have this problem.

FYI:
Very simpile code like follows PHP works as it should be (Warning message is 
displyed), but not for longer code. ('server not found or dns error' or empty page. 
Try code that I've submitted. The later one is self contained single file.)

<?php
$str = 'AAAAAAAAAAAAA';

// This works (raise warning message)
foreach ($str as $v => $k) {
}
?>


---------------------------------------------------------------------------

[2001-03-16 22:08:35] [EMAIL PROTECTED]
After I upgraded my test machine's glibc and gcc, I didn't check if this bug is happen 
on my machine. Unfortunately it still exists. (Upgrading glibc fixed malformed man 
pages when EUC-JP is used, though)

I wrote a new test code for developers so that you can easily verify this bug. (Single 
php file with HTML form to play with this errata)

Note: First of all, programmers should NOT write this kind of code. i.e. Using scalar 
where array is expected, this is error anyway. 

Try test case "foreach and value" and "foreach and reference". PHP does not complain 
illegal use of variable at all, but empty outputs.

This PHP behavior is not acceptable for many users I think. Since if programmer write 
PHP code,  that does this kind of illegal use of variables, can be very hard to find.

I also interested in why PHP behave differently when ASCII is used for scalar and when 
EUC-JP (Multi-byte Charset) is used for scalar.

======== source code =======
<html>
<head>
<title>Foreach and Reference Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
</head>

<body bgcolor="#FFFFFF">
<h1>Foreach and Reference Bug Test Page</h1>
<h3>Test Function: <?php isset($HTTP_POST_VARS['action']) ? 
print($HTTP_POST_VARS['action']) : print('Function is not set'); ?></h3>
<h3>Test Param: <?php isset($HTTP_POST_VARS['test_mode']) ? 
print($HTTP_POST_VARS['test_mode']) : print('Mode is not set'); ?></h3>
<form name="form1" method="post" >
<input type="submit" name="Submit" value="while and value">
<input type="hidden" name="action" value="while_and_value">
<input type="radio" name="test_mode" value="ascii" checked>
ASCII Text Scalar 
<input type="radio" name="test_mode" value="euc_jp">
EUC-JP Text Scalar 
</form>
<form name="form2" method="post" >
<input type="submit" name="Submit2" value="while and reference">
<input type="hidden" name="action" value="while_and_reference">
<input type="radio" name="test_mode" value="ascii" checked>
ASCII Text Scalar 
<input type="radio" name="test_mode" value="euc_jp">
EUC-JP Text Scalar 
</form>
<h3> </h3>
<form name="form3" method="post" >
<input type="submit" name="Submit3" value="foreach and value">
<input type="hidden" name="action" value="foreach_and_value">
<input type="radio" name="test_mode" value="ascii" checked>
ASCII Text Scalar 
<input type="radio" name="test_mode" value="euc_jp">
EUC-JP Text Scalar 
</form>
<form name="form4" method="post" >
<input type="submit" name="Submit22" value="foreach and reference">
<input type="hidden" name="action" value="foreach_and_reference">
<input type="radio" name="test_mode" value="ascii" checked>
ASCII Text Scalar 
<input type="radio" name="test_mode" value="euc_jp">
EUC-JP Text Scalar 
</form>
<?php 
// NOTE: error report level is E_ALL

$ascii  = 'abcdefghijklmn';                     // plain ascii
$euc_jp = 'あいうえおかきくけこ';       // multi-byte EUC char code

function while_and_value($msg) {
 while (list($k,$v) = each($msg[1])) {
  print($v);
 }
 while (list($k,$v) = each($msg[0])) {
  print($v);
 }
}

function while_and_reference(&$msg) {
 while (list($k,$v) = each($msg[1])) {
  print($v);
 }
 while (list($k,$v) = each($msg[0])) {
  print($v);
 }
}

function foreach_and_value($msg) {
 foreach ($msg[1] as $v) {
  print($v);
 }
 foreach ($msg[0] as $v) {
  print($v);
 }
}

function foreach_and_reference(&$msg) {
 foreach ($msg[1] as $v) {
  print($v);
 }
 foreach ($msg[0] as $v) {
  print($v);
 }
}


// Call function specified with $action with a paramter specified with $test_mode
if (isset($HTTP_POST_VARS['action'])) {
        $test_mode = $HTTP_POST_VARS['test_mode']; // ascii or euc_jp

        $action = $HTTP_POST_VARS['action']; // One of 4 function
        $action($$test_mode); 
}
?>
</body>
</html>


---------------------------------------------------------------------------

[2001-02-21 08:09:12] [EMAIL PROTECTED]
I found other strange behaviors with much more simple scripts. It is very similar to 
what I experienced, but it differ a little. Bug ID#9365 
(I got default HTML for null output. i.e. output that 
== FILE START ==
<?php 
?>
== FILE END ==
 script shows. These scripts do not show that.)

Here is 3 php files. (It does not have to be 3 files, but I've test with these 3 
files)
- test.php (just a submission handler. Defines some functions)
- test2.php (File to be executed, when user hit submit button. Defines some functions)
- test3.php (Submit form)

Test result is written in test2.php. Please refer the comments in test2.php (Test 
result is a little differ when I use multi-byte char code)

I've fund this, since I have very similar mistake in my code when I get rid of 
function - refer to 1st post what I mean (Bug ID#9365) There was a variable name 
collision, which I didn't care at all at that time. I passed EUC char code string 
where I should pass multi-dimensional array. Fixing this solved 2nd behavior. (Note: I 
still couldn't get the same behavior with these simple scripts. Fixing this bug may 
fix it, too.)  

Some of them are bug for sure, some error message is misleading, some might be 
inevitable due to PHP's reference implementation. Some might be already reported as 
bug/misbehavior. 

I'll try to find out when PHP stops and restart script execution from the beginning. 
This would be much more difficult, since the code does not have obvious mistake like 
this one. Or is this reported as bug already? If so, please let me know.

== test.php ==
<?php
if (isset($HTTP_POST_VARS['sub_btn'])) {
 include('test2.php');
 exit;
}
else {
 include('test3.php');
 exit;
}

function pmsg(&$msg) {
 foreach ($msg[1] as $v) {
  print("<div class="error">$v</div>n");
 }
 foreach ($msg[0] as $v) {
  print("<div class="message">$v</div>n");
 }
}

function pmsg2(&$msg) {
 while (list($k,$v) = each($msg[1])) {
  print("<div class="error">$v</div>n");
 }
 while (list($k,$v) = each($msg[0])) {
  print("<div class="message">$v</div>n");
 }
}
?>
=== END test.php ===

=== test2.php ===
<html>
<head>
</head>
<body>
THIS IS TEST2.PHP<br>
<?php 
// NOTE: error report level is E_ALL

$msg = 'abcd';
$msg2 = 'あいうえおかきくけこ'; // multi-byte EUC char code
$msg3 = "あいうえおかきくけこ"; // multi-byte EUC char code
//pmsg($msg1);   // <= PHP does NOT (cannot?) complains illegal pass by reference at 
all. 
// With $msg, IE5.5 complains "Can't find server or DNS error"
// With $msg2 or $msg3, IE5.5 just spins. It seems waiting server response. Stop 
button seems does not stop operation.
// Warning: Invalid argument supplied for foreach() in .../tmp/test.php on line 12 
(for unintialized var). Should complain for use of undefined var when it used.


//pmsg2($msg);  // <= PHP complains "only variable can be passed by reference" as 
expected.
    // The same result for $msg, $msg2, $msg3
// Fatal error: Only variables can be passed by reference in .../tmp/test.php on line 
21 ($msg,$msg2,$msg3)
// Warning: Variable passed to each() is not an array or object in .../tmp/test.php on 
line 21 (for uninitialized var) Should complain for use of undefined var when it used.


//pmsg3($msg);  // <= PHP does NOT (cannot?) complains at all like pmsg()
// With $msg IE5.5 just spins. It seems waiting server response.  Stop button seems 
does not stop operation.
// With $msg2 or $msg3, IE5.5 complains "Can't find server or DNS error"
// Warning: Invalid argument supplied for foreach() in ../tmp/test2.php on line xx <- 
complained at inside pmsg3() (for uninitialized var) Should complain for use of 
undefined var when it used.
// Note: behavior is differ from pmsg()!


//pmsg4($msg);   // <= PHP complains
// Fatal error: Only variables can be passed by reference in .../tmp/test2.php on line 
xx ($msg,$msg2,$msg3)
// Warning: Variable passed to each() is not an array or object in .../tmp/test2.php 
on line xx <- complained at inside pmsg4() (for uninitialized var) Should complain for 
use of undefined var when it used.


pmsg5($msg3);  // PHP does not (cannot?) complain?
// With $msg IE5.5 just spins. It seems waiting server response.  Stop button seems 
does not stop operation.
// With $msg2 IE5.5 complains "Can't find server or DNS error"
// With $msg3 IE5.5 just spins. It seems waiting server response.  Stop button seems 
does not stop operation.
// PHP show expected error messages for undefined var.
// Note: See the difference with pmsg6().


//pmsg6($msg3);  // PHP shows acceptable error messages for passing string where it 
should be array.
// Fatal error: Only variables can be passed by reference in .../tmp/test2.php on line 
xx <- complained at inside pmsg5 ($msg,$msg2,$msg3);
// Warning: Undefined variable: msg1 in .../tmp/test2.php on line xx (Undefined var) 
OK
// Warning: Variable passed to each() is not an array or object in .../tmp/test2.php 
on line xx (Undefined var) OK


function pmsg3(&$msg) {
 foreach ($msg[1] as $v) {
  print("<div class="error">$v</div>n");
 }
 foreach ($msg[0] as $v) {
  print("<div class="message">$v</div>n");
 }
}


function pmsg4(&$msg) {
 while (list($k,$v) = each($msg[1])) {
  print("<div class="error">$v</div>n");
 }
 while (list($k,$v) = each($msg[0])) {
  print("<div class="message">$v</div>n");
 }
}


function pmsg5($msg) {
 foreach ($msg[1] as $v) {
  print("<div class="error">$v</div>n");
 }
 foreach ($msg[0] as $v) {
  print("<div class="message">$v</div>n");
 }
}


function pmsg6($msg) {
 while (list($k,$v) = each($msg[1])) {
  print("<div class="error">$v</div>n");
 }
 while (list($k,$v) = each($msg[0])) {
  print("<div class="message">$v</div>n");
 }
}

?>
END<br>
</body>
</html>
=== END test2.php ===

=== test3.php ===
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
</head>

<body bgcolor="#FFFFFF">
<p>THIS IS TEST3.PHP </p>
<form name="form1" method="post">
<input type="submit" name="sub_btn" value="send">
<input type="text" name="textfield">
</form>
<p>END</p>
</body>
</html>
=== END test3.php ===



---------------------------------------------------------------------------

The remainder of the comments for this report are too long.  To view the rest of the 
comments, please view the bug report online.


ATTENTION! Do NOT reply to this email!
To reply, use the web interface found at http://bugs.php.net/?id=9369&edit=2


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to