Ksort doesn't honor LC_COLLATE

I have an array whose keys are words in Portuguese, and I am trying to sort the keys without regard to accents.

I have the following code, but it doesn't work.

    $array = array('ábaco' => 1, 
               'aéreo' => 2, 
               'abecedário' => 3, 
               'andar' => 4, 
               'absurdo' =>  5);

$locale = ( defined('PHP_OS') && 
            stristr(PHP_OS, 'win') && 
            !stristr(PHP_OS, 'darwin')) ? 'Portuguese_Brazil.1252' : 'pt_BR.UTF-8';

setlocale(LC_COLLATE, $locale);
var_dump($locale);
ksort($array, SORT_LOCALE_STRING);
var_dump($array);

      

The result is the following:

string 'pt_BR.UTF-8' (length=11)
array (size=5)
  'abecedário' => int 3
  'absurdo' => int 5
  'andar' => int 4
  'aéreo' => int 2
  'ábaco' => int 1

      

The word "baba" should be the first, for example, but the last because of its first letter "á".

I am running this script on Mac with PHP 5.4.

This problem seems to be different from the one described on this question: PHP ksort seems to be unaffected by setlocale

+3


source to share


1 answer


After some attempts, I have been unable to get ksort to respect the collation.

I ended up using uksort and created my own comparison function as shown below.



function stripAccents($str) {
    return strtr(
           utf8_decode($str), 
           utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'), 
           'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
}

function compareWords($w1, $w2){
    return strcasecmp(stripAccents($w1), stripAccents($w2));
}

uksort($array, "compareWords");

      

The stripAccents function was borrowed from this answer: fooobar.com/questions/92129 / ...

+2


source







All Articles