php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21444 Asort output not fully sorted in mixed type array with BOOLEANs
Submitted: 2003-01-05 16:26 UTC Modified: 2003-01-24 11:40 UTC
From: xxx1844 at thihigh dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 4.3.0 OS: Windows XP Pro Build 2600
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
35 - 26 = ?
Subscribe to this entry?

 
 [2003-01-05 16:26 UTC] xxx1844 at thihigh dot com
I use PHP4.0.3 on Apache 1.3.27, both standard binaries as supplied on the download site. Freshly installed yesterday. No modifications. I used the php.ini-recommended file as php.ini
Installed exactly as prescribed in install.txt, only instead of c:/php I use d:/program files/php and changed the ini accordingly.
Adapted the apache conf file as described. 

I used below script in an attempt to judge workload forced on the php server as well as asort() speed. Output is a bit large to add here, but can be requested via my email. In short, the array IS sorted, but in all identical "subrows" every now and then one or two array items are 1's (I assume the equivalent of TRUE. Rerunning the script  results in the SAME faults. Sorting within the script twice or more does not change the faulty array.
Tried with single-type arrays, that doesn't seem to produce the same errors, but this was not thoroughly tested. 

I am sorry, but I haven't figured out a way to get a backtrace yet, I  am relatively new to this PHP stuff.
For your convenience, you can run the script from my server by opening http://eniac.xs4all.nl/tut8.php and see my PHP server details on http://eniac.xs4all.nl/x345info.php (I noticed this script still 'sees' remainders of previous 1.3.24 apache as well as the correct 1.3.27 installs, allthough the .24 has been removed...

More info ? Contact me at my email. Thanks!
<?php
	$arr1 = array("a","b","c","d","4",5,4,"true","TRUE",true);
/*
 concatenate to itself 10 times to get a real LONG array (5120 elements)
*/
	for ($p = 1; $p < 10; $p++) 
		{ $arr1 = array_merge ($arr1,$arr1); }
	asort($arr1);
	foreach ($arr1 as $val) 
		{ print $val."  ";}

?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-01-05 16:32 UTC] xxx1844 at thihigh dot com
Well, it appears to be only related to the BOOLEAN array item. Removing that from the original array leaves a perfectly sorted array as far as I can see now.
 [2003-01-05 16:44 UTC] xxx1844 at thihigh dot com
Last addition: I meant sort() where I used asort(), but the result is the same....
 [2003-01-18 10:15 UTC] andrey@php.net
  IMO this is not PHP problem but the way the compares are done. You have to master the type juggling to see that the result is correct. I have reduced your testcase to this :
<?php
$arr1 = array("a","b","c","d","4",5,4,"true","TRUE",true);
sort($arr1);
var_dump($arr1);
?>

The output is :
array(10) {
  [0]=>
  bool(true)
  [1]=>
  int(4)
  [2]=>
  string(1) "4"
  [3]=>
  string(4) "TRUE"
  [4]=>
  string(1) "a"
  [5]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
  [8]=>
  string(4) "true"
  [9]=>
  int(5)
}
It may look strange - why (int)5 is after all the strings. This is because "4" is lower than (int) 5, "4" is before "true" and "true" is before 5. The first 2 are obvious, the third one is not. But it is ok. It's better not to mix types in the array. If 5 is changed to "5" then "5" goes right after "4".

Bogusifying

 [2003-01-18 12:07 UTC] xxx1844 at thihigh dot com
I have to disagree with you. Indeed, if it is the array you tested, these results are correct. Fill an array with multiple instances of identical values like the ones in the original example, and the boolean trues (output as '1') are distributed in a unpredictable way across some -not all- of the subsets of other values. Example:
a a a a 1 a a 1 a a a 1 b b b b b b 1 b 1 1 b b b  and so on.

I agree with you using multiple types in an array can be tricky, but the results I got just should not occur. Another (unrealistic imho) option would be to just say: don't use mixed type arrays, but I would expect this is not the way PHP should be heading.
 [2003-01-21 06:01 UTC] m dot ford at lmu dot ac dot uk
Following on from my comments in Bug #21728, I've analysed this sort tooo and, believe it or not, this is actually a correct sort for the default SORT_REGULAR sort type!!  This is because of the non-sequential order that comparisons are done, and the automatic type-conversion that occurs for those comparisons.

In this case, all non-null strings are cast to (bool)true when comparing with a bool, so that true=="a" and true=="b" and true=="c" and....  This gives you the strange result you see, where your genuine Boolean true values can be distributed anywhere within your otherwise correctly sorted strings.

Producing the same breakdown for (a slightly shortened version of) this array as I did for the arrays in #21728 gives:

  'a'  : 'a'   ==>  (string) 'a'  == 'a'
  'a'  : true  ==>  (bool)   true == true
  true : 'a'   ==>  (bool)   true == true
  'a'  : true  ==>  (bool)   true == true
  true : 'a'   ==>  (bool)   true == true
  'a'  : 'a'   ==>  (string) 'a'  == 'a'
  'a'  : true  ==>  (bool)   true == true
  true : 'b'   ==>  (bool)   true == true
  'b'  : 'b'   ==>  (string) 'b'  == 'b'
  'b'  : true  ==>  (bool)   true == true
  true : 'b'   ==>  (bool)   true == true
  'b'  : true  ==>  (bool)   true == true
  true : true  ==>  (bool)   true == true
  true : 'b'   ==>  (bool)   true == true
  'b'  : 'b'   ==>  (string) 'b'  == 'b'

And yet another surprise -- every comparison of neighbouring elements in that sorted array is an equality -- no single comparison yields a less-than result, even though the 'a's are all correctly sorted before the 'b's!!

I think the moral here is not to use the SORT_REGULAR sort type when you have mixed-type elements in the array.  In this case, you might possibly get an acceptable result by specifying the SORT_STRING sort type, as false would compare as "" and true as "1" -- only a problem if those values also occur naturally (either as strings or numbers) in the array.  The other option would be to use usort() with a callback that checks types before doing a value comparison.

But anyway, I agree, not a PHP bug -- more a curiosity of its design!

Cheers!

Mike
 [2003-01-24 11:40 UTC] sniper@php.net
NOT a bug.

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 18:01:28 2024 UTC