UTF-8 può memorizzare qualsiasi carattere Unicode. Se la tua codifica è qualcos'altro, incluso ISO-8859-1 o Windows-1252, UTF-8 può memorizzare ogni carattere in esso. Quindi non devi preoccuparti di perdere alcun carattere quando converti una stringa da qualsiasi altra codifica in UTF-8.
Inoltre, sia ISO-8859-1 sia Windows-1252 sono codifiche a byte singolo in cui ogni byte è valido. Non è tecnicamente possibile distinguere tra loro. Avrei scelto Windows-1252 come corrispondenza predefinita per le sequenze non UTF-8, poiché gli unici byte che decodificano in modo diverso sono l'intervallo 0x80-0x9F. Questi decodificano vari caratteri come le virgolette intelligenti e l'Euro in Windows-1252, mentre in ISO-8859-1 sono caratteri di controllo invisibili che non vengono quasi mai utilizzati. I browser Web a volte possono dire che stanno usando ISO-8859-1, ma spesso useranno davvero Windows-1252.
sarebbe questo codice verificare che una stringa è sicuro da inserire in un documento UTF-8 codificato
Si sarebbe certamente desidera impostare il parametro opzionale ‘stretta’ a TRUE per questo scopo. Ma non sono sicuro che questo copra tutte le sequenze UTF-8 non valide. La funzione non pretende di controllare esplicitamente una sequenza di byte per la validità di UTF-8. Esistono casi noti in cui mb_detect_encoding potrebbe indovinare UTF-8 in modo errato prima, anche se non so se ciò può ancora accadere in modalità rigorosa.
Se si vuole essere sicuri, fai da te utilizzando il W3-recommended regex:
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);
Grazie mille. So che gli sviluppatori commentano sempre la lentezza delle regex: quanto dovrei stare attento a usare questo in grandi loop con molto testo? Ad esempio, un ciclo che itera 200 volte e pulisce il testo di 10.000 caratteri per ogni iterazione. – Brian
Anche se non sono un fan delle espressioni regolari, in questo caso non dovrebbe essere così male. Il regex rallenta quando si hanno sequenze successive 'n'?/'* /' + 'Che possono indurre a tornare indietro alla ricerca di modi diversi di corrispondere. Questo non accadrà in questo caso. – bobince
Eccellente. Pertanto, quando si utilizza iconv come descritto sopra, se si specifica CP1252 come set di caratteri di input e la stringa è diversa da CP1252 o ISO-8859-1, restituirà una stringa sicura UTF-8, sebbene alcuni caratteri potrebbero andare persi. È corretto? – Brian