A la hora de ordenar vectores en PHP tenemos una colección de funciones que nos ayudan. Pero no sirven de mucho a la hora de trabajar con textos acentuados en idiomas, como castellano, catalán, francés, etc ...
Éstas funciones están programadas inicialmente en inglés, por tanto no tienen en cuenta los caracteres especiales y acentos, que en el idioma de shakespeare no existen pero si en idiomas como los ya mencionados
Problema
Se puede convertir en un gran problema la ordenación en listas de palabras o texto que comiencen con carácteres acentuados, como por ejemplo con una Á. Si decidimos usar la función sort sobre un vector:
$coleccion=array(); $coleccion[]="Ornitorrinco"; $coleccion[]="Antes o despues"; $coleccion[]="Ni despues ni antes"; $coleccion[]="Óptica"; $coleccion[]="Ácido"; sort($coleccion,SORT_STRING);
El código anterior devuelve el arreglo ordenado, pero en dos partes, ya que primero ordena todo aquello que no esté acentuado y luego el resto, cualquier texto q comience por Á lo ordenará a partir de la z, nos dará la siguiente salida por tanto:
array(5) {
[0]=>
string(15) "Antes o despues"
[1]=>
string(19) "Ni despues ni antes"
[2]=>
string(12) "Ornitorrinco"
[3]=>
string(6) "Ácido"
[4]=>
string(7) "Óptica"
}
Solución
Utilizar un "callback" que viene a ser utilizar una función definida por nosotros para la ordenación de los elementos de ese vector. De esta forma tendríamos una solución como:
function callback($name1,$name2){
$patterns = array(
'a' => '(á|à|â|ä|Á|À|Â|Ä)',
'e' => '(é|è|ê|ë|É|È|Ê|Ë)',
'i' => '(í|ì|î|ï|Í|Ì|Î|Ï)',
'o' => '(ó|ò|ô|ö|Ó|Ò|Ô|Ö)',
'u' => '(ú|ù|û|ü|Ú|Ù|Û|Ü)'
);
$name1 = preg_replace(array_values($patterns), array_keys($patterns), $name1);
$name2 = preg_replace(array_values($patterns), array_keys($patterns), $name2);
return strcasecmp($name1, $name2);
}
uasort($coleccion,"callback");
El truco "bàsico" está en reemplazar todos los acentos previamente a la función de comparación strcasecmp. El código anterior nos dará una salida bien ordenada alfabéticamente:
array(5) {
[3]=>
string(6) "Ácido"
[0]=>
string(15) "Antes o despues"
[1]=>
string(19) "Ni despues ni antes"
[4]=>
string(7) "Óptica"
[2]=>
string(12) "Ornitorrinco"
}