Odczytywanie wielu tekstów z różnych kanałów RSS i wstawianie ich do mojej bazy danych.
Oczywiście istnieje kilka różnych kodowań znaków używanych w kanałach, np. UTF-8 i ISO 8859-1.
Niestety czasami występują problemy z kodowaniem tekstów. Przykład:
„Ss” w „Fußball” powinien wyglądać następująco w mojej bazie danych: „Ÿ”. Jeśli jest to „Ÿ”, jest wyświetlane poprawnie.
Czasami „ß” w „Fußball” wygląda następująco w mojej bazie danych: „ߟ”. Oczywiście jest to wyświetlane nieprawidłowo.
W innych przypadkach „ß” jest zapisywane jako „ß” - więc bez żadnych zmian. Następnie jest wyświetlany niepoprawnie.
Co mogę zrobić, aby uniknąć przypadków 2 i 3?
Jak mogę ustawić to samo kodowanie, najlepiej UTF-8? Kiedy muszę użyć utf8_encode()
, kiedy muszę użyć utf8_decode()
(jasne jest, jaki jest efekt, ale kiedy muszę użyć funkcji?) I kiedy nie mogę nic zrobić z danymi wejściowymi?
Jak sprawić, by wszystko było tak samo kodujące? Być może z funkcją mb_detect_encoding()
? Czy mogę napisać dla tego funkcję? Więc moje problemy to:
- Jak dowiedzieć się, jakiego kodowania używa tekst?
- Jak przekonwertować go na UTF-8 - bez względu na stare kodowanie?
Czy taka funkcja działałaby?
function correct_encoding($text) {
$current_encoding = mb_detect_encoding($text, 'auto');
$text = iconv($current_encoding, 'UTF-8', $text);
return $text;
}
Testowałem to, ale to nie działa. Co jest z tym nie tak?
źródło
Odpowiedzi:
Jeśli zastosujesz
utf8_encode()
do już napisanego UTF-8, zwróci zniekształcone wyjście UTF-8.Stworzyłem funkcję, która rozwiązuje wszystkie te problemy. To się nazywa
Encoding::toUTF8()
.Nie musisz wiedzieć, jakie jest kodowanie swoich ciągów. Może to być Latin1 ( ISO 8859-1) , Windows-1252 lub UTF-8, lub ciąg może zawierać ich kombinację.
Encoding::toUTF8()
przekonwertuje wszystko na UTF-8.Zrobiłem to, ponieważ usługa przekazała mi dane zepsute, mieszając UTF-8 i Latin1 w tym samym ciągu.
Stosowanie:
Pobieranie:
https://github.com/neitanod/forceutf8
Dołączyłem inną funkcję,
Encoding::fixUFT8()
która naprawi każdy ciąg UTF-8, który wygląda na zniekształcony.Stosowanie:
Przykłady:
wyświetli:
Przekształciłem funkcję (
forceUTF8
) w rodzinę funkcji statycznych w klasie o nazwieEncoding
. Nowa funkcja toEncoding::toUTF8()
.źródło
Najpierw musisz wykryć, jakie kodowanie zostało użyte. Podczas analizowania źródeł danych RSS (prawdopodobnie przez HTTP) należy odczytać kodowanie z
charset
parametruContent-Type
pola nagłówka HTTP . Jeśli nie jest obecny, przeczytaj kodowanie zencoding
atrybutu instrukcji przetwarzania XML . Jeśli tego również brakuje, użyj UTF-8 zgodnie ze specyfikacją .Edytuj Oto, co prawdopodobnie zrobiłbym:
Chciałbym użyć cURL do wysyłania i pobierania odpowiedź. Pozwala to ustawić określone pola nagłówka i pobrać również nagłówek odpowiedzi. Po pobraniu odpowiedzi musisz przeanalizować odpowiedź HTTP i podzielić ją na nagłówek i treść. Nagłówek powinien następnie zawierać
Content-Type
pole nagłówka zawierające typ MIME i (mam nadzieję)charset
parametr również z kodowaniem / zestawem znaków. Jeśli nie, przeanalizujemy XML PI pod kątem obecnościencoding
atrybutu i stamtąd uzyskamy kodowanie. Jeśli tego również brakuje, specyfikacje XML określają użycie UTF-8 jako kodowania.źródło
charset=
iencoding=
nie tylko na odpowiednich pozycjach. Po trzecie, nie sprawdzasz, czy zadeklarowane kodowanie jest akceptowane.Wykrywanie kodowania jest trudne.
mb_detect_encoding
działa na zasadzie zgadywania na podstawie liczby zdanych kandydatów. W niektórych kodowaniach niektóre sekwencje bajtów są niepoprawne, dlatego można rozróżnić różnych kandydatów. Niestety istnieje wiele kodowań, w których te same bajty są poprawne (ale różne). W takich przypadkach nie ma możliwości ustalenia kodowania; Możesz zaimplementować własną logikę, aby zgadywać w takich przypadkach. Na przykład dane pochodzące z japońskiej witryny mogą mieć kodowanie japońskie.Tak długo, jak masz do czynienia tylko z językami Europy Zachodniej, trzy główne kodowania do rozważenia to
utf-8
:iso-8859-1
icp-1252
. Ponieważ są to ustawienia domyślne dla wielu platform, najprawdopodobniej zostaną również błędnie zgłoszone. Na przykład. jeśli ludzie używają różnych kodowań, prawdopodobnie będą szczerzy, ponieważ ich oprogramowanie bardzo często się psuje. Dlatego dobrą strategią jest zaufanie do dostawcy, chyba że kodowanie zostanie zgłoszone jako jedno z tych trzech. Nadal powinieneś dokładnie sprawdzić, czy rzeczywiście jest poprawne, używającmb_check_encoding
(pamiętaj, że poprawne to nie to samo, co bycie - te same dane wejściowe mogą być poprawne dla wielu kodowań). Jeśli jest to jeden z nich, możesz użyćmb_detect_encoding
rozróżniać między nimi. Na szczęście jest to dość deterministyczne; Musisz tylko użyć właściwej sekwencji wykrywania, która jestUTF-8,ISO-8859-1,WINDOWS-1252
.Po wykryciu kodowania musisz przekonwertować je na wewnętrzną reprezentację (
UTF-8
jest to jedyny rozsądny wybór). Funkcjautf8_encode
przekształcaISO-8859-1
się wUTF-8
, więc może być używana tylko dla tego określonego typu danych wejściowych. W przypadku innych kodowań użyjmb_convert_encoding
.źródło
Naprawdę dobry sposób, aby wdrożyć
isUTF8
-function można znaleźć na php.net :źródło
mb_check_encoding($string, 'UTF-8')
Ten ściąg zawiera listę typowych ostrzeżeń związanych z obsługą UTF-8 w PHP: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
Pomocna może być również funkcja wykrywająca znaki wielobajtowe w ciągu znaków ( źródło ):
źródło
Trochę do góry. Powiedziałeś, że „ß” powinno być wyświetlane w bazie danych jako „Ÿ”.
Jest tak prawdopodobnie dlatego, że używasz bazy danych z kodowaniem znaków Latin-1 lub być może twoje połączenie PHP-MySQL jest ustawione nieprawidłowo, to znaczy, P uważa, że MySQL jest ustawiony na używanie UTF-8, więc wysyła dane jako UTF-8 , ale Twój MySQL wierzy, że PHP wysyła dane zakodowane jako ISO 8859-1, więc może ponownie spróbować zakodować przesłane dane jako UTF-8, powodując tego rodzaju problemy.
Spójrz na mysql_set_charset . To może ci pomóc.
źródło
Twoje kodowanie wygląda jak zakodowane dwukrotnie w UTF-8 ; to znaczy, z innego kodowania, do UTF-8 i ponownie do UTF-8. Tak jakbyś miał ISO 8859-1, przekonwertowany z ISO 8859-1 na UTF-8 i traktował nowy ciąg jako ISO 8859-1 w celu kolejnej konwersji na UTF-8.
Oto pseudokod tego, co zrobiłeś:
Powinieneś spróbować:
mb_detect_encoding()
lub cokolwiek chcesz użyćZakłada się, że w „środkowej” konwersji użyłeś ISO 8859-1. Jeśli korzystasz z systemu Windows-1252, przekonwertuj go na Windows-1252 (latin1). Oryginalne kodowanie źródłowe nie jest ważne; ten, którego użyłeś w wadliwym, drugim nawróceniu jest.
Zgaduję, co się stało; niewiele można zrobić, aby uzyskać cztery bajty zamiast jednego rozszerzonego bajtu ASCII.
Język niemiecki używa również ISO 8859-2 i Windows-1250 (Latin-2).
źródło
Interesującą rzeczą
mb_detect_encoding
imb_convert_encoding
to, że kolejność kodowań proponujesz ma znaczenia:Możesz więc użyć określonej kolejności przy określaniu oczekiwanego kodowania. Należy jednak pamiętać, że nie jest to niezawodne.
źródło
if ($input_is_not_UTF8) $input_is_windows1252 = true;
. Zobacz także: html.spec.whatwg.org/multipage/…Musisz przetestować zestaw znaków na wejściu, ponieważ odpowiedzi mogą pochodzić z różnych kodowań.
Wymuszam przesłanie całej zawartości do UTF-8, wykonując wykrywanie i tłumaczenie przy użyciu następującej funkcji:
Ta procedura zamieni wszystkie zmienne PHP pochodzące ze zdalnego hosta w UTF-8.
Lub zignoruj wartość, jeśli kodowania nie można wykryć ani przekonwertować.
Możesz dostosować go do swoich potrzeb.
Po prostu wywołaj go przed użyciem zmiennych.
źródło
Opracowanie kodowania znaków w kanałach RSS wydaje się skomplikowane . Nawet normalne strony internetowe często pomijają lub kłamią na temat ich kodowania.
Możesz więc spróbować użyć prawidłowego sposobu wykrycia kodowania, a następnie wrócić do jakiejś formy automatycznego wykrywania (zgadywania).
źródło
charset
/encoding
deklaracja, jeśli: opisz kodowanie, w którym dane są zakodowane.Wiem, że to starsze pytanie, ale wydaje mi się, że użyteczna odpowiedź nigdy nie boli. Miałem problemy z kodowaniem między aplikacją komputerową, SQLite i zmiennymi GET / POST. Niektóre będą w UTF-8, inne w ASCII i zasadniczo wszystko popieprzy się, gdy w grę wejdą zagraniczne postacie.
Oto moje rozwiązanie. Przeszukuje GET / POST / REQUEST (pominąłem pliki cookie, ale możesz je dodać w razie potrzeby) przy każdym ładowaniu strony przed przetwarzaniem. Działa dobrze w nagłówku. PHP wyrzuca ostrzeżenia, jeśli nie może automatycznie wykryć kodowania źródłowego, więc ostrzeżenia te są pomijane za pomocą @.
źródło
Od wieków szukałem rozwiązań dla kodowania , a ta strona jest prawdopodobnie końcem wielu lat poszukiwań! Przetestowałem niektóre z podanych przez ciebie sugestii i oto moje notatki:
To jest mój ciąg testowy:
Wykonuję INSERT, aby zapisać ten ciąg w bazie danych w polu ustawionym jako
utf8_general_ci
Zestaw znaków mojej strony to UTF-8.
Jeśli wykonam INSERT właśnie w ten sposób, w mojej bazie danych prawdopodobnie mam postacie pochodzące z Marsa ...
Muszę więc przekonwertować je na jakiś „zdrowy” UTF-8. próbowałem
utf8_encode()
, ale znaki kosmitów atakowały moją bazę danych ...Próbowałem więc użyć funkcji
forceUTF8
zamieszczonej pod numerem 8, ale w bazie danych zapisany ciąg wygląda następująco:Więc zbierając więcej informacji na tej stronie i łącząc je z innymi informacjami na innych stronach, rozwiązałem problem z tym rozwiązaniem:
Teraz w mojej bazie danych mam ciąg z poprawnym kodowaniem.
UWAGA: działa tylko uwaga do załatwienia
mysql_client_encoding
! Musisz być podłączony do bazy danych, ponieważ ta funkcja chce mieć identyfikator zasobu jako parametr.Ale cóż, po prostu wykonuję to ponowne kodowanie przed moim INSERT, więc dla mnie to nie jest problem.
źródło
UTF-8
kodowania klienta dla mysql? Nie potrzebowałbym ręcznej konwersji w ten sposóbTo proste: kiedy dostajesz coś, co nie jest UTF-8, musisz zakodować to w UTF-8.
Tak więc, gdy pobierasz określony plik danych, który jest ISO 8859-1, przeanalizuj go
utf8_encode
.Jeśli jednak pobierasz kanał UTF-8, nie musisz nic robić.
źródło
php.net/
mb_detect_encoding
lub
Naprawdę nie wiem, jakie są wyniki, ale sugeruję, abyś wziął kilka swoich kanałów z innym kodowaniem i spróbował, czy
mb_detect_encoding
działa, czy nie.auto update jest skrótem od „ASCII, JIS, UTF-8, EUC-JP, SJIS”. zwraca wykryty zestaw znaków, którego można użyć do konwersji ciągu znaków na utf-8 za pomocą iconv .
nie przetestowałem tego, więc nie ma gwarancji. i może jest prostszy sposób.
źródło
@harpax, który pracował dla mnie. W moim przypadku jest to wystarczająco dobre:
źródło
Po uporządkowaniu skryptów php nie zapomnij powiedzieć mysql, jaki zestaw znaków przekazujesz i chciałbyś go odzyskać.
Przykład: ustaw zestaw znaków utf8
Przekazywanie danych utf8 do tabeli latin1 w sesji I / O latin1 daje te paskudne ptasie odchody. Widzę to co drugi dzień w sklepach z oscommerce. W czwartej i czwartej może się to wydawać właściwe. Ale phpmyadmin pokaże prawdę. Mówiąc mysqlowi, jaki przekazany zestaw znaków obsłuży dla ciebie konwersję danych mysql.
Jak odzyskać istniejące zaszyfrowane dane mysql to kolejny wątek do omówienia. :)
źródło
Ta wersja jest dla języka niemieckiego, ale możesz modyfikować $ CHARSETS i $ TESTCHARS
źródło
Pobierz kodowanie z nagłówków i przekonwertuj je na utf-8.
źródło
Ÿ
jest Mojibake dlaß
. W twojej bazie danych możesz mieć hexNależy nie używać żadnych kodowanie / dekodowanie funkcje w PHP; zamiast tego należy poprawnie skonfigurować bazę danych i połączenie z nią.
Jeśli dotyczy MySQL, zobacz: Problemy ze znakami utf8; to, co widzę, nie jest tym, co zapisałem
źródło
Znajduję rozwiązanie tutaj http://deer.org.ua/2009/10/06/1/
Myślę, że @ to zła decyzja i dokonaj pewnych zmian w rozwiązaniu z deer.org.ua;
źródło
Najczęściej głosowana odpowiedź nie działa. Oto moje i mam nadzieję, że to pomoże.
źródło
Podczas próby obsługi wielu języków, takich jak japoński i koreański, możesz mieć kłopoty. mb_convert_encoding z parametrem „auto” nie działa dobrze. Ustawienie mb_detect_order („ASCII, UTF-8, JIS, EUC-JP, SJIS, EUC-KR, UHC”) nie pomaga, ponieważ nieprawidłowo wykryje EUC- *.
Doszedłem do wniosku, że dopóki łańcuchy wejściowe pochodzą z HTML, powinien używać „charset” w elemencie meta. Używam prostego parsera DOM HTML, ponieważ obsługuje on nieprawidłowy HTML.
Poniższy fragment wyodrębnia element tytułowy ze strony internetowej. Jeśli chcesz przekonwertować całą stronę, możesz usunąć niektóre wiersze.
źródło
Miałem ten sam problem z phpQuery ( ISO-8859-1 zamiast UTF-8 ) i ten hack pomógł mi:
mb_internal_encoding('UTF-8')
,phpQuery::newDocumentHTML($html, 'utf-8')
,mbstring.internal_encoding
I inne manipulacje nie miała żadnego wpływu.źródło
Spróbuj bez „auto”
To jest:
zamiast:
Więcej informacji można znaleźć tutaj: mb_detect_encoding
źródło