php - pasar - utf8_decode javascript
UTF-8 hasta el final (13)
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());
}
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.
El soporte de Unicode en PHP sigue siendo un gran lío. Si bien es capaz de convertir una cadena ISO8859 (que usa internamente) a utf8, carece de la capacidad de trabajar con cadenas Unicode de forma nativa, lo que significa que todas las funciones de procesamiento de cadenas dañarán y dañarán sus cadenas. Por lo tanto, debe usar una biblioteca separada para el soporte adecuado de utf8 o reescribir todas las funciones de manejo de cadenas.
La parte fácil es simplemente especificar el conjunto de caracteres en los encabezados HTTP y en la base de datos, pero nada de eso importa si su código PHP no genera un UTF8 válido. Esa es la parte difícil, y PHP no te da prácticamente ayuda allí. (Creo que PHP6 se supone que soluciona lo peor de esto, pero todavía falta un poco)
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");
.
En primer lugar, si estás en <5.3PHP entonces no. Tienes un montón de problemas para abordar.
Me sorprende que nadie haya mencionado la biblioteca intl , la que tiene un buen soporte para Unicode , grafemas , operaciones de cadenas , localización y mucho más, consulte a continuación.
Citaré información sobre el soporte de Unicode en PHP por las slides Elizabeth Smith en PHPBenelux''14
INTL
Bueno:
- Envoltura alrededor de la biblioteca de la UCI
- Configuraciones regionales estandarizadas, establecer la configuración regional por script
- Formateo de numero
- Formato de moneda
- Formato de mensaje (reemplaza a gettext)
- Calendarios, fechas, zona horaria y hora.
- Transliterador
- Spoofchecker
- Paquetes de recursos
- Convertidores
- Soporte de IDN
- Grafemas
- Colación
- Iteradores
Malo:
- No soporta zend_multibite
- No admite la conversión de salida de entrada HTTP
- No soporta la sobrecarga de funciones
mb_string
- Habilita el soporte zend_multibyte
- Admite codificación HTTP de entrada / salida transparente
- Proporciona algunos envoltorios para la funcionalidad como strtoupper
ICONV
- Primaria para la conversión de caracteres
- Controlador de búfer de salida
- funcionalidad de codificación mime
- conversión
- algunos ayudantes de cuerda (len, substr, strpos, strrpos)
- Filtro de flujo
stream_filter_append($fp, ''convert.iconv.ISO-2022-JP/EUC-JP'')
BASES DE DATOS
- mysql: Conjunto de caracteres y compilación en tablas y en conexión (no la intercalación). Tampoco use mysql - msqli o PDO
- postgresql: pg_set_client_encoding
- sqlite (3): asegúrese de que haya sido compilado con unicode y soporte internacional
Algunos otros gotchas
- No puede usar nombres de archivos Unicode con PHP y Windows a menos que use una extensión de la tercera parte.
- Envíe todo en ASCII si está usando exec, proc_open y otras llamadas de línea de comandos
- El texto sin formato no es texto sin formato, los archivos tienen codificaciones
- Puedes convertir archivos sobre la marcha con el filtro iconv
Actualizaré esta respuesta en caso de que las cosas cambien las características agregadas y así sucesivamente.
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.
Me gustaría añadir una cosa a la excelente respuesta de chazomaticus :
Tampoco olvide la etiqueta META (como esta, o la versión HTML4 o XHTML de la misma ):
<meta charset="utf-8">
Eso parece trivial, pero IE7 me ha dado problemas con eso antes.
Estaba haciendo todo bien; La base de datos, la conexión de la base de datos y el encabezado HTTP de tipo de contenido se configuraron en UTF-8, y funcionó bien en todos los demás navegadores, pero Internet Explorer aún insistió en usar la codificación "Europa Occidental".
Resultó que a la página le faltaba la etiqueta META. Añadiendo que resolvió el problema.
Editar:
El W3C en realidad tiene una sección bastante grande dedicada a I18N . Tienen una serie de artículos relacionados con este problema, que describen el lado HTTP, (X) HTML y CSS de las cosas:
- Preguntas frecuentes: Cambiar la codificación de la página HTML (X) a UTF-8
- Declarar codificaciones de caracteres en HTML
- Tutorial: conjuntos de caracteres y codificaciones en XHTML, HTML y CSS
- Configuración del parámetro charset HTTP
Recomiendan usar tanto el encabezado HTTP como la metaetiqueta HTML (o la declaración XML en caso de que XHTML sirva como XML).
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.
Viejo tema, lo sé. Encontré un problema con alguien que usaba PDO y la respuesta fue usar esto para la cadena de conexión PDO:
$pdo = new PDO(
''mysql:host=mysql.example.com;dbname=example_db'',
"username",
"password",
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
El sitio del que tomé esto está abajo, pude obtenerlo usando google cache por suerte.
Almacenamiento de datos :
Especifique el
utf8mb4
caracteresutf8mb4
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ónutf8mb4
si se especifica una intercalaciónutf8mb4_*
(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
decharset
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 deContent-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>
.
- 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
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.