3

I have an array which keys are words in portuguese and I'm trying to sort the keys without consider 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 'ábaco' should be the first, for example, but it's the last one because of its first letter "á".

I'm running this script on a Mac with PHP 5.4.

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

Community
  • 1
  • 1
javsmo
  • 1,337
  • 1
  • 14
  • 23

1 Answers1

2

After trying some options, I didn't manage to make ksort respect the collation.

I ended using uksort and making my own comparison function, like this one 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: https://stackoverflow.com/a/11743977/726142

Community
  • 1
  • 1
javsmo
  • 1,337
  • 1
  • 14
  • 23
  • 1
    I am so happy! I was almost about to give up about ksorting my UTF-8 German country names. THANK YOU SO MUCH!!!! – Adam Sep 15 '16 at 12:06