Ordenar array alfabéticamente teniendo en cuenta acentos en PHP

orto.jpg
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"
}

 
create gmail account