Bug #17307 Updated: sorting using usort() does not produce correct result anymore

From: Date: Tue, 04 Jun 2002 16:00:08 +0000
Subject: Bug #17307 Updated: sorting using usort() does not produce correct result anymore
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-9477@lists.php.net to get a copy of this message
ID: 17307 Updated by: mauf@franzoni.info Reported By: fcartegnie@nordnet.fr Status: Critical Bug Type: Arrays related Operating System: Linux PHP Version: 4.2.1 New Comment: No, I hit the problem on a P3 first... currently testing on a celeron - both using apache 2.0.36, debian with 2.4.18 on p3, rh7.2 (2.4.7-10) on celeron. here is the config, if it can helps: ./configure \ --prefix=/usr/local/php4-200206040600 \ --with-mysql=/usr/local/mysql-3.23.49 \ --with-apxs2=/usr/local/httpd-2.0.36/bin/apxs \ --enable-track-vars \ --enable-sigchild \ --enable-shared \ --enable-cxx \ --enable-cli=yes (I tried to track it a while but I get scrambled when it comes into the zend modules :-( ) Previous Comments: ------------------------------------------------------------------------ [2002-06-04 10:35:57] mfischer@php.net Setting to critical without further investigation, hope someone can check this out soon. Btw, are you on a 64bit platform? ------------------------------------------------------------------------ [2002-06-04 10:30:39] mauf@franzoni.info mmmhhh... I just tried php4-200206040600.tar.gz from snaps but it keeps sorting wrong... ------------------------------------------------------------------------ [2002-05-31 05:24:14] mfischer@php.net Please try latest snapshot from snaps.php.net , the problem is supposed to be fixed there. ------------------------------------------------------------------------ [2002-05-31 05:04:37] mauf@franzoni.info I've hit the sort problem too... I tried to reproduce it in a few way and I have to say that sometimes it seems to work (sort correctly) some not... unfortunately I can only contribute with a complex routine I use to sort site navigation menus (that it's the only one it always fails on V4.2.1 and works happily in 4.0.6). For the result: on the left side the table shows the tree as is (and is already sorted) - on the right the same tree after sorting (that indeed is not). <? $d = array( array(2, 0, 8, 1, 0, "branch A", "1", "12,8,0,0,0,0,0"), array(2, 0, 9, 1, 0, "branch B", "1", "12,9,0,0,0,0,0"), array(2, 0, 10, 1, 0, "branch C", "1", "12,10,0,0,0,0,0"), array(2, 0, 11, 1, 0, "branch D", "1", "12,11,0,0,0,0,0"), array(2, 0, 12, 1, 0, "branch E", "1", "12,12,0,0,0,0,0"), array(2, 0, 13, 1, 0, "branch F", "1", "12,13,0,0,0,0,0"), array(2, 0, 14, 1, 0, "branch G", "1", "12,14,0,0,0,0,0"), array(2, 0, 15, 1, 0, "branch H", "1", "12,15,0,0,0,0,0"), array(2, 0, 16, 1, 0, "branch I", "1", "12,16,0,0,0,0,0"), array(2, 0, 17, 1, 0, "branch J", "1", "12,17,0,0,0,0,0"), array(2, 0, 18, 1, 0, "branch K", "1", "12,18,0,0,0,0,0"), array(2, 0, 19, 1, 0, "branch L", "1", "12,19,0,0,0,0,0"), array(2, 0, 20, 1, 0, "branch M", "1", "12,20,0,0,0,0,0"), array(2, 0, 21, 1, 0, "branch N", "1", "12,21,0,0,0,0,0"), array(2, 0, 155, 1, 0, "branch O", "1", "12,155,0,0,0,0,0"), array(2, 0, 163, 1, 0, "branch P", "1", "12,163,0,0,0,0,0"), array(2, 0, 981, 1, 0, "branch Q", "1b", "12,981,0,0,0,0,0"), array(3, 0, 982, 981, 0, "under branch Q", "2", "12,981,982,0,0,0,0"), array(3, 0, 983, 981, 0, "under branch Q too", "2", "12,981,983,0,0,0,0") ); function sort_level($a, $b) { // sort navigation array // indexes : [0] level, [1] order, [2] tree_id, [3] parent_id, [4] parent_ord // (unused) [5] descr, [6] class, [7] navigation if ($a[0] == 2) { // a at second level if ($b[0] == 2) { // both a and b at second level if ($a[1] == $b[1]) { // a and b at same level, same order if ($a[2] == $b[2]) { // same level, same order, same tree_id (???) return 0; } else { // return according to tree_id return ($a[2] > $b[2]) ? 1 : -1; } } else { // return according to order (in same level) return ($a[1] > $b[1]) ? 1 : -1; } } else { // a at second level, b at third if ($a[2] == $b[3]) { // b is child of a return -1; } else { // return according to a and b's parent order return ($a[1] > $b[4]) ? 1 : -1; } } } else { // a at third level if ($b[0] == 3) { // both a and b at third level if ($a[1] == $b[1]) { // a and b at same level, same order if ($a[2] == $b[2]) { // same level, same order, same tree_id (???) return 0; } else { // return according to tree_id return ($a[2] > $b[2]) ? 1 : -1; } } else { // return according to order (in same level) return ($a[1] > $b[1]) ? 1 : -1; } } else { // b at second level, a at third if ($a[3] == $b[2]) { // a is child of b return 1; } else { // return according to a's parent and b order return ($a[4] > $b[1]) ? 1 : -1; } } } // just can't get here ! } function dotable($t) { print "<table border=1 cellspacing=1 cellpadding=5>\n"; for ($i = 0; $i < count($t); $i++) { print " <tr>"; for ($j = 0; $j < count($t[$i]); $j++) { print " <td>".$t[$i][$j]."</td>\n"; } print " </tr>\n"; } print "</table>\n"; return; } ?> <html> <head> </head> <body> <table border=1 cellspacing=1 cellpadding=5> <tr> <td><? dotable($d); ?></td> <? usort($d, "sort_level"); ?> <td><? dotable($d); ?></td> </tr> </table> </body> </html> ------------------------------------------------------------------------ [2002-05-22 14:15:55] fcartegnie@nordnet.fr <?php /* let's define some array elements For example, 3 products (A,B,C) with different price (livre) */ $elt["nom"]="A"; $elt["livre"]=10; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="A"; $elt["livre"]=9; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="A"; $elt["livre"]=7; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="A"; $elt["livre"]=11; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="A"; $elt["livre"]=101; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="B"; $elt["livre"]=104; $elt["quantite"]=1; $ar[]=$elt; $elt["nom"]="C"; $elt["livre"]=101; $elt["quantite"]=1; $ar[]=$elt; /* Our sort function only swap 2 values if the name is the same and the first price is higher than second As we give a 'nom' field sorted alphabetically array, we might get the result : A7 A9 A10 A11 A101 B104 C101 Which is the result in php 4.0.6 But the result un php 4.2.1 is : C101 B104 A7 A9 A10 A11 A101 */ function sort_function($a, $b) { if ((($a["livre"]/$a["quantite"]) == ($b["livre"]/$b["quantite"])) || $a["nom"] != $b["nom"]) return 0; return (($a["livre"]/$a["quantite"]) < ($b["livre"]/$b["quantite"])) ? -1 : 1; } /* This is a 2nd function, which always returns that elements are equal. So it might not change the array... If you try this alternate function, you'll see that the array is modified to : B104 C101 A101 A11 A9 A7 A10 ??????! really strange behaviour */ function sort_function_void($a, $b) { return 0; } echo "<HTML><PRE>UnSorted:\n"; for ($i=0;$i<sizeof($ar);$i++) echo $ar[$i]["nom"].$ar[$i]["livre"]."\n"; usort($ar, sort_function); //usort($ar, sort_function_void); echo "Sorted:\n"; for ($i=0;$i<sizeof($ar);$i++) echo $ar[$i]["nom"].$ar[$i]["livre"]."\n"; ?> ------------------------------------------------------------------------ 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/17307 -- Edit this bug report at http://bugs.php.net/?id=17307&edit=1

« previous php.bugs (#9477) next »