2010-12-10 12 views
17

Mam kanał pobrany z witryn osób trzecich, a czasami muszę zastosować utf8_decode, a innym razem utf8_encode, aby uzyskać pożądany widoczny wynik.Jak wykryć, czy trzeba zastosować dekodowanie UTF8 czy kodować w ciągu znaków?

Jeśli przez pomyłkę zostanie zastosowana ta sama substancja dwukrotnie lub zastosuje się niewłaściwą metodę, otrzymam coś bardziej brzydkiego, to właśnie chcę zmienić.

Jak wykryć, co należy zastosować w ciągu znaków?

UPDATE

Faktycznie treść zwraca UTF-8, ale w środku nie ma części, które nie są.

+0

Jeżeli założymy, że pasza deklaruje pewną charset ale wykorzystuje inną? –

+0

Tak, to jest przyczyna. – Pentium10

+0

proszę podać przykładowy kanał proszę – Gordon

Odpowiedz

50

Nie mogę powiedzieć, że mogę polegać na mb_detect_encoding(). Miał jakieś zakręcone fałszywe alarmy jakiś czas temu.

Najbardziej uniwersalny sposób znalazłem się dobrze w każdym przypadku było:

if (preg_match('!!u', $string)) 
{ 
    // this is utf-8 
} 
else 
{ 
    // definitely not utf-8 
} 
+2

+1 Wdrożono utf8_validate(), który używa twojego rozwiązania do konwersji ciągu na utf8, jeśli nie jest, działa jak urok! –

+4

Dziękujemy! To bardzo sprytna sztuczka ;-) Ponieważ nie miałem absolutnie żadnego pojęcia, jak to działa, zagłębiłem się w dokumentację PHP, aby znaleźć [to] (http://us2.php.net/manual/en/reference.pcre. pattern.modifiers.php): 'u (PCRE8) Ten modyfikator włącza dodatkową funkcjonalność PCRE, która jest niezgodna z Perlem. Ciągi znaków są traktowane jako UTF-8. Ten modyfikator jest dostępny z PHP 4.1.0 lub nowszego na Uniksie oraz z PHP 4.2.3 na Win32. Poprawność UTF-8 wzorca jest sprawdzana od PHP 4.3.5. ' W każdym razie, dzięki pęczku! – Edward

+2

ta kropka w wyrażeniu regularnym nie jest nawet potrzebna 'preg_match ('!! u', $ str)' działa poprawnie – rsk82

0

Kanał (myślę, że masz na myśli pewien rodzaj kanału bazującego na XML) powinien mieć atrybut w nagłówku informujący o kodowaniu. Jeśli nie, masz pecha, ponieważ nie masz niezawodnego sposobu identyfikowania kodowania.

3

Można użyć

charset może również być dostępny w HTTP Response Headers lub w samych danych Response.

Przykład:

var_dump(
    mb_detect_encoding(
     file_get_contents('http://stackoverflow.com/questions/4407854') 
    ), 
    $http_response_header 
); 

wyjściowa (codepad):

string(5) "UTF-8" 
array(9) { 
    [0]=> 
    string(15) "HTTP/1.1 200 OK" 
    [1]=> 
    string(33) "Cache-Control: public, max-age=11" 
    [2]=> 
    string(38) "Content-Type: text/html; charset=utf-8" 
    [3]=> 
    string(38) "Expires: Fri, 10 Dec 2010 10:40:07 GMT" 
    [4]=> 
    string(44) "Last-Modified: Fri, 10 Dec 2010 10:39:07 GMT" 
    [5]=> 
    string(7) "Vary: *" 
    [6]=> 
    string(35) "Date: Fri, 10 Dec 2010 10:39:55 GMT" 
    [7]=> 
    string(17) "Connection: close" 
    [8]=> 
    string(21) "Content-Length: 34119" 
} 
0

Kodowanie autotection nie jest kuloodporne ale można spróbować mb_detect_encoding(). Zobacz także mb_check_encoding().

3
function str_to_utf8 ($str) { 
    $decoded = utf8_decode($str); 
    if (mb_detect_encoding($decoded , 'UTF-8', true) === false) 
     return $str; 
    return $decoded; 
} 

var_dump(str_to_utf8("« Chrétiens d'Orient » : la RATP fait marche arrière")); 
//string '« Chrétiens d'Orient » : la RATP fait marche arrière' (length=56) 
var_dump(str_to_utf8("« Chrétiens d'Orient » : la RATP fait marche arrière")); 
//string '« Chrétiens d'Orient » : la RATP fait marche arrière' (length=56) 
Powiązane problemy