php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70937 natsort/natcasesort change key data type
Submitted: 2015-11-18 13:57 UTC Modified: 2015-11-19 08:15 UTC
From: David dot Gausmann at measX dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 5.6.15 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: David dot Gausmann at measX dot com
New email:
PHP Version: OS:

 

 [2015-11-18 13:57 UTC] David dot Gausmann at measX dot com
Description:
------------
I am using php to transfer arrays via JSON.
After using natsort/natcasesort for sorting the resulting data aren't JSON arrays anymore. This happens because natsort/natcasesort are changing the datatype of the array keys from int to string (but only when the data becomes sorted; otherwise the key data type won't change).

A workaround is it to use usort with strnatcmp/strnatcasecmp as second parameter.

Test script:
---------------
<?php
$array = array('b', 'a', 'c');

echo "After creation:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
sort($array);
echo "After sort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
rsort($array);
echo "After rsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natsort($array);
echo "After natsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natcasesort($array);
echo "After natcasesort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
usort($array, 'strnatcmp');
echo "After usort(strnatcmp):<br>\r\n", json_encode($array), "<br>\r\n";

?>

Expected result:
----------------
In all used sort functions the result should be an array like ["a","b","c"].

Actual result:
--------------
Instead natsort/natcasesort return {"1":"a","0":"b","2":"c"} in JSON syntax.
Only the other sort functions return an array like ["a","b","c"].

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-11-18 18:23 UTC] nhojohl at gmail dot com
This is because natsort and natcasesort maintain the key association (it does not re-key the array).

An array must have sequential keys in order for json_encode to encode it as a natural array, otherwise it converts the array to an associative array (an object) and maintains the key value association.

If you use array_values on the resulting array after sorting it; it'l resolve your issue (relevant reference: http://php.net/manual/en/function.natcasesort.php#32610)

Example:

$array = array('b', 'a', 'c');
natsort($array);
$array = array_values($array);
echo "After natsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natcasesort($array);
$array = array_values($array);
echo "After natcasesort:<br>\r\n", json_encode($array), "<br>\r\n";
 [2015-11-19 02:57 UTC] laruence@php.net
-Status: Open +Status: Not a bug
 [2015-11-19 02:57 UTC] laruence@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2015-11-19 08:15 UTC] David dot Gausmann at measX dot com
Hello again,

I've read the documentation before creating this bug report, but I still didn't get it after I found out how it behaves. The documentation simply doesn't sound like "be aware your numeric keys will turn into strings".

It says:
>> This function implements a sort algorithm that orders alphanumeric strings in the way a human being would while maintaining key/value associations. This is described as a "natural ordering". An example of the difference between this algorithm and the regular computer string sorting algorithms (used in sort()) can be seen in the example below. <<

The information must be hidden in "while maintaining key/value associations", but it is not clear which consequences this has.
An additional information like this would be fine:
>> The maintenance of the key/value associations is performed via conversion of the numeric keys into strings. Unlike sort() elements will be accessed after sorting via their old index (e. g. $array[0] will return the element with index 0 and not the first element). If you don't need this behaviour, call array_values after sort or use usort with 'strnatcasecmp'. <<

The same goes for natcasesort. It would be very fine when you add something like that to the documentation.

Kind Regards
David Gausmann
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 01 20:01:36 2025 UTC