utf8_encode utf8 decodificar array php encoding utf-8

decodificar - utf8_encode array php



Garantizar utf-8 vĂ¡lido en PHP (6)

Estoy usando PHP para manejar el texto de una variedad de fuentes. No anticipo que vaya a ser algo más que UTF-8, ISO-8859-1, o quizás WINDOWS-1252. Si se trata de algo más que uno de esos, solo necesito asegurarme de que el texto se convierta en una cadena UTF-8 válida, incluso si se pierden caracteres. ¿La opción // TRANSLIT de iconv lo soluciona? Por ejemplo, ¿este código aseguraría que una cadena es segura de insertar en un documento codificado UTF-8 (o base de datos)?

function make_safe_for_utf8_use($string) { $encoding = mb_detect_encoding($string, "UTF-8,ISO-8859-1,WINDOWS-1252"); if ($encoding != ''UTF-8'') { return iconv($encoding, ''UTF-8//TRANSLIT'', $string); } else { return $string; } }


UTF-8 puede almacenar cualquier caracter Unicode. Si su codificación es otra cosa, incluyendo ISO-8859-1 o Windows-1252, UTF-8 puede almacenar cada carácter en ella. Por lo tanto, no tiene que preocuparse por perder ningún carácter al convertir una cadena de cualquier otra codificación a UTF-8.

Además, tanto ISO-8859-1 como Windows-1252 son codificaciones de un solo byte donde cualquier byte es válido. No es técnicamente posible distinguir entre ellos. Elegiría Windows-1252 como su coincidencia predeterminada para secuencias que no sean UTF-8, ya que los únicos bytes que decodifican de manera diferente son el rango 0x80-0x9F. Estos decodifican a varios personajes como comillas inteligentes y al euro en Windows-1252, mientras que en ISO-8859-1 son caracteres de control invisibles que casi nunca se usan. Los navegadores web a veces dicen que están usando ISO-8859-1, pero a menudo usarán Windows-1252.

¿Este código aseguraría que una cadena es segura de insertar en un documento codificado en UTF-8?

Sin duda, querrá establecer el parámetro ''estricto'' opcional en VERDADERO para este propósito. Pero no estoy seguro de que esto realmente cubra todas las secuencias UTF-8 no válidas. La función no pretende verificar una secuencia de bytes para la validez UTF-8 explícitamente. Se han conocido casos en los que mb_detect_encoding adivinaría incorrectamente el UTF-8 anteriormente, aunque no sé si aún puede suceder en modo estricto.

Si quiere estar seguro, hágalo usted mismo usando la expresión regular recomendada por W3 :

if (preg_match(''%^(?: [/x09/x0A/x0D/x20-/x7E] # ASCII | [/xC2-/xDF][/x80-/xBF] # non-overlong 2-byte | /xE0[/xA0-/xBF][/x80-/xBF] # excluding overlongs | [/xE1-/xEC/xEE/xEF][/x80-/xBF]{2} # straight 3-byte | /xED[/x80-/x9F][/x80-/xBF] # excluding surrogates | /xF0[/x90-/xBF][/x80-/xBF]{2} # planes 1-3 | [/xF1-/xF3][/x80-/xBF]{3} # planes 4-15 | /xF4[/x80-/x8F][/x80-/xBF]{2} # plane 16 )*$%xs'', $string)) return $string; else return iconv(''CP1252'', ''UTF-8'', $string);



No estoy seguro de si esto lograría lo mismo, pero ¿no podría simplemente usar utf8_encode() en todo el texto sin preocuparse por la detección? Si el texto ya es UTF-8, no lo dañará. Y si no lo es, se convertirá. Si ya ha pensado en hacer esto, ¿hay algún motivo por el que esto no funcione para usted?


Solo una nota: en lugar de usar la expresión regular frecuentemente recomendada (bastante compleja) del W3C , simplemente puede usar el modificador ''u'' para probar una cadena para la validez de UTF-8:

<?php if (preg_match("//u", $string)) { // $string is valid UTF-8 }


respuesta a "iconv es idempotente"

tampoco iconv - iconv no es idempotente

una gran diferencia entre utf8_encode () e iconv () es que iconv puede generar errores como este "Detectó un carácter multibyte incompleto en la cadena de entrada" incluso con

iconv (''ISO-8859-1'', ''UTF-8''. ''// IGNORE'', $ str)

en el código anterior:

$ encoding = mb_detect_encoding ($ string, "UTF-8, ISO-8859-1, WINDOWS-1252");

debes saber que mb_detect_encoding puede responder a uft-8 incluso para cadenas utf-8 no válidas (utf8 mal formado)


Con la biblioteca mbstring , tiene mb_check_encoding () .

Ejemplo de uso:

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

Cuando el rendimiento importa, esto es más rápido que la expresión regular proporcionada en la respuesta aceptada.

Una prueba rápida en mi configuración muestra (para 20,000 iteraciones):

  • expresión regular: ~ 310 ms
  • mb_check_encoding: ~ 90 ms

EDITAR

Con PHP 7.1.9 en un sistema Windows 10 reciente, la solución de mb_check_encoding() regulares supera a mb_check_encoding() para cualquier longitud de cadena (todavía 20,000 iteraciones):

  • 10 caracteres: regex => 4ms, mb_check_encoding() => 64ms
  • 10000 caracteres: regex => 125ms, mb_check_encoding() => 2.4s