2012-03-09 29 views
8

sto avendo alcuni problemi utilizzando il seguente codice all'input dell'utente:Rimozione/caratteri multibyte incomplete non validi

htmlentities($string, ENT_COMPAT, 'UTF-8'); 

Quando viene rilevato un carattere multibyte non valida PHP getta un avviso:

PHP Warning : htmlentities(): sequenza multibyte non valido in argomento nella /path/to/file.php on line 123

il mio primo pensiero è stato quello di sopprimere l'errore, ma questo è sl ow e poveri pratica: http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html

mio secondo pensiero è stato quello di usare il flag ENT_IGNORE, ma anche manuale PHP suggerisce di non usare questo:

scartano sequenze unitari codice non validi invece di restituire una stringa vuota . L'utilizzo di questo flag è sconsigliato in quanto »may have security implications.

Un po 'di ulteriore motivo mi ha portato al seguente pezzo di codice:

// detect encoding 
$encoding = mb_detect_encoding($query); 
if($encoding != 'UTF-8') { 
    $query = mb_convert_encoding($query, 'UTF-8', $encoding); 
} else { 
    // strip out invalid utf8 sequences 
    $query = iconv('UTF-8', 'UTF-8//IGNORE', $query); 
} 

Purtroppo iconv anche genera E_NOTICE quando si rimuove/ignora i caratteri non validi:

Se si aggiunge la stringa // TRANSLIT a out_charset la traslitterazione è attivata. Ciò significa che quando un personaggio non può essere rappresentato nel set di caratteri di destinazione, può essere approssimato attraverso uno o più personaggi dall'aspetto simile. Se si aggiunge la stringa // IGNORE, i caratteri che non possono essere rappresentati nel set di caratteri di destinazione vengono eliminati automaticamente. Altrimenti, str viene tagliato dal primo carattere illegale e viene generato un E_NOTICE.

Quindi sono praticamente senza opzioni qui. Preferirei usare una libreria collaudata per gestire questo tipo di cose piuttosto che tentare con alcune delle soluzioni basate su espressioni regolari che ho visto fluttuare.

In modo che mi porta alla mia domanda finale: Come posso rimuovere i caratteri multibyte non validi, in modo efficiente, in modo sicuro, senza comunicazioni/avvisi/errori?

+4

Se non si desidera utilizzare 'ENT_IGNORE', non si desidera utilizzare' // IGNORE' neanche. Fanno la stessa cosa e hanno le stesse implicazioni per la sicurezza. Questo può essere un punto ovvio e un approccio pigro ma ... * non dovresti nascondere questi errori nella produzione comunque *? Il punto di queste situazioni che lancia un 'E_NOTICE' è che l'amministratore del server è a conoscenza di potenziali problemi con il server - i caratteri non validi sarebbero presenti solo se qualcuno li inviava maliziosamente o alcuni dati erano corrotti, entrambi richiedono l'attenzione dell'amministratore. In ogni caso è un caso limite estremo. – DaveRandom

+0

È * rifiutando * codificato in modo non valido UTF-8 un'opzione? Se è rotto, probabilmente non dovresti usarlo per cominciare. – deceze

+0

Dave, sì gli errori sono nascosti, ma li stiamo osservando nei log. È un caso limite in cui qualcuno inviava parametri negativi per un motivo o per l'altro. – Dean

risposta

2

Come è possibile rimuovere caratteri multibyte non validi, in modo efficiente, sicuro, senza avvisi/avvisi/errori?

Beh, come hai già delineato nella tua domanda sul proprio (or at least linked), eliminando la sequenza di byte non valida (s) non è un'opzione.

Invece dovrebbe essere probabilmente sostituito con il carattere di sostituzione U + FFFD. A partire da PHP 5.4.0 è possibile utilizzare il flag ENT_SUBSTITUTE per htmlentities. Probabilmente è più sicuro se non vuoi rifiutare la stringa.

iconv ti darà sempre un avviso nelle versioni di PHP recenti se non cancella nemmeno l'intera stringa. Quindi non sembra una buona alternativa per te.

4

iconv('UTF-8', "ISO-8859-1//IGNORE", $string);

ha funzionato molto bene per me. Non sembra generare alcun preavviso.

+1

+1 Stavo usando: 'iconv (' UTF-8 ',' ASCII // TRANSLIT ', $ var)' e IGNORE invece di TRANSLIT ha corretto l'avviso 'caratteri non validi' e rimosso le icone emoji indesiderate dal stringa. –

Problemi correlati