utf8_decode - utf>- 8 php




UTF-8 hasta el final (9)

Estoy configurando un nuevo servidor y quiero admitir UTF-8 completamente en mi aplicación web. He intentado en el pasado en servidores existentes y siempre parece que tengo que recurrir a la norma ISO-8859-1.

¿Dónde exactamente necesito configurar la codificación / conjuntos de caracteres? Soy consciente de que necesito configurar Apache, MySQL y PHP para hacer esto. ¿Hay alguna lista de verificación estándar que pueda seguir, o tal vez solucionar problemas donde ocurren las discrepancias?

Esto es para un nuevo servidor Linux, ejecutando MySQL 5, PHP 5 y Apache 2.


Acabo de pasar por el mismo problema y encontré una buena solución en los manuales de PHP.

Cambié toda mi codificación de archivos a UTF8 y luego la codificación predeterminada en mi conexión. Esto solucionó todos los problemas.

if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
   printf("Current character set: %s\n", $mysqli->character_set_name());
}

set_charset()


Además de configurar default_charset en php.ini, puede enviar el juego de caracteres correcto usando header() desde su código, antes de cualquier salida:

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

Trabajar con Unicode en PHP es fácil siempre y cuando se dé cuenta de que la mayoría de las funciones de cadena no funcionan con Unicode, y algunas pueden dañar las cadenas por completo . PHP considera que los "caracteres" tienen 1 byte de largo. A veces esto está bien (por ejemplo, explode() solo busca una secuencia de bytes y la usa como separador, por lo que no importa qué caracteres reales busque). Pero otras veces, cuando la función realmente está diseñada para funcionar con caracteres , PHP no tiene idea de que su texto tiene caracteres de varios bytes que se encuentran con Unicode.

Una buena biblioteca para comprobar es phputf8 . Esto vuelve a escribir todas las funciones "malas" para que pueda trabajar con seguridad en cadenas UTF8. También hay extensiones como la extensión mbstring que intentan hacer esto por usted, pero prefiero usar la biblioteca porque es más portátil (pero escribo productos para el mercado masivo, por lo que es importante para mí). Pero phputf8 puede usar mbstring detrás de escena, de todos modos, para aumentar el rendimiento.


En PHP, deberá usar las funciones multibyte o activar mbstring.func_overload . De esa forma, cosas como strlen funcionarán si tienes caracteres que ocupan más de un byte.

También necesitarás identificar el conjunto de caracteres de tus respuestas. Puede usar AddDefaultCharset, como arriba, o escribir el código PHP que devuelve el encabezado. (O puede agregar una etiqueta META a sus documentos HTML).


En mi caso, estaba usando mb_split , que usa mb_split regulares. Por lo tanto, también tuve que asegurarme manualmente de que la codificación de mb_regex_encoding('UTF-8'); regulares fuera utf-8 haciendo mb_regex_encoding('UTF-8');

Como nota al margen, también descubrí ejecutando mb_internal_encoding() que la codificación interna no era utf-8, y lo cambié ejecutando mb_internal_encoding("UTF-8"); .


La mejor respuesta es excelente. Esto es lo que tenía que hacer en una configuración regular de debian / php / mysql:

// storage
// debian. apparently already utf-8

// retrieval
// the mysql database was stored in utf-8, 
// but apparently php was requesting iso. this worked: 
// ***notice "utf8", without dash, this is a mysql encoding***
mysql_set_charset('utf8');

// delivery
// php.ini did not have a default charset, 
// (it was commented out, shared host) and
// no http encoding was specified in the apache headers.
// this made apache send out a utf-8 header
// (and perhaps made php actually send out utf-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// submission
// this worked in all major browsers once apache
// was sending out the utf-8 header. i didnt add
// the accept-charset attribute.

// processing
// changed a few commands in php, like substr,
// to mb_substr

eso fue todo !


Lo único que agregaría a estas sorprendentes respuestas es enfatizar en guardar sus archivos en codificación utf8, he notado que los navegadores aceptan esta propiedad por encima de la configuración de utf8 como su código de codificación. Cualquier editor de texto decente le mostrará esto, por ejemplo, Notepad ++ tiene una opción de menú para el archivo adjunto, le muestra la codificación actual y le permite cambiarla. Para todos mis archivos php uso utf8 sin BOM.

Hace algún tiempo, alguien me pidió que agregara el soporte utf8 para una aplicación php / mysql diseñada por otra persona, noté que todos los archivos estaban codificados en ANSI, así que tuve que usar ICONV para convertir todos los archivos, cambiar las tablas de la base de datos para usar el utf8 charset y utf8_general_ci complacen, agregue 'SET NAMES utf8' a la base de abstracción de la base de datos después de la conexión (si usa 5.3.6 o anterior, de lo contrario tiene que usar charset = utf8 en la cadena de conexión) y cambie las funciones de cadena para usar el multibyte php funciones de cadena equivalentes.


Recientemente descubrí que el uso de strtolower() puede causar problemas en los que los datos se truncan después de un carácter especial.

La solución fue usar

mb_strtolower($string, 'UTF-8');

mb_ usa MultiByte. Soporta más personajes pero en general es un poco más lento.


