admin管理员组

文章数量:1314292

I ran a few tests on 2d arrays and found that in some contexts, native sorting functions can give unexpected results when array keys are 2, 5, 10, or 13.

$expected = range(0, 11);
$array = array_fill(0, 50, $expected);  // create a 2d array with 50 rows containing 12 integer values

array_walk($array, 'sort');  // sort the 12 integer values within each row

var_export(
    array_filter(
        $array,
        fn($row) => $row !== $expected  // only keep rows which are sorted incorrectly
    )
);
  • sort() second level int values test
  • sort() second level float values test
  • sort() second level numeric string values test
  • sort() second level non-numeric string values test
  • krsort() second level numeric string values test
  • krsort() second level int values test
  • krsort() second level non-numeric string values test

❌ Sorting rows of alphanumeric strings causes too many unintended sorting outcomes to list.

What is causing these inconsistencies?

I ran a few tests on 2d arrays and found that in some contexts, native sorting functions can give unexpected results when array keys are 2, 5, 10, or 13.

$expected = range(0, 11);
$array = array_fill(0, 50, $expected);  // create a 2d array with 50 rows containing 12 integer values

array_walk($array, 'sort');  // sort the 12 integer values within each row

var_export(
    array_filter(
        $array,
        fn($row) => $row !== $expected  // only keep rows which are sorted incorrectly
    )
);
  • sort() second level int values test
  • sort() second level float values test
  • sort() second level numeric string values test
  • sort() second level non-numeric string values test
  • krsort() second level numeric string values test
  • krsort() second level int values test
  • krsort() second level non-numeric string values test

❌ Sorting rows of alphanumeric strings causes too many unintended sorting outcomes to list.

What is causing these inconsistencies?

Share Improve this question edited Feb 2 at 13:36 mickmackusa asked Feb 2 at 13:17 mickmackusamickmackusa 48.1k13 gold badges93 silver badges161 bronze badges Recognized by PHP Collective
Add a comment  | 

1 Answer 1

Reset to default 4

The seldom realized issue arises because array_walk($array, 'sort'); or array_walk($array, sort(...)); calls sort() with an unintended second argument.

When array_walk() is implemented in this way, it passes two arguments to the callback function -- $value by reference as well as the $key.

The second argument of sort() is meant to be for a consistent sorting flag, not ever-changing array keys.

Numeric keys of 2, 5, 10, and 13 correspond to sorting flag constants which call for comparing values as strings instead of numeric values.

The fundamental sorting constants list:

Constant Integer Value Description
SORT_REGULAR 0 Standard comparison
SORT_NUMERIC 1 Numeric comparison
SORT_STRING 2 String comparison
SORT_LOCALE_STRING 5 String comparison based on locale settings
SORT_NATURAL 6 Natural order string comparison
SORT_FLAG_CASE 8 Case-insensitive sorting (used with SORT_STRING or SORT_NATURAL)

Relevant combined flags:

Constant Integer Value
SORT_STRING | SORT_FLAG_CASE 10 (2 + 8)
SORT_LOCALE_STRING | SORT_NATURAL 13 (5 + 6)

Even if some Stack Overflow posts work properly in their context, it would be better practice to not allow your codebase to use these potential silent-bug producers.

本文标签: