Bug #66544 [Opn->Nab]: uasort works incorrent in some cases
| From: | rasmus@php.net | Date: | Wed, 22 Jan 2014 18:46:55 +0000 |
| Subject: | Bug #66544 [Opn->Nab]: uasort works incorrent in some cases | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-183957@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66544&edit=1
ID: 66544
Updated by: rasmus@php.net
Reported by: korovkin dot kirill at gmail dot com
Summary: uasort works incorrent in some cases
-Status: Open
+Status: Not a bug
Type: Bug
Package: *General Issues
Operating System: Linux 2.6.32-042stab07
PHP Version: 5.4.24
Block user comment: N
Private report: N
New Comment:
Yup, the logic is wrong here. The sort function will compare them in this order:
a = freeshipping, b = shipping
a = tax_shipping, b = freeshipping
a = discount, b = freeshipping
a = tax_shipping, b = discount
If you go through it one by one you will see that the first 3 checks all return 0, only the
tax_shipping vs. discount is going to return -1 so those two elements are the only two affected.
Previous Comments:
------------------------------------------------------------------------
[2014-01-22 18:38:09] mail at requinix dot net
Looks like undefined behavior to me: your comparison function claims that discount == freeshipping
and tax_shipping == freeshipping, yet tax_shipping < discount.
Pick an unambiguous place for freeshipping to go, update the arrays so that your function can
definitively state the sort order for every pairing, and it will sort correctly. Besides, allowing
freeshipping to land wherever the sort happens to place it doesn't sound like a good idea.
------------------------------------------------------------------------
[2014-01-22 14:11:34] korovkin dot kirill at gmail dot com
Description:
------------
You can see all information in the test script.
Test script:
---------------
$inputArray = array(
'shipping' => array(
'after' => array(),
'before' => array(),
'_code' => 'shipping'
),
'freeshipping' => array(
'after' => array(),
'before' => array(),
'_code' => 'freeshipping'
),
'discount' => array(
'after' => array('shipping', 'tax_shipping'),
'before' => array(),
'_code' => 'discount'
),
'tax_shipping' => array(
'after' => array('shipping'),
'before' => array('discount'),
'_code' => 'tax_shipping'
)
);
function compare ($a, $b) {
$aCode = $a['_code'];
$bCode = $b['_code'];
if (in_array($aCode, $b['after']) || in_array($bCode, $a['before'])) {
$res = -1;
} elseif (in_array($bCode, $a['after']) || in_array($aCode, $b['before'])) {
$res = 1;
} else {
$res = 0;
}
return $res;
}
uasort($inputArray, 'compare');
var_dump(array_keys($inputArray));
Expected result:
----------------
array (size=4)
0 => string 'shipping' (length=8)
1 => string 'tax_shipping' (length=12)
2 => string 'discount' (length=8)
3 => string 'freeshipping' (length=12)
Or another position for 'freeshipping'. But 'shipping' must be before
'tax_shipping' and 'discount' must be after 'tax_shipping'.
Actual result:
--------------
array (size=4)
0 => string 'tax_shipping' (length=12)
1 => string 'discount' (length=8)
2 => string 'freeshipping' (length=12)
3 => string 'shipping' (length=8)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66544&edit=1