Reputation: 997
I have a user defined sort function which uses a 'global' declaration in order to refer to a multi-dimensional array when deciding on the correct sort order. It used to work fine under PHP 5.1.6 but now fails under 5.3.3.
The code throws PHP warning:
PHP Warning: uksort(): Array was modified by the user comparison function
But the code definitely does not modify the array.
This code duplicates the problem:
$arr = array();
$arr['i1']['val1'] = 99;
$arr['i1']['val2'] = 100;
$arr['i2']['val1'] = 89;
$arr['i2']['val2'] = 101;
function cmp($a, $b)
{
global $arr;
if ($arr[$a]['val2'] > $arr[$b]['val2']) { return 1; }
if ($arr[$a]['val2'] < $arr[$b]['val2']) { return -1; }
return 0;
}
if (uksort($arr, 'cmp'))
{
echo "success";
}
else
{
echo "failure";
}
Upvotes: 1
Views: 958
Reputation: 198117
As sidestepping the issue is so popular, here is the cause of your issue:
global $arr;
I'm sure you sensed that aready, to solve that, remove the line and replace $arr
with $GLOBALS['arr']
. This removes the modification message and you'er accessing the global variable from the symbol table and not the one uksort
is currently operating on.
Example:
<?php
$arr = array();
$arr['i1']['val1'] = 99;
$arr['i1']['val2'] = 100;
$arr['i2']['val1'] = 89;
$arr['i2']['val2'] = 101;
function cmp($a, $b)
{
if ($GLOBALS['arr'][$a]['val2'] > $GLOBALS['arr'][$b]['val2']) { return 1; }
if ($GLOBALS['arr'][$q]['val2'] < $GLOBALS['arr'][$b]['val2']) { return -1; }
return 0;
}
if (uksort($arr, 'cmp'))
{
echo "success\n";
}
else
{
echo "failure\n";
}
print_r($arr);
Output for 5.3.23 - 5.5.3: (other versions crash/misbehave)
success
Array
(
[i1] => Array
(
[val1] => 99
[val2] => 100
)
[i2] => Array
(
[val1] => 89
[val2] => 101
)
)
Ups, maybe that's why you see a warning in more recent versions: (Demo: http://3v4l.org/DkK3v)
Upvotes: 0
Reputation: 522442
If you're not going to sort by the actual keys, don't use uksort
but usort
or uasort
:
function cmp($a, $b) {
return $a['val2'] - $b['val2'];
}
uasort($arr, 'cmp');
Upvotes: 1