2011-07-17 12 views
18
funkcja

iconv czasami daje mi błąd:Jak wykryć nieprawidłowy ciąg utf-8 w PHP?

Notice: 
iconv() [function.iconv]: 
Detected an incomplete multibyte character in input string in [...] 

Czy istnieje sposób, aby wykryć, że istnieją nielegalne znaków w UTF-8 ciąg przed wprowadzeniem danych do inconv?

+0

Tymczasem znalazłem to: http: // stackoverflow.com/questions/4407854/how-to-detect-if-have-to-apply-utf8-decode-or-encode-on-a-string – rsk82

Odpowiedz

46

Po pierwsze, należy pamiętać, że nie można wykryć, czy tekst należy do określonego niepożądanego kodowania. Możesz tylko sprawdzić, czy łańcuch jest poprawny w danym kodowaniu.

Możesz skorzystać z sprawdzania poprawności UTF-8, które jest dostępne w preg_match[PHP Manual] od wersji 4.3.5. powróci 0 (bez dodatkowych informacji), jeżeli nieprawidłowy ciąg jest podana:

$isUTF8 = preg_match('//u', $string); 

Inną możliwością jest mb_check_encoding[PHP Manual]:

$validUTF8 = mb_check_encoding($string, 'UTF-8'); 

Inną funkcją można użyć jest mb_detect_encoding[PHP Manual]:

$validUTF8 = ! (false === mb_detect_encoding($string, 'UTF-8', true)); 

Ważne jest ustawienie parametru strict na true.

Dodatkowo, iconv[PHP Manual] pozwala na zmianę/odrzucenie nieprawidłowych sekwencji w locie. (Jednakże, jeśli iconv spotkania takiej sekwencji, generuje powiadomienie; takie zachowanie nie może być zmieniony.)

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

Można użyć @ i sprawdzić długość łańcucha powrotnej:

strlen($string) === strlen(@iconv('UTF-8', 'UTF-8//IGNORE', $string)); 

Sprawdź przykłady na stronie podręcznika iconv.

Nie udostępniono kodu źródłowego, z którego pochodzi powiadomienie. Powinieneś go dodać, jeśli chcesz bardziej konkretnej sugestii.

+0

nie mylisz się, ale wydaje się, że 'preg_match ('!.! U', $ str)' robi trik - w milczeniu sprawdza, czy str jest utf-8, zanim spróbuje coś znaleźć. - ta kropka w wyrażeniu regularnym nie jest nawet potrzebna – rsk82

+0

@ user393087: Dokonałem niewielkiej edycji, aby metoda 'preg_match' działała poprawnie również na pustych ciągach. – hakre

+2

@Alan: Dzięki za miłą edycję. – hakre

0

Specyfikacja znaków, które są nieprawidłowe w UTF-8, jest całkiem jasna. Prawdopodobnie chcesz je rozebrać, zanim spróbujesz je przeanalizować. Nie powinno ich tam być, więc gdybyś mógł uniknąć tego nawet przed wygenerowaniem XML, który byłby jeszcze lepszy.

Zobacz tutaj odniesienie:

http://www.w3.org/TR/xml/#charsets

Nie jest to pełna lista, wiele parser również zabronić niektórych znaków niskich numerach kontrolnych, ale nie mogę znaleźć pełną listę już teraz.

Jednak może iconv mieć wbudowane wsparcie dla tego:

http://www.zeitoun.net/articles/clear-invalid-utf8/start

0

Można spróbować użyć mb_detect_encoding do wykrycia, jeśli masz inny zestaw znaków (niż UTF-8), a następnie przekonwertować do mb_convert_encoding UTF-8, jeśli jest wymagany. Bardziej prawdopodobne jest, że ludzie podają właściwą treść w innym zestawie znaków niż w przypadku podania nieprawidłowego kodu UTF-8.

+0

Należy pamiętać, że prawidłowe ciągi ASCII są również poprawnymi łańcuchami UTF8. Oznacza to, że mb_detect_encoding zwróci "ASCII" dla dowolnego łańcucha, który jest poprawnym ciągiem UTF8 i który nie zawiera żadnych znaków Unicode – GordonM

0

umieścić @ przed iconv() w celu powstrzymania powiadomienia o powyższym oraz // IGNORUJ po UTF-8 w źródłowym kodowania id ignorować nieprawidłowe znaki:

@iconv('UTF-8//IGNORE', $destinationEncoding, $yourString); 
+0

Wiem, jak to zignorować, nie wiem jak to wykryć, nie chcę przekazać tego po cichu w dół mojego kodu. – rsk82

+0

co chcesz zrobić po wykryciu błędu? – nobody

+0

Przy okazji, rozwiązanie 'preg_match()' w drugim pytaniu jest bardzo interesujące. – nobody

Powiązane problemy