2010-04-16 8 views
20

PHP str_replace() fue diseñado solo para cadenas ANSI y, como tal, puede manipular cadenas UTF-8. Sin embargo, dado que es binario-seguro, ¿funcionaría correctamente si solo se le asignaran cadenas válidas UTF-8 como argumentos?¿Se puede usar str_replace de manera segura en una cadena codificada en UTF-8 si solo se le asignan cadenas codificadas como UTF-8 como argumentos?

Editar: No estoy buscando una función de reemplazo, solo me gustaría saber si esta hipótesis es correcta.

Respuesta

19

Sí. UTF-8 está diseñado deliberadamente para permitir este y otros procesos similares no compatibles con Unicode.

En UTF-8, cualquier secuencia de bytes no ASCII que represente un carácter válido siempre comienza con un byte en el rango \xC0-\xFF. Este byte puede no aparecer en ningún otro lugar de la secuencia, por lo que no puede hacer una secuencia UTF-8 válida que coincida con parte de un personaje.

Este no es el caso para las codificaciones multibyte antiguas, donde las diferentes partes de una secuencia de bytes son indistinguibles. Esto causó muchos problemas, por ejemplo, tratar de reemplazar una barra invertida ASCII en una cadena Shift-JIS (donde el byte \x5C podría ser el segundo byte de una secuencia de caracteres que representa algo más).

0

Sí, creo que esto es correcto, al menos no pude encontrar ningún contraejemplo.

5

Es correcto porque los caracteres UTF-8 multibyte son exclusivamente caracteres no ASCII (valor de 128 bytes) que comienzan con un byte que define cuántos bytes se siguen, por lo que no puede coincidir accidentalmente con una parte de un UTF- 8 caracteres multibyte con otro.

Observar (abstracta):

  • a para un carácter ASCII
  • 2x para un carácter de 2 bytes
  • 3xx para un carácter de 3 bytes
  • 4xxx para un 4-byte personaje

Si está buscando, por ejemplo, a2x3xx (a Bytes rango ASCII), ya a < x y 2x no puede ser un subconjunto de 3xx o 4xxx, etcétera, puede estar seguro de que su UTF-8 coincidirá correctamente, dado el requisito de que todas las cadenas son sin duda válida UTF-8.

Editar: Vea la respuesta de bobince para una explicación menos abstracta.

1

Bueno, hacer tienen un contraejemplo:. Tengo un UTF8 codificada ajustes de" archivo ini' especificación de la configuración appliation como el nombre del remitente de correo electrónico que dice algo así como:

email_from = Märta 

y leerlo de allí a la variable $sender.Ahora que puedo reemplazar el cuerpo del mensaje (UTF8 nuevo)

respecto {} remitente

$message = str_replace("{sender}",$sender_name,$message); 

El correo electrónico es absolutamente correcta en todos los aspectos pero el remitente es totalmente roto. Hay otros casos (como explotar()) cuando algo sale mal con una cadena UTF. Es saludable antes de la conversión, pero no después de ella. Lamento decir que parece que no hay forma de corregir este comportamiento.

Editar: En realidad, explode() está implicado en el análisis del archivo .ini por lo que el problema puede también radica en que la función misma por lo que el str_replace() bien puede ser inocente.

+0

¿Está absolutamente seguro de que su cuerpo de correo electrónico está debidamente codificado en UTF-8? – Gumbo

+0

Sí, absolutamente positivo. He tenido una experiencia extraña cuando uso el explode() antes. Un ejemplo simplificado: función ech1 ($ var) {echo $ var; } función ech2 ($ var) {$ parts = explode ("|", $ var); echo $ parts [1];} echo1 ($ var); // sin problemas // ahora obtenemos una cadena de resultados concatenados de db ("Bjorn | Weckström") y usamos la segunda función echo2 ($ concatenado); Una versión de explosión() - romperá el UTF totalmente cada vez. Y esto también es para la web, no solo para correo. EDITAR: perdón por la pérdida de formato – karvonen

+0

Puedo afirmar esto: 'str_replace' mata por completo las cadenas UTF8, y no conozco ninguna forma de evitarlo. – csvan

0

No, no puedes.
De la práctica te digo que si tienes algunos símbolos multibyte como ◊ etc, y otros no son multibyte, no funcionarán correctamente, porque hay símbolos que tardan de 2 a 4 en colocarlos, str_replace toma bytes fijos y reemplaza ... Como resultado, tenemos algo que no contiene símbolos, basura, etc.

+0

¿Puedes dar un ejemplo (cadena)? – Shi

Cuestiones relacionadas