'PHP Sorting - getting 10, 11, 12 ... 1, 20, 2 rather than 1, 10, 11, 12 ... 2, 20
I have parameters like this that need to be sorted (Note: I am sorting AFTER converting the key=>value combinations to strings):
$param['SignatureMethod'] = 'HmacSHA256';
$param['SignatureVersion'] = '2';
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
$param['Version'] = '2011-10-01';
$param['SellerSKUList.SellerSKU.1'] = $sku1;
$param['SellerSKUList.SellerSKU.2'] = $sku2;
$param['SellerSKUList.SellerSKU.3'] = $sku3;
$param['SellerSKUList.SellerSKU.4'] = $sku4;
I have about 30 parameters total. In order to call the endpoint, I need to generate a signature of the parameters in an alphabetical sort.
Using PHP's sort()
works fine for less than 10, but when I try to use 20, it gives me output like this:
SellerSKUList.SellerSKU.10=4574&
SellerSKUList.SellerSKU.11=4575&
...
SellerSKUList.SellerSKU.18=4582&
SellerSKUList.SellerSKU.19=4583&
SellerSKUList.SellerSKU.1=4565&
SellerSKUList.SellerSKU.20=4584&
SellerSKUList.SellerSKU.2=4566
I need it to be like this:
SellerSKUList.SellerSKU.1=4565&
SellerSKUList.SellerSKU.10=4574&
SellerSKUList.SellerSKU.11=4575&
...
SellerSKUList.SellerSKU.18=4582&
SellerSKUList.SellerSKU.19=4583&
SellerSKUList.SellerSKU.2=4566&
SellerSKUList.SellerSKU.20=4584
Sort function looks like this:
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
sort($url);
It seems to me that the sort() function should give desired output, but my experiences show different. Is there another function or another way to sort 1 before 10 within a string?
I have tried:
usort($url,strcmp) => 10,11,12...1,20,2
uksort($url,strcmp) => 10,11,12...20,2,1
natsort($url) => 1,2,3,...10,11,12
Desired: => 1,10,11...19,2,20
Solution 1:[1]
I found a solution - if I uksort($params,strcmp)
before imploding the key=>value pairs, the sort order is correct.
uksort($param, 'strcmp');
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
Thanks to @Thomas Smart's comment here: https://stackoverflow.com/a/12505517/2661831
I'd still like to know if there's a way to sort strings like this:
SellerSKUList.SellerSKU.10=4574&
SellerSKUList.SellerSKU.11=4575&
SellerSKUList.SellerSKU.18=4582&
SellerSKUList.SellerSKU.19=4583&
SellerSKUList.SellerSKU.1=4565&
SellerSKUList.SellerSKU.20=4584&
SellerSKUList.SellerSKU.2=4566
Solution 2:[2]
You can sort your array of strings by isolating the substring before the first =
in the string.
Code: (Demo)
array_multisort(array_map(fn($v) => strtok($v, '='), $array), $array);
var_export($array);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | mickmackusa |