utf8_encode utf8 mb_convert_encoding ejemplo charset array php unicode

mb_convert_encoding - utf8_encode php ejemplo



¿Qué factores hacen que PHP Unicode-incompatible? (7)

Cuando PHP se inició hace varios años, UTF-8 realmente no era compatible. Estamos hablando de una época en la que el sistema operativo no Unicode como Windows 98 / Me todavía estaba actualizado y otros idiomas grandes como Delphi tampoco eran Unicode. No todos los idiomas fueron diseñados con Unicode en mente desde el día 1, y cambiar completamente tu lenguaje a Unicode sin romper muchas cosas es difícil. Delphi solo se convirtió en compatible con Unicode hace uno o dos años, por ejemplo, mientras que otros lenguajes como Java o C # se diseñaron en Unicode desde el día 1.

Entonces cuando PHP creció y se convirtió en PHP 3, PHP 4 y ahora PHP 5, simplemente nadie decidió agregar Unicode. ¿Por qué? Presumiblemente para mantener la compatibilidad con los scripts existentes o porque utf8_de / encode y mb_string ya existían y funcionaban. No estoy seguro, pero creo firmemente que tiene algo que ver con el crecimiento orgánico. Las características no existen simplemente por defecto, tienen que ser escritas por alguien, y eso simplemente no sucedió con PHP todavía.

Editar: Ok, leí la pregunta mal. La pregunta es: ¿cómo se almacenan las cadenas internamente? Si escribo "Währung" o "Écriture", ¿qué codificación se usa para crear los bytes utilizados? En el caso de PHP, es ASCII con una página de códigos. Eso significa: si codigo la cadena usando ISO-8859-15 y la decodifica con alguna página de códigos china, obtendrá resultados raros. La alternativa es en lenguajes como C # o Java, donde todo se almacena como Unicode, lo que significa: ya no hay página de códigos y teóricamente no se puede perder. Recomiendo el artículo de Joel sobre Unicode y conjuntos de caracteres, pero esencialmente se reduce a: ¿Cómo se almacenan las cadenas internamente, y la respuesta con PHP es "No en Unicode", lo que significa que debe ser muy cuidadoso y explícito al procesar cadenas para asegúrese de mantener siempre la cadena en la codificación adecuada durante la entrada, el almacenamiento (base de datos) y la salida, lo cual es muy erróneo.

Puedo usar caracteres UTF-8 muy bien en mis scripts.

De hecho, es posible tener nombres de variables y funciones que contengan caracteres Unicode .

También está la extensión mb_string que trata con cadenas de múltiples bytes, sin embargo, en innumerables artículos PHP es criticado por su falta de soporte Unicode.

No lo entiendo ¿Por qué PHP dice que no es compatible con Unicode?


El concepto de un "personaje multibyte" es el núcleo del problema.

  1. Se filtra un detalle de implementación: debería poder trabajar con la abstracción de un personaje sin saber cómo los implementadores eligen representar los datos, tal vez dependiendo de la plataforma que les convenga para representar todo como UTF16 o UTF32, en cuyo caso todo es multibyte, no es que a los usuarios de la abstracción del personaje les importe.
  2. Es un error: además de un hábito de pensamiento desactualizado donde todos "realmente sabemos" que las cadenas son secuencias de bytes, ahora tenemos que saber que a veces los bytes se agrupan en cosas conocidas como caracteres Unicode, y tienen especiales casos por todo el lugar para lidiar con eso.
  3. Es como un ratón tratando de comerse un elefante. Al encuadrar Unicode como una extensión de ASCII (tenemos cadenas normales y tenemos mb_strings) las cosas van por el camino equivocado, y se cuelga de los casos especiales que se requieren para tratar con caracteres con garabatos graciosos que necesitan más de un byte. Si considera que Unicode proporciona un espacio abstracto para cualquier personaje que necesite, ASCII se adapta a eso sin necesidad de tratarlo como un caso especial.

Lo que se entiende por ''soporte'' es ''soporte nativo''. Eche un vistazo a this para obtener información detallada.


Muchas de las extensiones comunes no tienen soporte Unicode o (lo que es peor) usted "necesita saber" que una cadena contiene secuencias unicode / utf-8, como por ejemplo XMLReader. Y puede marcar una gran diferencia cuando PHP''s glob () llama a FindFirstFileA o FindFirstFileW en win32.
Otro problema (mucho más pequeño pero sorprendentemente a menudo el motivo de la molestia) son las listas de materiales que PHP no reconoce.


Muchas de las funciones de cadena son simplemente envoltorios delgados alrededor de los equivalentes de la biblioteca C, que también tratan todo como una secuencia de bytes. Otra razón es que PHP lleva consigo una gran cantidad de equipaje innecesario de compatibilidad con versiones anteriores y, por lo tanto, se queda atascado con malas decisiones de diseño de 3 y 4.

Tal vez con los espacios de nombres de 5.3 finalmente tendrán una forma de eliminar gradualmente las funciones anteriores.


