2012-06-13 32 views
7

Estoy trabajando para clientes internacionales que tienen alfabetos muy diferentes y estoy tratando de obtener finalmente una visión general de un flujo de trabajo completo entre PHP y MySQL que asegure que todas las codificaciones de caracteres se inserten correctamente. He leído un montón de tutoriales sobre esto, pero todavía tengo preguntas (hay mucho que aprender) y pensé que podría simplemente poner todo junto aquí y preguntar.Flujo de trabajo UTF8 PHP, MySQL resume

PHP

header('Content-Type:text/html; charset=UTF-8'); 
mb_internal_encoding('UTF-8'); 

HTML

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
<form accept-charset="UTF-8"> .. </form> 

(aunque este último es opcional y más bien una sugerencia, pero yo prefiero la creencia sugiere que no hacer nada)

MySQL

CREATE database_name DEFAULT CHARACTER SET utf8; o ALTER database_name DEFAULT CHARACTER SET utf8; y/o use utf8_general_ci como MySQL intercalación conexión.

(es important to note aquí que esto aumentará el tamaño de la base de datos si se utiliza varchar)

conexión

mysql_query("SET NAMES 'utf8'"); 
mysql_query("SET CHARACTER_SET utf8"); 

empresas lógica

detectar si no UTF8 con mb_detect_encoding() y convierta con ivon().
validar excesivamente largas secuencias de UTF8 y UTF16

$body=preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]|(?<=^|[\x00-\x7F])[\x80-\xBF]+|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/','�',$body); 
$body=preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $body); 

Preguntas

  • se ofrecen mb_internal_encoding('UTF-8') necesaria en PHP 5.3 y superior y si es así ¿significa que tiene que usar todas las funciones de varios bytes en vez de sus funciones principales como mb_substr() en lugar de substr()?

  • ¿Sigue siendo necesario verificar si hay picaduras de entrada mal formadas y, en caso afirmativo, cuál es una función/clase confiable para hacerlo? Posiblemente no quiero quitar datos malos y no sé lo suficiente sobre transliteración.

  • ¿debería ser realmente utf8_general_ci o más bien utf8_bin?

  • ¿falta algo en el flujo de trabajo anterior?

fuentes:

http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ 
http://webcollab.sourceforge.net/unicode.html 
http://stackoverflow.com/a/3742879/1043231 
http://www.adayinthelifeof.nl/2010/12/04/about-using-utf-8-fields-in-mysql/ 
http://akrabat.com/php/utf8-php-and-mysql/ 
+1

bien, entonces la pregunta es? –

+0

lo siento, tuve problemas para publicar esta pregunta, ya que parece que stackoverflow confunde parte de mi URL de origen como código y arroja un error .... funciona ahora ... – Dominik

+0

mb_internal_encoding ('UTF-8') es necesario si mb_internal_encoding() result es distinto de UTF-8. –

Respuesta

1

debería realmente ser utf8_general_ci o más bien utf8_bin?

Debe utilizar utf8_bin para mayúsculas y minúsculas búsqueda, de lo contrario utf8_general_ci

se mb_internal_encoding ('UTF-8') es necesario en PHP 5.3 y superior y si es así ¿significa que tengo que utilizar todas las funciones de varios bytes en lugar de sus funciones básicas como mb_substr() en lugar de substr()?

Sí, por supuesto, si tiene una cadena multibyte necesita la función familiar mb_ *, excepto la función estándar binaria segura php como str_replace(); (y algunos otros)

¿Sigue siendo necesario comprobar si hay picaduras de entrada mal formadas y, de ser así, cuál es una función/clase confiable para hacerlo? Posiblemente no quiero quitar datos malos y no sé lo suficiente sobre transliteración.

Hmm, no, no lo puedes comprobar.

+3

El segundo y el tercer punto no son realistas. El segundo punto depende de qué se trata el "filtrado" ... aún puede hacer '(int) $ _ GET ['utf8var']', por ejemplo.Las funciones de cadena de PHP son binarias. A menos que esté arruinando las cosas, 'str_replace()' y la familia todavía funcionan (con la única excepción del alias UTF8). – Christian

6
  • mb_internal_encoding('UTF-8') no hace nada por sí mismo, sólo se establece el parámetro de codificación por defecto para cada función mb_. Si no está utilizando ninguna función mb_, no hace ninguna diferencia. Si es así, tiene sentido configurarlo para que no tenga que pasar el parámetro $encoding cada vez de forma individual.
  • IMO mb_detect_encoding es prácticamente inútil ya que es fundamentalmente imposible detectar con precisión la codificación de texto desconocido. Debería saber en qué codificación está una burbuja de texto porque tiene una especificación al respecto o necesita analizar los metadatos apropiados, como encabezados o metaetiquetas, donde se especifica la codificación.
  • El uso de mb_check_encoding para comprobar si un blob de texto es válido en la codificación que espera que sea normalmente suficiente. Si no es así, deséchelo y arroje un error apropiado.
  • Con respecto a:

    ¿Quiere decir esto que tengo que usar todas las funciones de varios bytes en lugar de sus funciones básicas

    Si está manipulando cadenas que contienen caracteres de varios bytes, entonces sí, es necesario use las funciones mb_ para evitar obtener resultados incorrectos. Las funciones de cadena principal solo funcionan en un nivel de byte, no en un nivel de carácter, que es lo que generalmente desea al trabajar con cadenas.

  • utf8_general_ci vs utf8_bin sólo hace una diferencia cuando el cotejo , es decir, la clasificación y la comparación de cadenas. Con utf8_bin, los datos se tratan en forma binaria, es decir, solo los datos idénticos son idénticos. Con utf8_general_ci se aplica cierta lógica, p. "é" ordena junto con "e" y la mayúscula se considera igual a minúsculas.