SORU
3 Temmuz 2012, Salı


PHP DomDocument işlemek için başarısız utf-8 karakter (kalite

Web sunucusu utf-8 kodlaması ile yanıt veriyor, tüm dosyaları utf-8 kodlaması ile kaydedilmiş ve bildiğim her şeyi ayarını utf-8 kodlaması için ayarlandı.

Burada ise çıkış çalışıp çalışmadığını sınamak için hızlı bir program:

<?php
$html = <<<HTML
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Test!</title>
</head>
<body>
    <h1>☆ Hello ☆ World ☆</h1>
</body>
</html>
HTML;

$dom = new DomDocument("1.0", "utf-8");
$dom->loadHTML($html);

header("Content-Type: text/html; charset=utf-8");
echo($dom->saveHTML());

Program çıktısı:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Test!</title></head><body>
    <h1>☆ Hello ☆ World ☆</h1>
</body></html>

Gibi işler:

† Dünya A† . A† A Merhaba


Ben yanlış ne yapıyor olabilir? Daha ne kadar özel DomDocument utf-8 düzgün bir şekilde işlemek için söylemek zorunda mıyım?

CEVAP
3 Temmuz 2012, Salı


Chat, DOMDocument::loadHTML() bekler HTML bir dize söyledi.

HTML ISO-8859-1 kodlama (ISO Latin Alfabesi No: 1) gözlük başına varsayılan olarak kullanır. Uzun zamandan beri 6.1. The HTML Document Character Set bkz. Gerçekte ortak webbrowsers Windows-1252 Daha fazla varsayılan destek.

Ben PHP DOMDocument libxml dayalı olduğundan o kadar geçmişe ve HTML 4.0 için tasarlanmıştır HTMLparser getiriyor.

Güvenli ISO-8859-1 kodlanmış bir dize yükleyebilirsiniz o zaman düşünmek yanlış olmaz bence.

Eğer string UTF-8 kodlanır. Tüm karakterler HTML Entities içine 127 / h7F daha dönüp iyisin. Eğer bunu yapmak istemiyorsan eğer, o HTML-ENTITIES hedef kodlama ile mb_convert_encoding yaptığı da budur.

  • Varlıklar bu karakterleri, adlandırılmış taraf olacak. € -> €
  • Diğerleri (ondalık) sayısal onların varlığı, ☆ -> ☆ ör

Aşağıdaki ilerleme biraz geri arama işlevini kullanarak daha görünür hale getiren bir kod bir örnektir:

$html = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function($match) {
    list($utf8) = $match;
    $entity = mb_convert_encoding($utf8, 'HTML-ENTITIES', 'UTF-8');
    printf("%s -> %s\n", $utf8, $entity);
    return $entity;
}, $html);

Senin dize için bu örnek çıktısı:

☆ -> ☆
☆ -> ☆
☆ -> ☆

Her neyse, o sadece daha derin bir dize içine bakarak. Ya loadHTML ile başa çıkabilirim bir kodlama haline çevirdim. HTML Varlıkları içine US-ASCII dışında tüm dönüştürerek yapılabilir:

$us_ascii = mb_convert_encoding($utf_8, 'HTML-ENTITIES', 'UTF-8');

Giriş aslında UTF-8 olarak kodlanmış olmasına dikkat edin. Eğer bile kodlamalar (bazı girişi ile gerçekleşebilir karma) varsa mb_convert_encoding tek başına bir dize kodlama işleyebilir. Ben zaten şu an için daha fazla ayrıntı bırakıyorum bu yüzden özellikle düzenli ifadeler yardımıyla dize değiştirme yapmak için nasıl yukarıda belirtilen,.

Diğer alternatifipucukodlama. Bu belge değiştirerek ve ekleyerek durumda yapılabilir

<meta http-equiv="content-type" content="text/html; charset=utf-8">

bir karakter kümesi belirtme İçerik Tipi. Bu da iyi bir Web sunucusu (örneğin örnekte olduğu gibi bir dize içinde diskte kayıtlı) bulunmayan HTML dizeleri için bir uygulamadır. Web sunucusu normalde set tepki Başlığı bu.

Eğer yanlış uyarılar umurunda olmadığını, sadece dize önünde ekleyebilirsiniz:

$dom = new DomDocument();
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$html);

HTML 2.0 görüşler başına, tek bir belge <head> bölümünde görünür, bu öğeleri otomatik olarak orada yer alacak. Bu, burada olanları da. Çıktı (pretty-print):

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta charset="utf-8">
    <title>Test!</title>
  </head>
  <body>
    <h1>☆ Hello ☆ World ☆</h1>    
  </body>
</html>

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • dcigs

    dcigs

    9 EYLÜL 2006
  • Mr. H

    Mr. H

    1 Temmuz 2012
  • Tek Syndicate

    Tek Syndicat

    23 Temmuz 2008