Hallo,
DOMDocument hat eine Macke, die man per Schmuddellösung umschiffen kann:
Bereits beim Laden des Dokumentes muss die passende Kodierung genau mit diesem <meta>-Tag (dem antiquierten aus HTML4.1) als erster Tag dieser Art angebeben werden. Das geht schmuddelig, in dem man ihn einfach "deplaced" vor das Dokument schaltet.
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . $page);
Das gibt zwar einen Parsing-Error, aber nun stimmt die Ausgabe. tztz.
Ich teste jetzt mal, ob man diese Zeile nicht an der passenden Stelle ins Dokument stanzen kann. Da aber die SROnline-Seite ohnehin ca. 40 Parsing-Fehler produziert, ist das eigentlich auch egal.
Wenn man ihn an eine passende Stelle verfrachten will (also direkt hinter dem <head> Opener-Tag), dann muss man entweder sehr viel Aufwand treiben, oder aber sich an dieser Stelle auf RegEx verlassen, also den <head ???>-Tag suchen und ersetzen durch "<head ???><meta ...>".
Mit Aufwand habe ich es auch durchgeführt. Die Vorgehensweise sieht dann folgendermaßen aus:
- Meta-Tag als Musterdatei ablegen. Das ist einfacher, als die Node generisch zu basteln
- Meta Muster in ein eigenes Dokument laden und die <meta>-Node suchen
$metanode = $metadom->getElementsByTagName('meta')->item(0);
## oder wenn man ihr sinnvollerweise eine ID verpasst hat:
$metanode = $metadom->getElementByID('meta_utf8');
-
prüfen, ob $metanode wirklich geladen ist, also ungleich NULL!
-
Originaldokument laden
-
Meta-Node importierern
-
importierte Meta-Node hinter dem <head>-Element plazieren
$newMeta = $dom->importNode($metanode);
$dom->getElementsByTagName('head')->item(0)->insertBefore($newMeta, $dom->getElementsByTagName('head')->item(0)->firstChild);
- Dokument mit $dom->saveHTML($var) wegschreiben in eine Variable
- Dokument erneut einlesen mit $dom->loadHTML($var);
die alte Instanz kann man dann getrost überschreiben damit.
Leider wird nur so das Dokument neu geparst, was (ich habe es ausprobiert) notwendig ist, damit sich die neue <meta>-Angabe für die Kodierung auswirkt.
ganz schon schmuddelig
Es erscheint mir daher legitim, an dieser Stelle eine RegEx-Lösung zu wählen für das Auffinden des <head ???>-Opener-Tags, oder sich in diesem Spezialfall einfach darauf zu verlassen, dass dort nur "<head>" steht. Das kann man dann einfach mit str_replace() ersetzen.
$meta = '<meta http-equiv="content-type" content="text/html; charset=utf-8">' ."\r\n";
if (strpos($page, '<head>') !== false)
{
$page = str_replace('<head>', "<head>\r\n$meta", $page);
$meta = '';
}
Grüße
TS