Estoy leyendo muchos textos de varios canales RSS y los inserto en mi base de datos.
Por supuesto, hay varias codificaciones de caracteres diferentes utilizadas en las fuentes, por ejemplo, UTF-8 e ISO 8859-1.
Desafortunadamente, a veces hay problemas con las codificaciones de los textos. Ejemplo:
El "ß" en "Fußball" debería verse así en mi base de datos: "Ÿ". Si es un "Ÿ", se muestra correctamente.
A veces, el "ß" en "Fußball" se ve así en mi base de datos: "ß". Entonces se muestra incorrectamente, por supuesto.
En otros casos, el "ß" se guarda como un "ß", es decir, sin ningún cambio. Entonces también se muestra incorrectamente.
¿Qué puedo hacer para evitar los casos 2 y 3?
¿Cómo puedo hacer que todo tenga la misma codificación, preferiblemente UTF-8? ¿Cuándo debo usar utf8_encode()
, cuándo debo usar utf8_decode()
(está claro cuál es el efecto pero cuándo debo usar las funciones?) Y cuándo no debo hacer nada con la entrada?
¿Cómo hago que todo tenga la misma codificación? Quizás con la función mb_detect_encoding()
? ¿Puedo escribir una función para esto? Entonces mis problemas son:
- ¿Cómo puedo saber qué codificación utiliza el texto?
- ¿Cómo lo convierto a UTF-8, sea cual sea la codificación anterior?
¿Funcionaría una función como esta?
function correct_encoding($text) {
$current_encoding = mb_detect_encoding($text, 'auto');
$text = iconv($current_encoding, 'UTF-8', $text);
return $text;
}
Lo he probado, pero no funciona. ¿Qué tiene de malo?
fuente
Respuestas:
Si aplica
utf8_encode()
a una cadena ya UTF-8, devolverá una salida UTF-8 ilegible.Hice una función que aborda todos estos problemas. Se llama
Encoding::toUTF8()
.No necesita saber cuál es la codificación de sus cadenas. Puede ser Latin1 ( ISO 8859-1) , Windows-1252 o UTF-8, o la cadena puede tener una combinación de ellos.
Encoding::toUTF8()
convertirá todo a UTF-8.Lo hice porque un servicio me estaba dando una fuente de datos desordenados, mezclando UTF-8 y Latin1 en la misma cadena.
Uso:
Descargar:
https://github.com/neitanod/forceutf8
He incluido otra función,
Encoding::fixUFT8()
que arreglará cada cadena UTF-8 que se vea confusa.Uso:
Ejemplos:
dará salida:
He transformado la función (
forceUTF8
) en una familia de funciones estáticas en una clase llamadaEncoding
. La nueva función esEncoding::toUTF8()
.fuente
Primero debe detectar qué codificación se ha utilizado. Mientras analiza las fuentes RSS (probablemente a través de HTTP), debe leer la codificación del
charset
parámetro delContent-Type
campo de encabezado HTTP . Si no está presente, lea la codificación delencoding
atributo de la instrucción de procesamiento XML . Si eso también falta, use UTF-8 como se define en la especificación .Editar Aquí es lo que probablemente haría:
Me gustaría usar cURL para enviar a buscar la respuesta. Eso le permite establecer campos de encabezado específicos y buscar el encabezado de respuesta también. Después de buscar la respuesta, debe analizar la respuesta HTTP y dividirla en encabezado y cuerpo. El encabezado debe contener el
Content-Type
campo de encabezado que contiene el tipo MIME y (con suerte) elcharset
parámetro con la codificación / juego de caracteres también. De lo contrario, analizaremos la PI de XML para determinar la presencia delencoding
atributo y obtendremos la codificación a partir de ahí. Si eso también falta, las especificaciones XML definen el uso de UTF-8 como codificación.fuente
charset=
yencoding=
y no sólo en las posiciones adecuadas. Y en tercer lugar, no está comprobando si se acepta la codificación declarada.Detectar la codificación es difícil.
mb_detect_encoding
funciona adivinando, en función de una serie de candidatos que lo aprueba. En algunas codificaciones, ciertas secuencias de bytes no son válidas, por lo que puede distinguir entre varios candidatos. Desafortunadamente, hay muchas codificaciones, donde los mismos bytes son válidos (pero diferentes). En estos casos, no hay forma de determinar la codificación; Puede implementar su propia lógica para hacer conjeturas en estos casos. Por ejemplo, los datos que provienen de un sitio japonés podrían tener más probabilidades de tener una codificación japonesa.Mientras solo trate con idiomas de Europa occidental, las tres codificaciones principales a considerar son
utf-8
,iso-8859-1
ycp-1252
. Dado que estos son valores predeterminados para muchas plataformas, también es más probable que se denuncien erróneamente. P.ej. Si las personas usan diferentes codificaciones, es probable que sean francos al respecto, ya que de lo contrario su software se rompería muy a menudo. Por lo tanto, una buena estrategia es confiar en el proveedor, a menos que la codificación se informe como uno de esos tres. Aún debe verificar que sea válido, usandomb_check_encoding
(tenga en cuenta que válido no es lo mismo que ser , la misma entrada puede ser válida para muchas codificaciones). Si es uno de esos, puede usarmb_detect_encoding
para distinguir entre ellos Afortunadamente eso es bastante determinista; Solo necesita usar la secuencia de detección adecuada, que esUTF-8,ISO-8859-1,WINDOWS-1252
.Una vez que haya detectado la codificación, debe convertirla a su representación interna (
UTF-8
es la única opción sensata). La función seutf8_encode
transformaISO-8859-1
enUTF-8
, por lo que solo se puede usar para ese tipo de entrada en particular. Para otras codificaciones, usemb_convert_encoding
.fuente
Una forma realmente agradable de implementar una
isUTF8
función se puede encontrar en php.net :fuente
mb_check_encoding($string, 'UTF-8')
Esta hoja de referencia enumera algunas advertencias comunes relacionadas con el manejo de UTF-8 en PHP: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
Esta función de detección de caracteres multibyte en una cadena también podría ser útil ( fuente ):
fuente
Un poco de cabeza. Usted dijo que el "ß" debería mostrarse como "Ÿ" en su base de datos.
Esto probablemente se deba a que está utilizando una base de datos con codificación de caracteres Latin-1 o posiblemente su conexión PHP-MySQL está configurada incorrectamente, esto es, P cree que su MySQL está configurado para usar UTF-8, por lo que envía datos como UTF-8 , pero su MySQL cree que PHP está enviando datos codificados como ISO 8859-1, por lo que una vez más puede intentar codificar sus datos enviados como UTF-8, causando este tipo de problemas.
Echa un vistazo a mysql_set_charset . Te puede ayudar.
fuente
Su codificación parece codificada en UTF-8 dos veces ; es decir, desde alguna otra codificación, a UTF-8 y nuevamente a UTF-8. Como si tuviera ISO 8859-1, convertido de ISO 8859-1 a UTF-8, y tratado la nueva cadena como ISO 8859-1 para otra conversión a UTF-8.
Aquí hay un pseudocódigo de lo que hiciste:
Deberías intentarlo:
mb_detect_encoding()
o lo que quieras usarEso supone que en la conversión "intermedia" usó ISO 8859-1. Si usó Windows-1252, conviértalo a Windows-1252 (latin1). La codificación fuente original no es importante; la que usaste en la segunda conversión defectuosa es.
Esta es mi suposición sobre lo que sucedió; Hay muy poco más que podría haber hecho para obtener cuatro bytes en lugar de un byte ASCII extendido.
El idioma alemán también utiliza ISO 8859-2 y Windows-1250 (Latin-2).
fuente
Lo interesante de
mb_detect_encoding
ymb_convert_encoding
es que el orden de las codificaciones que sugieres sí importa:Por lo tanto, es posible que desee utilizar un orden específico al especificar las codificaciones esperadas. Aún así, tenga en cuenta que esto no es infalible.
fuente
if ($input_is_not_UTF8) $input_is_windows1252 = true;
. Ver también: html.spec.whatwg.org/multipage/…Debe probar el conjunto de caracteres en la entrada ya que las respuestas pueden codificarse con diferentes codificaciones.
Obligo a que todo el contenido se envíe a UTF-8 mediante detección y traducción mediante la siguiente función:
Esa rutina convertirá todas las variables PHP que provienen del host remoto en UTF-8.
O ignore el valor si la codificación no se pudo detectar o convertir.
Puede personalizarlo según sus necesidades.
Solo invocalo antes de usar las variables.
fuente
Resolver la codificación de caracteres de los canales RSS parece ser complicado . Incluso las páginas web normales a menudo omiten o mienten acerca de su codificación.
Por lo tanto, podría intentar usar la forma correcta de detectar la codificación y luego recurrir a alguna forma de autodetección (adivinar).
fuente
charset
/encoding
: describa la codificación en la que están codificados los datos.Sé que esta es una pregunta anterior, pero creo que una respuesta útil nunca está de más. Estaba teniendo problemas con mi codificación entre una aplicación de escritorio, SQLite y las variables GET / POST. Algunos estarían en UTF-8, otros estarían en ASCII, y básicamente todo se arruinaría cuando se involucraran caracteres extranjeros.
Aquí está mi solución. Elimina su OBTENER / POSTAR / SOLICITAR (omití las cookies, pero podría agregarlas si lo desea) en cada carga de la página antes del procesamiento. Funciona bien en un encabezado. PHP lanzará advertencias si no puede detectar la codificación de origen automáticamente, por lo que estas advertencias se suprimen con @ 's.
fuente
Estuve buscando soluciones para la codificación desde hace siglos , ¡y esta página es probablemente la conclusión de años de búsqueda! Probé algunas de las sugerencias que mencionaste y aquí están mis notas:
Esta es mi cadena de prueba:
Hago un INSERT para guardar esta cadena en una base de datos en un campo que está configurado como
utf8_general_ci
El conjunto de caracteres de mi página es UTF-8.
Si hago un INSERTAR así, en mi base de datos, probablemente tenga algunos personajes procedentes de Marte ...
Entonces necesito convertirlos en algún UTF-8 "sano". Lo intenté
utf8_encode()
, pero aún los personajes extraterrestres estaban invadiendo mi base de datos ...Así que intenté usar la función
forceUTF8
publicada en el número 8, pero en la base de datos la cadena guardada se ve así:Entonces, al recopilar más información en esta página y fusionarla con otra información en otras páginas, resolví mi problema con esta solución:
Ahora en mi base de datos tengo mi cadena con la codificación correcta.
NOTA: ¡ Solo la nota para cuidar está en funcionamiento
mysql_client_encoding
! Debe estar conectado a la base de datos, porque esta función quiere un ID de recurso como parámetro.Pero bueno, acabo de volver a codificar antes de mi INSERT, así que para mí no es un problema.
fuente
UTF-8
codificación de cliente para mysql en primer lugar? No necesitaría la conversión manual de esta maneraEs muy sencillo: cuando se consigue algo que no es UTF-8, debe codificar que en UTF-8.
Por lo tanto, cuando va a buscar una determinada fuente que es ISO 8859-1, analícela
utf8_encode
.Sin embargo, si va a buscar una fuente UTF-8, no necesita hacer nada.
fuente
php.net/
mb_detect_encoding
o
Realmente no sé cuáles son los resultados, pero te sugiero que solo tomes algunos de tus feeds con diferentes codificaciones y pruebes si
mb_detect_encoding
funciona o no.la actualización
automática es la abreviatura de "ASCII, JIS, UTF-8, EUC-JP, SJIS". devuelve el juego de caracteres detectado, que puede usar para convertir la cadena a utf-8 con iconv .
No lo he probado, así que no hay garantía. y tal vez hay una manera más simple.
fuente
@harpax que funcionó para mí. En mi caso, esto es lo suficientemente bueno:
fuente
Después de ordenar sus scripts php, no olvide decirle a mysql qué conjunto de caracteres está pasando y le gustaría recibir.
Ejemplo: establecer el conjunto de caracteres utf8
Pasar datos utf8 a una tabla latin1 en una sesión de E / S latin1 da esos desagradables birdfeets. Lo veo cada dos días en las tiendas de comercio electrónico. Atrás y cuarto puede parecer correcto. Pero phpmyadmin mostrará la verdad. Al decirle a mysql qué conjunto de caracteres está pasando, manejará la conversión de datos de mysql por usted.
Cómo recuperar los datos mysql revueltos existentes es otro hilo a tratar. :)
fuente
Esta versión es para el idioma alemán, pero puede modificar los $ CHARSETS y los $ TESTCHARS
fuente
Obtenga codificación de encabezados y conviértalo a utf-8.
fuente
Ÿ
es Mojibake paraß
. En su base de datos, puede tener hexadecimalUsted debe no utilizar cualquier codificación / decodificación de funciones en PHP; en su lugar, debe configurar la base de datos y la conexión a ella correctamente.
Si MySQL está involucrado, vea: Problemas con los caracteres utf8; lo que veo no es lo que almacené
fuente
Encuentro la solución aquí http://deer.org.ua/2009/10/06/1/
Creo que @ es una mala decisión y hago algunos cambios a la solución desde deer.org.ua;
fuente
La respuesta más votada no funciona. Aquí está el mío y espero que ayude.
fuente
Cuando intentas manejar varios idiomas como el japonés y el coreano, puedes meterte en problemas. mb_convert_encoding con el parámetro 'auto' no funciona bien. Establecer mb_detect_order ('ASCII, UTF-8, JIS, EUC-JP, SJIS, EUC-KR, UHC') no ayuda, ya que detectará EUC- * incorrectamente.
Llegué a la conclusión de que siempre que las cadenas de entrada provengan de HTML, debe usar 'charset' en un meta elemento. Uso Simple HTML DOM Parser porque admite HTML no válido.
El fragmento a continuación extrae el elemento del título de una página web. Si desea convertir toda la página, puede que desee eliminar algunas líneas.
fuente
Tuve el mismo problema con phpQuery ( ISO-8859-1 en lugar de UTF-8 ) y este truco me ayudó:
mb_internal_encoding('UTF-8')
,phpQuery::newDocumentHTML($html, 'utf-8')
,mbstring.internal_encoding
Y otras manipulaciones no tuvieron ningún efecto.fuente
Probar sin 'auto'
Es decir:
en vez de:
Puede encontrar más información aquí: mb_detect_encoding
fuente