Si desea que el servidor MySQL decida el conjunto de caracteres, y no PHP como cliente (comportamiento antiguo; preferido, en mi opinión), intente agregar skip-character-set-client-handshake a su my.cnf , bajo [mysqld] , y reiniciar mysql .

Esto puede causar problemas en caso de que esté utilizando algo que no sea UTF8.


Almacenamiento de datos :

  • Especifique el utf8mb4 caracteres utf8mb4 en todas las tablas y columnas de texto en su base de datos. Esto hace que MySQL almacene y recupere físicamente los valores codificados de forma nativa en UTF-8. Tenga en cuenta que MySQL usará implícitamente la codificación utf8mb4 si se especifica una intercalación utf8mb4_* (sin ningún conjunto de caracteres explícito).

  • En versiones anteriores de MySQL (<5.5.3), lamentablemente se verá obligado a usar simplemente utf8 , que solo admite un subconjunto de caracteres Unicode. Desearía estar bromeando.

Acceso a los datos :

  • En el código de su aplicación (por ejemplo, PHP), en cualquier método de acceso a base de datos que use, deberá configurar el conjunto de caracteres de conexión en utf8mb4 . De esta manera, MySQL no realiza ninguna conversión desde su UTF-8 nativo cuando entrega los datos a su aplicación y viceversa.

  • Algunos controladores proporcionan su propio mecanismo para configurar el conjunto de caracteres de conexión, que actualiza su propio estado interno e informa a MySQL de la codificación que se usará en la conexión; este suele ser el enfoque preferido. En PHP:

    • Si está utilizando la capa de abstracción PDO con PHP ≥ 5.3.6, puede especificar el charset de charset en el DSN :

      $dbh = new PDO('mysql:charset=utf8mb4');
      
    • Si está usando mysqli , puede llamar a set_charset() :

      $mysqli->set_charset('utf8mb4');       // object oriented style
      mysqli_set_charset($link, 'utf8mb4');  // procedural style
      
    • Si está atascado con mysql simple pero está ejecutando PHP ≥ 5.2.3, puede llamar a mysql_set_charset .

  • Si el controlador no proporciona su propio mecanismo para configurar el conjunto de caracteres de conexión, es posible que tenga que emitir una consulta para decirle a MySQL cómo su aplicación espera que los datos de la conexión se codifiquen: SET NAMES 'utf8mb4' .

  • La misma consideración con respecto a utf8mb4 / utf8 aplica como anteriormente.

Salida :

  • Si su aplicación transmite texto a otros sistemas, también deberán estar informados de la codificación de caracteres. Con las aplicaciones web, el navegador debe estar informado de la codificación en la que se envían los datos (a través de encabezados de respuesta HTTP o metadatos HTML ).

  • En PHP, puede usar la opción default_charset php.ini, o emitir manualmente el encabezado MIME de Content-Type usted mismo, que es más trabajo pero tiene el mismo efecto.

Entrada :

  • Desafortunadamente, debe verificar que cada cadena recibida sea válida como UTF-8 antes de intentar almacenarla o utilizarla en cualquier lugar. PHP mb_check_encoding() hace el truco, pero tienes que usarlo religiosamente. Realmente no hay forma de evitar esto, ya que los clientes malintencionados pueden enviar datos en cualquier codificación que deseen, y no he encontrado un truco para que PHP haga esto por usted de manera confiable.

  • A partir de mi lectura de la especificación actual de HTML , las siguientes sub-viñetas ya no son necesarias ni válidas para el HTML moderno. Según tengo entendido, los navegadores trabajarán y enviarán datos en el conjunto de caracteres especificado para el documento. Sin embargo, si está apuntando a versiones anteriores de HTML (XHTML, HTML4, etc.), estos puntos pueden ser útiles:

    • Solo para HTML anterior a HTML5 : desea que todos los datos que le envíen los navegadores estén en UTF-8. Desafortunadamente, si utiliza la única forma de hacerlo de manera confiable, agregue el atributo accept-charset a todas sus etiquetas <form> : <form ... accept-charset="UTF-8"> .
    • Solo para HTML antes de HTML5 : tenga en cuenta que la especificación HTML del W3C dice que los clientes "deberían" predeterminados para enviar formularios al servidor en cualquier conjunto de caracteres que el servidor haya servido, pero aparentemente solo es una recomendación, por lo tanto, la necesidad de ser explícita en cada uno de ellos. etiqueta <form> .

Otras consideraciones de código :

  • Obviamente, todos los archivos que va a servir (PHP, HTML, JavaScript, etc.) deben estar codificados en UTF-8 válido.

  • Debe asegurarse de que cada vez que procese una cadena UTF-8, lo haga de manera segura. Esta es, desafortunadamente, la parte difícil. Probablemente querrá hacer un uso extensivo de la extensión mbstring de PHP.

  • Las operaciones de cadena incorporadas de PHP no son seguras por defecto para UTF-8. Hay algunas cosas que puede hacer de manera segura con las operaciones normales de cadena de PHP (como la concatenación), pero para la mayoría de las cosas debería usar la función equivalente mbstring .

  • Para saber lo que estás haciendo (lee: no lo arruines), realmente necesitas conocer UTF-8 y cómo funciona en el nivel más bajo posible. Echa un vistazo a cualquiera de los enlaces de utf8.com para obtener algunos buenos recursos para aprender todo lo que necesitas saber.







utf-8