Hay algunas respuestas realmente buenas e intenta responder a su pregunta aquí. No soy un maestro de codificación, pero entiendo su deseo de tener una pila UTF-8 pura hasta su base de datos. He estado usando la utf8mb4codificación de MySQL para tablas, campos y conexiones.
Mi situación se redujo a "Solo quiero que mis desinfectantes, validadores, lógica de negocios y declaraciones preparadas se ocupen de UTF-8 cuando los datos provienen de formularios HTML o enlaces de registro por correo electrónico". Entonces, de manera simple, comencé con esta idea:
- Intenta detectar la codificación:
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
- Si no se puede detectar la codificación,
throw new RuntimeException
- Si la entrada es
UTF-8, continúe.
De lo contrario, si es ISO-8859-1oASCII
a. Intento de conversión a UTF-8 (espera, no terminado)
si. Detectar la codificación del valor convertido.
C. Si la codificación informada y el valor convertido son ambos UTF-8, continúe.
re. Más,throw new RuntimeException
De mi clase abstracta Sanitizer

private function isUTF8($encoding, $value)
{
return (($encoding === 'UTF-8') && (utf8_encode(utf8_decode($value)) === $value));
}
private function utf8tify(&$value)
{
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
mb_internal_encoding('UTF-8');
mb_substitute_character(0xfffd); //REPLACEMENT CHARACTER
mb_detect_order($encodings);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if (!$stringEncoding) {
$value = null;
throw new \RuntimeException("Unable to identify character encoding in sanitizer.");
}
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = mb_convert_encoding($value, 'UTF-8', $stringEncoding);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = null;
throw new \RuntimeException("Unable to convert character encoding from ISO-8859-1, or ASCII, to UTF-8 in Sanitizer.");
}
}
return;
}
Se podría argumentar que debería separar las preocupaciones de codificación de mi Sanitizerclase abstracta y simplemente inyectar un Encoderobjeto en una instancia secundaria concreta de Sanitizer. Sin embargo, el principal problema con mi enfoque es que, sin más conocimiento, simplemente rechazo los tipos de codificación que no quiero (y confío en las funciones PHP mb_ *). Sin más estudios, no puedo saber si eso perjudica a algunas poblaciones o no (o si estoy perdiendo información importante). Entonces, necesito aprender más. Encontré este artículo.
Lo que todo programador debe saber de manera absoluta y positiva sobre las codificaciones y los conjuntos de caracteres para trabajar con texto
Además, ¿qué sucede cuando se agregan datos cifrados a mis enlaces de registro de correo electrónico (usando OpenSSLo mcrypt)? ¿Podría esto interferir con la decodificación? ¿Qué pasa con Windows-1252? ¿Qué pasa con las implicaciones de seguridad? El uso de utf8_decode()y utf8_encode()en Sanitizer::isUTF8es dudoso.
La gente ha señalado fallas en las funciones PHP mb_ *. Nunca me tomé el tiempo para investigar iconv, pero si funciona mejor que las funciones mb_ *, avíseme.