Bug #29992 [Com]: foreach by reference corrupts the array
Edit report at https://bugs.php.net/bug.php?id=29992&edit=1 ID: 29992 Comment by: looris at gmail dot com Reported by:fletch at pobox dot com Summary:foreach by reference corrupts the array Status: Not a bug Type: Bug Package:Scripting Engine problem Operating System: linux PHP Version:5.0.1 Block user comment: N Private report: N New Comment: No one cares about the technical explanation about why this happens at a low level. I'm quite puzzled you are still in denial about this bug. Previous Comments: [2012-02-09 16:49:22] ras...@php.net No matter how you paint this, it isn't a bug. What you are really asking for is some sort of block-level scoping. As such, it should be proposed as a feature request, but it would be a major change in the language. The simplest way to illustrate that is to just unroll the loops. Take this example: $a = array(1,2); foreach($a as &$b) { } foreach($a as $b) { } print_r($a); The problem here is that people find it inconsistent that the 2nd loop changes $a. But if we unroll the loops and write the exactly equivalent code without the foreach construct we get: $a = array(1,2); // First loop, $b is a reference to each element in $a $b = &$a[0]; $b = &$a[1]; // Second loop, $b is assigned the value of each element in $a $b = $a[0]; $b = $a[1]; Those two pieces of code are identical in every way. The thing that confuses people is that $b is still a reference $a[1] going into the second loop. Since PHP doesn't have block-level scoping, there is nothing in the language that would permit $b to be unset between the two loops without introducing a major inconsistency. In fact there is plenty of code that relies on this fact which would break if we made such an arbitrary change. I suppose what you are asking for is syntax along the lines of: $a = array(1,2); { local $b = &$a[0]; $b = &$a[1]; } { local $b = $a[0]; $b = $a[1]; } Where $b is locally scoped in each of those blocks and it might look like this in a foreach case: $a = array(1,2); foreach($a as local &$b) { } foreach($a as local $b) { } Without such a scoping syntax change, something as simple as: forach(array(1,2,3) as $b) { } echo $b; where the code fully expects $b to be 3 would break. [2012-02-09 12:33:40] robbie at shapehq dot co dot uk I feel very strongly that this behavior is wrong. It's not consistent with other languages and will cause great confusion! [2011-10-20 04:56:50] bruce at kaskubar dot com With all due respect to those who spend their time developing, debugging, and explaining PHP, BALDERDASH! Elsewhere, those of us who continue to claim "bug" are supposed to be chastened by all the explanations that have been provided over the years. The fact that the reports persist and the explanations grow is evidence contrary to the finding of Bogus and in support of what is expected behavior. Fletch's example, for example, is real and reproducible through at least v5.3.2. How in the world can it be expected for a (second) loop and its object to perform as though no related instructions were executed previously, and then for that interaction to raise its ugly head for only the last iteration? It cannot be. It can be explained. But so can an earthquake be. That doesn't make it expected. I am unaware of any other case where prior use of a variable affects subsequent use of the same-named variable where its value is being explicitly reset or, as in the case of foreach, implicitly reset by virtue of its purpose. (That is, we can use $i as a loop counter here and as a file handle there and as long as we don't cross their purposes in the space-time continuum, all is well.) The only bogus thing about this bug report and all its cousins is their shared status. [2011-09-02 15:13:42] publcishady at gmail dot com If you describe how it works that's not an excuse for unexpected results. I understand why the last element becomes a reference, but I don't understand why it SHOULD become a reference. That's obviously a bug for me. [2011-07-18 05:03:24] martijn at twotribes dot com Well, it is expected by the people who designed the language perhaps, but not by me. Iterating through an array, without doing anything, shouldn't change the array. Period. If I do something similar in another language like C++, this will never be the result.
#49300 [NEW]: very bizarre loops with decimal numbers
From: looris at gmail dot com Operating system: debian stable PHP version: 5.2.10 PHP Bug Type: Unknown/Other Function Bug description: very bizarre loops with decimal numbers Description: Just look at the code. Reproduce code: --- Expected result: 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Actual result: -- 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 -- Edit bug report at http://bugs.php.net/?id=49300&edit=1 -- Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=49300&r=trysnapshot52 Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=49300&r=trysnapshot53 Try a snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=49300&r=trysnapshot60 Fixed in SVN: http://bugs.php.net/fix.php?id=49300&r=fixed Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=49300&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=49300&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=49300&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=49300&r=needscript Try newer version: http://bugs.php.net/fix.php?id=49300&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=49300&r=support Expected behavior: http://bugs.php.net/fix.php?id=49300&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=49300&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=49300&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=49300&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=49300&r=php4 Daylight Savings:http://bugs.php.net/fix.php?id=49300&r=dst IIS Stability: http://bugs.php.net/fix.php?id=49300&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=49300&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=49300&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=49300&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=49300&r=mysqlcfg
#49300 [Bgs]: very bizarre loops with decimal numbers
ID: 49300 User updated by: looris at gmail dot com Reported By: looris at gmail dot com Status: Bogus Bug Type: Unknown/Other Function Operating System: debian stable PHP Version: 5.2.10 New Comment: what are you talking about? string representation? the second loop loops 8 times, when it should have looped only 7 times. and using < or <= gives exactly the same result: it still loops for 0.8 when it shouldn't (since i wrote $value<0.8) I assumed you would notice it but clearly you didn't, I'll be more descriptive next time. We do agree that if $value is 0.8, the expression $value<0.8 is FALSE, now do we? Previous Comments: [2009-08-20 08:58:58] der...@php.net Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://docs.sun.com/source/806-3568/ncg_goldberg.html Thank you for your interest in PHP. . ------------ [2009-08-19 20:39:01] looris at gmail dot com Description: Just look at the code. Reproduce code: --- Expected result: 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Actual result: -- 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 -- Edit this bug report at http://bugs.php.net/?id=49300&edit=1
#49300 [Bgs]: very bizarre loops with decimal numbers
ID: 49300 User updated by: looris at gmail dot com Reported By: looris at gmail dot com Status: Bogus Bug Type: Unknown/Other Function Operating System: debian stable PHP Version: 5.2.10 New Comment: unfortunatly, you do not understand how languages work. a high level language, like php, must (MUST, not should!) abstract all the low level mechamisms. a developer who writes php code must not be required to know how things work at levels below that of php. if something unexpected like this happens, it's php's fault, not programmer's! every time someone finds a thing that is clearly a bug (clearly to any sane person) and you state "it's working as intended", you only fool yourself. what's the point in programming in a high level language, if that languages behaves in an unpredictable way, and its developers are happy with it? I don't care how php handles floating point numbers internally, it may send all the data to a pair of monkey who do the math with pen and paper and then send it back to the program for all I care (and that at least would explain some oddities). I perfectly know how floats are represented in computers, dude. I perfectly know that it's a rounding issue caused by the conversion from decimal to binary... I just don't care. While I code in php I expect the language to be fool-proof, and I expect it to solve this problems without me having to bother. It can be done, just use a fractional representation for floats until you are forced to switch to a normal one. I mean, I know you never will, but it's still my duty to tell you what you should do. Previous Comments: [2009-08-20 12:18:41] scott...@php.net Unfortunately you're not understanding how floating point maths is represented with a computer. Read the link that derick pointed you to or have a quick look at wikipedia. ---------------- [2009-08-20 10:36:22] looris at gmail dot com what are you talking about? string representation? the second loop loops 8 times, when it should have looped only 7 times. and using < or <= gives exactly the same result: it still loops for 0.8 when it shouldn't (since i wrote $value<0.8) I assumed you would notice it but clearly you didn't, I'll be more descriptive next time. We do agree that if $value is 0.8, the expression $value<0.8 is FALSE, now do we? [2009-08-20 08:58:58] der...@php.net Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://docs.sun.com/source/806-3568/ncg_goldberg.html Thank you for your interest in PHP. . ---------------- [2009-08-19 20:39:01] looris at gmail dot com Description: Just look at the code. Reproduce code: --- Expected result: 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Actual result: -- 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 -- Edit this bug report at http://bugs.php.net/?id=49300&edit=1
#49300 [Bgs]: very bizarre loops with decimal numbers
ID: 49300 User updated by: looris at gmail dot com Reported By: looris at gmail dot com Status: Bogus Bug Type: Unknown/Other Function Operating System: debian stable PHP Version: 5.2.10 New Comment: actually, it's supposed to do just this kind of thing. compared to C, it allows you not to declare variables, not to malloc memory you want to use, not to destroy that memory, not to care about converting variables from one type to another, not to care about types at all. it does a whole lot of things, all aimed at removing that burden from the developer, so yes, it would be perfectly natural for it to store floats in a much friendlier way when it's needed. Previous Comments: [2009-08-21 12:10:01] ras...@php.net Just curious, have you filed this bug against every other high-level language? Because they all behave like this. It is not PHP's job to invent a better way to store floating point values. [2009-08-20 12:43:38] looris at gmail dot com unfortunatly, you do not understand how languages work. a high level language, like php, must (MUST, not should!) abstract all the low level mechamisms. a developer who writes php code must not be required to know how things work at levels below that of php. if something unexpected like this happens, it's php's fault, not programmer's! every time someone finds a thing that is clearly a bug (clearly to any sane person) and you state "it's working as intended", you only fool yourself. what's the point in programming in a high level language, if that languages behaves in an unpredictable way, and its developers are happy with it? I don't care how php handles floating point numbers internally, it may send all the data to a pair of monkey who do the math with pen and paper and then send it back to the program for all I care (and that at least would explain some oddities). I perfectly know how floats are represented in computers, dude. I perfectly know that it's a rounding issue caused by the conversion from decimal to binary... I just don't care. While I code in php I expect the language to be fool-proof, and I expect it to solve this problems without me having to bother. It can be done, just use a fractional representation for floats until you are forced to switch to a normal one. I mean, I know you never will, but it's still my duty to tell you what you should do. [2009-08-20 12:18:41] scott...@php.net Unfortunately you're not understanding how floating point maths is represented with a computer. Read the link that derick pointed you to or have a quick look at wikipedia. ---------------- [2009-08-20 10:36:22] looris at gmail dot com what are you talking about? string representation? the second loop loops 8 times, when it should have looped only 7 times. and using < or <= gives exactly the same result: it still loops for 0.8 when it shouldn't (since i wrote $value<0.8) I assumed you would notice it but clearly you didn't, I'll be more descriptive next time. We do agree that if $value is 0.8, the expression $value<0.8 is FALSE, now do we? [2009-08-20 08:58:58] der...@php.net Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://docs.sun.com/source/806-3568/ncg_goldberg.html Thank you for your interest in 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 at http://bugs.php.net/49300 -- Edit this bug report at http://bugs.php.net/?id=49300&edit=1
Bug #29992 [Com]: foreach by reference corrupts the array
Edit report at http://bugs.php.net/bug.php?id=29992&edit=1 ID: 29992 Comment by: looris at gmail dot com Reported by: fletch at pobox dot com Summary: foreach by reference corrupts the array Status: Bogus Type: Bug Package: Scripting Engine problem Operating System: linux PHP Version: 5.0.1 New Comment: This *IS* a bug, since no one would EVER expect this kind of behaviour. And no one "might use this for some weird reason", believe me. "foreach" means "do stuff FOR EACH element of an array". It does not mean, to any sane person, "do stuff for each element of an array except the last one, and twice for the one before the last one". Your stubbornness in stating this is intentional is quite frightening. Previous Comments: [2006-08-07 14:18:11] kou...@php.net Although there's a user note in the manual, still this problem is not described in the documentation itself. Anyway, I believe the behaviour of foreach in this case is extremely dangerous. Imagine there's such a "referential" loop in a library which is included by some other scripts and it operates on $_SESSION or some other important array. Now any foreach in the other scripts might corrupt the base array without even knowing it - just because the name of the "value" variable is the same. The main purpose of foreach itself is (as the name implies) to do something "for each" element of the array, i.e. to provide an easier way to traverse an array than the other loop constructs and not to touch other variables or references that are still pointing somewhere, unless it's done implicitly in the body of the loop. IMHO, foreach has to clear the variables used for key-value pairs, i.e. to unset the reference before proceeding, just like it resets the array pointer. Otherwise we have to put a big red note in the manual to always unset variables after using the referential syntax or to use $long_descriptive_names_for_references, which is a little unreasonable in the current context. [2004-10-08 08:54:14] der...@php.net Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php Right, thanks for that analysis. No bug here. (And no, we can't unset it by default, as people might use this for some weird reason). [2004-10-07 21:12:18] gardan at gmx dot de There is no corruption. It is easy to explain this behaviour. Take the following: $arr = array(1 => array(1, 2), 2 => array(1, 2), 3 => array(1, 2)); foreach($arr as &$value) { } foreach(array(1,2,3,4,5) as $key => $value) { } echo $test[3]; After the first foreach() loop what you have in $value is a reference to the last element in $arr (here: to array(1,2)). Now, when the next foreach loop assigns a value to $value, it assigns this value to where $value points, that is: to the last position of $arr. Now in the second foreach() the last item of $arr becomes first 1, then 2, etc and in the end, what you get as output by this program, is: 5 Not the expected: Array Now this is indeed very confusing if you don't know what's going on. Solution: unset $v before a new foreach() loop (maybe this could be done by php by default?) [2004-10-04 16:37:43] yaroukh at email dot cz I believe the problem I'm gonna describe here has the same roots as the one fletch has described ... Try this: slots =& $slots; } public function & getSlot($idx) { if(IsSet($this->slots[$idx])) return $this->slots[$idx]; return null; } public function getLength() { return Count($this->slots); } } // fill the array and create object { $slots = Array( 'zero', 'one', 'two', 'three', 'four' ); $aw = new ArrayWrapper($slots); // } // output A var_dump($aw); // iteration 1 for($idx = 0; $idx < $aw->getLength(); $idx++) $aw->getSlot($idx); // output B; everything is OK
[PHP-BUG] Bug #51412 [NEW]: inconsistency using uninitialized array elements
From: Operating system: linux, osx, (any?) PHP version: Irrelevant Package: Arrays related Bug Type: Bug Bug description:inconsistency using uninitialized array elements Description: While I agree that it would be better to actually initialize elements before using them, it is anyway wrong that they behave in inconsistent ways when you do that. They should BOTH count as 0, hence become 1 and -1, OR they should **BOTH** stay NULL. It does not make any sense at all to have them behave in two different ways. Test script: --- $pitale=array(); $pitale["ok"]++; $pitale["bug"]--; print_r($pitale); Expected result: Array ( [ok] => 1 [bug] => -1 ) ---OR--- Array ( [ok] => [bug] => ) Actual result: -- Array ( [ok] => 1 [bug] => ) -- Edit bug report at http://bugs.php.net/bug.php?id=51412&edit=1 -- Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=51412&r=trysnapshot52 Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=51412&r=trysnapshot53 Try a snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=51412&r=trysnapshot60 Fixed in SVN: http://bugs.php.net/fix.php?id=51412&r=fixed Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=51412&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=51412&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=51412&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=51412&r=needscript Try newer version: http://bugs.php.net/fix.php?id=51412&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=51412&r=support Expected behavior: http://bugs.php.net/fix.php?id=51412&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=51412&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=51412&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=51412&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=51412&r=php4 Daylight Savings:http://bugs.php.net/fix.php?id=51412&r=dst IIS Stability: http://bugs.php.net/fix.php?id=51412&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=51412&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=51412&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=51412&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=51412&r=mysqlcfg