php - special - ¿Se puede usar str_replace de forma segura en una cadena codificada en UTF-8 si solo se le dan cadenas codificadas en UTF-8 válidas como argumentos?
substring php (5)
Bueno, tengo un ejemplo de contador: tengo una configuración codificada en UTF8 ".ini ''archivo que especifica la configuración de la aplicación como el nombre del remitente del correo electrónico. Dice algo así como:
email_from = Märta
y lo leí desde allí a la variable $sender
. Ahora que sustituyo el cuerpo del mensaje (UTF8 de nuevo)
saludos {remitente}
$message = str_replace("{sender}",$sender_name,$message);
El correo electrónico es absolutamente correcto en todos los aspectos, pero el remitente está 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. Lamento decir que parece que no hay manera de corregir este comportamiento.
Edición : en realidad, explode()
está involucrado en el análisis del archivo .ini, por lo que el problema puede estar en esa misma función, por lo que el str_replace()
puede ser inocente.
str_replace()
PHP fue diseñado solo para cadenas ANSI y, como tal, puede dañar las cadenas UTF-8. Sin embargo, dado que es seguro para archivos binarios, ¿funcionaría correctamente si solo se le dieran cadenas UTF-8 válidas como argumentos?
Edit: no estoy buscando una función de reemplazo, me gustaría saber si esta hipótesis es correcta.
Es correcto porque los caracteres multibyte UTF-8 son exclusivamente caracteres no ASCII (valor de más de 128 bytes) que comienzan con un byte que define cuántos bytes siguen, por lo que no puede terminar accidentalmente una parte de un carácter multibyte UTF-8 con otro.
Visualizar (abstractamente):
-
a
para un personaje ASCII -
2x
para un carácter de 2 bytes -
3xx
para un carácter de 3 bytes -
4xxx
para un carácter de 4 bytes
Si está haciendo coincidir, por ejemplo, a2x3xx
( a
byte en el rango ASCII), ya que a
< x
, y 2x
no puede ser un subconjunto de 3xx
o 4xxx
, etc., puede estar seguro de que su UTF-8 coincidirá correctamente, dado el requisito previo de que todas las cadenas sean definitivamente válidas UTF-8.
Edición: vea la respuesta de bobince para una explicación menos abstracta.
No, no puedes.
Desde la práctica, le digo que si tiene algunos símbolos multibyte como ◊ etc, y otros no son multibyte, no funcionará correctamente, porque hay símbolos que requieren de 2-4 para colocarlos, str_replace
toma bytes fijos y reemplaza ... Como resultado tenemos algo que no es ningún símbolo basura, etc.
Sí, creo que esto es correcto, al menos no pude encontrar ningún contraejemplo.
Sí. UTF-8 está diseñado deliberadamente para permitir este y otros procesos similares que no son 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
. Es posible que este byte no aparezca en ninguna otra parte de la secuencia, por lo que no puede crear una secuencia UTF-8 válida que coincida con parte de un carácter.
Este no es el caso de las codificaciones multibyte más 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 byte /x5C
podría ser el segundo byte de una secuencia de caracteres que representa otra cosa).