From:             phpbugs at jessemccarthy dot net
Operating system: Linux
PHP version:      5.2.1
PHP Bug Type:     Arrays related
Bug description:  uasort implementation is not robust

Description:
------------
I spent hours investigating why my script using uasort() was not producing
the expected results before finally discovering that the problem is due to
a bug / limitation in the uasort() implementation.

I don't know what's actually happening in the source code, but my theory
about the problem is that uasort() (or whatever underlying code) cuts
corners or tries to use a shortcut based on members that compare as
equal.

I *know* that "If two members compare as equal, their order in the sorted
array is undefined."  *However*, once uasort() has found certain members
to be equal, it seems to jump to conclusions based on that and doesn't go
on to compare other members to each other that need to be.

Say for example you have an array with 3 members, call them A, B, and C,
where the callback for uasort() would return
 0 for A compared to B
 0 for B compared to C
-1 for A compared to C

It seems that if uasort() compares A to B, and B to C and sees that they
are "equal", it never compares A to C, which are not equal.

I consider it a bug, and a major flaw, but I don't know for sure that
people familiar with the code don't intend for it to work that way.  Since
uasort() / usort() are billed as the solution for sorting by non-trivial
criteria, I really think that it should work more robustly and perform
more thorough processing in those situations.  If there is some reason it
can't be made to work that way, there should be a very noticeable warning
in the documentation about how limited its functionality is.

I encountered this issue in the course of real world development, trying
to tailor the order of output of form elements in Drupal based on its
weighting system.  The uasort() callback in my reproduce code is the
Drupal core code modified to sort members alphabetically if the assigned
weight values are equal.  Printing the values of the arguments in the
callback reveals that "A" and "C" (field_favorite_movies and
field_favorite_music) are never compared.

Reproduce code:
---------------
Source:
http://www.jessemccarthy.net/public/uasort_bug/reproduce_source.php

In action (with PHP 4.4.4., but the same behavior occurs on another server
with 5.2, where I originally encountered it):
http://www.jessemccarthy.net/public/uasort_bug/reproduce.php

Expected result:
----------------
I expect 'field_favorite_movies' to occur prior to 'field_favorite_music'
in the sorted array.  I expect 'monkey_wrench' to appear anywhere.

Actual result:
--------------
'field_favorite_music' occurs prior to 'field_favorite_movies'.  If
'monkey_wrench' is excluded from the original array, the order is correct
after sorting.

-- 
Edit bug report at http://bugs.php.net/?id=40616&edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=40616&r=trysnapshot44
Try a CVS snapshot (PHP 5.2): 
http://bugs.php.net/fix.php?id=40616&r=trysnapshot52
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=40616&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=40616&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=40616&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=40616&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=40616&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=40616&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=40616&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=40616&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=40616&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=40616&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=40616&r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=40616&r=php3
Daylight Savings:             http://bugs.php.net/fix.php?id=40616&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=40616&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=40616&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=40616&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=40616&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=40616&r=mysqlcfg

Reply via email to