Tú mismo lo dices: para manejar correctamente las cadenas que contienen caracteres multibyte, necesitas usar una extensión. Olvídese de usar las funciones de extensión en cualquier lugar en lugar de las más familiares, "normales", y sus datos se mutilarán. Lo mismo ocurre si usa una biblioteca de terceros que no se ha actualizado para usar la función de extensión en todas partes.

Además, una serie de codificaciones extremadamente populares aún no está explícitamente respaldada por PHP, presumiblemente porque es imposible hacerlo y es compatible con versiones anteriores.


creo que es en gran medida una dificultad cultural, no técnica.

en cuanto a los problemas técnicos --- y no es del todo trivial implementar unicode en un ecosistema construido sobre el supuesto de que ''un personaje es igual a un byte'' --- los desarrolladores podrían haber copiado gran parte de los esfuerzos de Java o Python (el último con una compatibilidad unicode decente y que funciona en gran medida desde 2001), pero nunca lo hicieron.

cuando leo el hilo de discusión adjunto a la documentación actual oficial para la función utf8_encode() php, utf8_encode() una sensación de vértigo.

firstoff, esa función se llama utf8_encode() ; sin embargo, la documentación indica que la cadena que espera se espera que esté en ISO-8859-1 (también conocida como latin-1). eso es tan rico php, eso es tan 80s.

la mayoría de los comentaristas parecen percibir el Unicode como una carga. hay muchas propuestas sobre cómo convertir cadenas ''de contenido desconocido'', cómo lidiar con cadenas de s con codificaciones mixtas ''(wtf?), o tratar con puntos de código que normalmente causan ruptura porque están más allá de los cuatro bytes de esa función por límite de punto de código.

la discusión se centra en correcciones para deshacerse de garabatos o para evitar las partes problemáticas del comportamiento de esa función. y eso, para mí, es sooo php: todo el mundo está haciendo correcciones, pocas cosas se implementan de una manera fundamentalmente correcta. Si crees que esto es una calumnia de mi parte, aquí hay algunas cositas:

Aunque esto parece romper el alemán Umlaute [äöü] si el documento ya es UTF-8.

(no entender que utf-8 no está diseñado para funcionar cuando se aplica dos veces)

Mire la función iconv (), que ofrece una forma de convertir de 8859 y temió a 1252 en UTF8

(buen punto: abandono del estado de la técnica por parte de los desarrolladores de php; en cambio, implementación propia con errores)

uso de preg_match para detectar si utf8_encode es necesario [...] excluyendo sustitutos [...] excluyendo overlongs

(sugiriendo borrar silenciosamente todo el contenido problemático de las cadenas, dejando solo aquellas cosas que no rompan utf8_encode() ; esto puede hacer que los textos sean ilegibles (o desaparezcan por completo), pero bueno, no más mensajes de error)

para codificar una cadena solo si aún no es UTF-8 [...] mb_detect_encoding($s, "UTF-8")

(como lo señaló otro comentarista , esto no va a funcionar:

$str = ''áéóú''; // ISO-8859-1 mb_detect_encoding($str, ''UTF-8''); // ''UTF-8'' mb_detect_encoding($str, ''UTF-8'', true); // false

así que aquí estamos viendo un error siendo reemplazado por otro. feliz cacería. también, lo que parecen proponer aquí es resolver un problema usando heurística (lenta, incierta) significa que podría y debe ser resuelto con medios mecánicos (rápidos, ciertos)

utf8_ [codificar | decodificar] en realidad también traducirá los caracteres de Windows-1252, no solo de / a ISO-8859-1 como dice la documentación

(nunca se puede confiar en que la documentación oficial de php sea clara o exhaustiva; siempre debe leer años de experiencia de los usuarios que nadie volverá a incluir en los documentos)

He estado trabajando en una función is_utf8 y quería publicarla aquí, además de otras, también tomé en consideración el error de 5000 caracteres

(Una solución para un problema que en gran parte solo existe porque Unicode no se implementa correctamente. También aprendemos que la función utf8_encode() no solo utf8_encode() más de 4 bytes por punto de código, sino que también se romperá si el texto resultante (¿o salida?) excede un límite de 5000 caracteres)

Podría seguir y seguir así. ya entiendes la idea: a juzgar por este hilo, la comunidad php simplemente no parece preparada para entender de qué se tratan las codificaciones y los juegos de caracteres, qué se necesita para construir una infraestructura sólida en general o, específicamente, para implementar unicode de forma adecuada. en cambio, están usando sus andamios, sus cartones, sus uñas y martillos y continúan construyendo este gran edificio llamado php, tirando su cinta adhesiva a cada problema que no se puede deshacer con otro clavo. por supuesto, ese edificio sufrirá por cada viento que viene soplando, como el carácter ocasional pero inesperado legal.

ver este hilo en particular activo durante ocho años no inculca la confianza de que la situación va a mejorar en ocho años a partir de ahora.