2011-12-15 9 views
5

Básicamente, si dos cadenas se evalúan como las mismas en mi base de datos, también me gustaría poder verificarlas a nivel de aplicación. Por ejemplo, si alguien ingresa "bjork" en un campo de búsqueda, quiero que PHP pueda unirlo a la cadena "Björk" tal como lo haría MySQL.Cómo emular la compilación de MySQLs utf8_general_ci en las comparaciones de cadenas PHP

Supongo que PHP no tiene un equivalente directo a las opciones de intercalación de MySQL, y que lo más fácil sería escribir una función simple que convierta las cadenas, usando strtolower() para hacerlas uniformemente minúsculas y strstr() para reemplazar caracteres de varios bytes con sus correspondientes equivalentes ASCII.

¿Es eso una suposición precisa? ¿Alguien tiene una matriz a prueba de tontos útil para usar como el segundo parámetro de Strstr() para conformar cadenas como harían varias intercalaciones de MySQL (específicamente para mis necesidades actuales, utf8_general_ci)? O, sin eso, ¿dónde podría encontrar documentación de cómo exactamente las diferentes colaciones en MySQL tratan a varios personajes? (Vi en alguna parte que en algunas colaciones ß se trata como S y en otras como Ss, por ejemplo, pero no describía la evaluación de cada personaje.)

+0

es posible ejecutar una consulta mysql y decirle a mysql qué intercalación usar para las cadenas que se le pasan, para ejecutar la comparación en el servidor mysql. podría no ser muy rápido pero crearía el comportamiento exacto. – hakre

+0

Debo agregar que la eficiencia es de suma importancia. – Thor

Respuesta

0

¿Has mirado la clase de intercalación de PHP? http://www.php.net/manual/en/class.collator.php

+0

Eso es interesante. No sabía que existía. Por desgracia, no pude averiguar en la documentación qué configuración se comportaría de la misma manera que MySQL. Además, supongo que estoy más interesado en poder ajustar cadenas, lo que daría la posibilidad de comparar una cadena con una matriz, por ejemplo. – Thor

3

Esto es lo que he estado usando, pero todavía no lo he probado para una coherencia total con MySQL.

function collation_conform($string,$collation='utf8_general_ci') 
{ 

    if($collation === 'utf8_general_ci') 
    { 
     if(!is_string($string)) 
      return $string; 

     $string = strtr($string, array(
      'Š'=>'S', 'š'=>'s', 'Ð'=>'D', 'Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 
      'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 
      'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 
      'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss','à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 
      'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 
      'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 
      'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'ƒ'=>'f')); 

     return strtolower($string); 
    } 
    else die('Unsupported Collation (collation_conform() collation_helper.php)'); 
} 
-1

Pruebe el siguiente código.

$s1 = 'Björk'; 
$s2 = 'bjork'; 

var_dump(
    is_same_string($s1, $s2) 
); 

function is_same_string($str, $str2, $locale = 'en_US') 
{ 
    $coll = collator_create($locale); 
    collator_set_strength($coll, Collator::PRIMARY); 
    return 0 === collator_compare($coll, $str, $str2); 
} 
+0

Era "Cómo emular MySQLs utf8_general_ci colación [...]" y respondiste con '$ locale = 'en_US''. ¿Estás seguro de que estos dos son iguales? En utf8_general_ci 'a' = 'ą' pero 'L'! = 'Ł' ... – Kalmar

Cuestiones relacionadas