Próbuję parsować trochę HTML przy użyciu DOMDocument, ale kiedy to robię, nagle tracę kodowanie (przynajmniej tak mi się wydaje).
$profile = "<div><p>various japanese characters</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
$divs = $dom->getElementsByTagName('div');
foreach ($divs as $div) {
echo $dom->saveHTML($div);
}
Wynikiem tego kodu jest to, że otrzymuję mnóstwo znaków, które nie są japońskie. Jeśli jednak to zrobię:
echo $profile;
wyświetla się poprawnie. Próbowałem saveHTML i saveXML i żadne z nich nie wyświetla się poprawnie. Używam PHP 5.3.
Co widzę:
ã¤ãªãã¤å·ã·ã«ã´ã«ã¦ãã¢ã¤ã«ã©ã³ãç³»ã®å®¶åºã«ã9人åå¼ã®5çªç®ã¨ãã¦çã¾ãããå½¼ãå«ãã¦4人ã俳åªã«ãªã£ããç¶è¦ªã¯æ¨æã®ã»ã¼ã«ã¹ãã³ã§ãæ¯è¦ªã¯éµä¾¿å±ã®å®¢å®¤ä¿ã ã£ããé«æ ¡æ代ã¯ãã£ãã£ã®ã¢ã«ãã¤ãã«å¤ãã¿ãæè²è³éãåããªããã«ããªãã¯ç³»ã®é«æ ¡ã¸é²å¦ã
Co należy pokazać:
イリノイ州シカゴにて、アイルランド系の家庭に、9人兄弟の5番目として生まれる。彼を含めて4人が俳優になった。父親は木材のセールスマンで、母親は郵便局の客室係だった。高校時代はキャディのアルバイトに勤しみ、教育資金を受けながらカトリック系の高校へ進学
EDYCJA: Uprościłem kod do pięciu wierszy, abyś mógł go przetestować samodzielnie.
$profile = "<div lang=ja><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
echo $dom->saveHTML();
echo $profile;
Oto zwracany HTML:
<div lang="ja"><p>イリノイ州シカゴã«ã¦ã€ã‚¢ã‚¤ãƒ«ãƒ©ãƒ³ãƒ‰ç³»ã®å®¶åºã«ã€</p></div>
<div lang="ja"><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>
php
utf-8
character-encoding
Nieco A.
źródło
źródło
Odpowiedzi:
DOMDocument::loadHTML
potraktuje twój ciąg znaków jako zgodny z ISO-8859-1, chyba że powiesz inaczej. Powoduje to niepoprawną interpretację ciągów UTF-8.Jeśli Twój ciąg nie zawiera deklaracji kodowania XML, możesz ją poprzedzić, aby traktować ciąg jako UTF-8:
Jeśli nie wiesz, czy ciąg będzie już zawierał taką deklarację, w programie SmartDOMDocument istnieje obejście, które powinno ci pomóc:
To nie jest świetne obejście, ale ponieważ nie wszystkie znaki mogą być reprezentowane w ISO-8859-1 (jak te katana), jest to najbezpieczniejsza alternatywa.
źródło
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $content);
naprawiłem to dla mnie w PHP7 (więc nadal jest to problem) - jest to naprawdę denerwujący problem, ponieważ zdefiniowałem utf8 w dokumencie HTML (z<meta charset="UTF-8" />
), ale to nie ma efektu, wydaje się, że potrzebuje części <? xml, która jest całkowicie nieintuicyjny.$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));
działa świetnie! DziękujęProblemem jest to, ze
saveHTML()
isaveXML()
, oba z nich nie działają poprawnie w systemie Unix. Nie zapisują poprawnie znaków UTF-8, gdy są używane w Uniksie, ale działają w systemie Windows.Obejście tego problemu jest bardzo proste:
Jeśli spróbujesz domyślnie, otrzymasz opisany błąd
Wszystko, co musisz zrobić, to zapisać w następujący sposób:
Ten wiersz kodu zapewni prawidłowe zapisanie znaków UTF-8. Jeśli używasz, użyj tego samego obejścia
saveXML()
.Aktualizacja
Zgodnie z sugestią „ Jack M ” w sekcji komentarzy poniżej i potwierdzoną przez „ Pamelę ” i „ Marco Aurélio Deleu ” w twoim przypadku może działać następująca odmiana:
Uwaga
Angielskie znaki nie powodują żadnego problemu, gdy używasz
saveHTML()
bez parametrów (ponieważ angielskie znaki są zapisywane jako znaki jednobajtowe w UTF-8)Problem występuje, gdy masz znaki wielobajtowe (takie jak chiński, rosyjski, arabski, hebrajski itp.)
Zalecam przeczytanie tego artykułu: http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ . Zrozumiesz, jak działa UTF-8 i dlaczego masz ten problem. Zajmie ci to około 30 minut, ale jest to czas dobrze spędzony.
źródło
$str = utf8_decode($dom->saveHTML($dom->documentElement));
utf8_decode($dom->saveHTML($dom->documentElement));
zrobiłem to idealnie dla mnie.Upewnij się, że prawdziwy plik źródłowy jest zapisany jako UTF-8 (aby się upewnić, możesz spróbować niezalecanych znaków BOM z UTF-8).
Również w przypadku HTML upewnij się, że zadeklarowałeś prawidłowe kodowanie za pomocą
meta
tagów:Jeśli jest to CMS (ponieważ otagowałeś swoje pytanie Joomla), być może będziesz musiał skonfigurować odpowiednie ustawienia dla kodowania.
źródło
<meta charset="UTF-8">
tag nie działa z DOMDocument.Możesz poprzedzić
utf-8
kodowanie linii wymuszające , tak jak to:Następnie możesz przejść do kodu, który już masz, na przykład:
źródło
Zajęło mi to trochę czasu, aby zrozumieć, ale oto moja odpowiedź.
Przed użyciem DomDocument chciałbym użyć file_get_contents do pobrania adresów URL, a następnie przetworzenia ich za pomocą funkcji łańcuchowych. Być może nie najlepszy sposób, ale szybki. Po przekonaniu się, że Dom był równie szybki, najpierw spróbowałem:
Nie udało się to spektakularnie w zachowaniu kodowania UTF-8 pomimo odpowiednich metatagów, ustawień php i wszystkich innych środków zaradczych oferowanych tutaj i gdzie indziej. Oto, co działa:
itp. Teraz wszystko jest w porządku ze światem. Mam nadzieję że to pomoże.
źródło
DomDocument('1.0', 'UTF-8')
. Ale w moim przypadku ładowany jest tylko częściowy HTML.Musisz nakarmić DOMDocument wersję swojego HTML z sensownym nagłówkiem. Podobnie jak HTML5.
być może dobrym pomysłem jest, aby utrzymać swój HTML tak ważny, jak to tylko możliwe, abyś nie wpadał w problemy, gdy zaczniesz kwerendę ... w okolicy :-) i trzymaj się z dala od
htmlentities
!!!! Jest to konieczne marnowanie zasobów w obie strony. trzymaj swój kod szalony !!!!źródło
Używam php 7.3.8 na manjaro i pracowałem z perskimi treściami. To rozwiązało mój problem:
źródło
Prace znalezione dla mnie:
źródło
?
)Użyj go, aby uzyskać poprawny wynik
Ta operacja
To zły sposób, ponieważ specjalne symbole, takie jak & lt; , & gt; mogą być w profilu $ i nie będą konwertowane dwukrotnie po mb_convert_encoding. Jest to dziura dla XSS i niepoprawnego HTML.
źródło
Jedyną rzeczą, która działała dla mnie, była zaakceptowana odpowiedź
JEDNAK
Doprowadziło to do powstania nowych problemów związanych
<?xml encoding="utf-8" ?>
z otrzymaniem dokumentu.Miałem wtedy rozwiązanie
Niektóre rozwiązania mówiły mi, że aby usunąć
xml
nagłówek, musiałem wykonaćNie działało to dla mnie jak w przypadku częściowego dokumentu (np. Dokumentu z dwoma
<p>
znacznikami), tylko jeden ze<p>
znaczników, który został zwrócony.źródło
Problem polega na tym, że dodając parametr do funkcji DOMDocument :: saveHTML (), tracisz kodowanie. W kilku przypadkach musisz uniknąć użycia parametru i użyć starej funkcji ciągu, aby znaleźć to, czego szukasz.
Myślę, że poprzednia odpowiedź działa dla ciebie, ale ponieważ to obejście nie zadziałało dla mnie, dodaję tę odpowiedź, aby pomóc ppl, który może być w moim przypadku.
źródło
Może również kodować jak poniżej .... zebrane z https://davidwalsh.name/domdocument-utf8-problem
źródło