PHP Umlaute löschen XML-Datei (DOMDocument())

nintendoluk

Commander
Registriert
Mai 2014
Beiträge
2.129
Hallo CB-Experten,

ich habe einem meiner Spiele eine Highscore-Funktion beigefügt. Dabei bekommt eine PHP-Seite Spielername und Punktzahl übermittelt, überprüft diese dann, ob es ein neuer Highscore ist und ändert dann eine XML-Datei in der die Daten gespeichert sind.
Der Quelltext sieht so aus:
PHP:
<?php

if(isset($_GET['score']) && isset($_GET['name']))
{
	$news = $_GET['score'];
	$newn = $_GET['name'];
}

$doc = new DOMDocument(); 
$doc->load( 'highscores.xml' ); 
   
$highscores = $doc->getElementsByTagName( "highscore" ); 
foreach( $highscores as $highscore ) 
{ 
  $names = $highscore->getElementsByTagName( "name" ); 
  $name = $names->item(0)->nodeValue; 

  $scores = $highscore->getElementsByTagName( "score" ); 
  $score = $scores->item(0)->nodeValue; 

  echo "<b>$name - $score \n</b><br>"; 
  
  	if($news > $score)
	{
	$scores->item(0)->nodeValue = $news;
	$names->item(0)->nodeValue = $newn;
	
	echo "new hs<br>";
	
	$news = $score;
	$newn = $name;
	
	$doc->save('highscores.xml');
	}
    } 
?>

Das Problem ist Folgendes:
Enthält nun der eingegebene Spielername Umlaute, bekommt die PHP seite zB. .../?name=Äöü&score=100 und statt dass ein Highscore unter diesem Namen gespeichert wird, ist anschließend das komplette XML-Dokument vollkommen leer!

In erster Linie würde ich nun gerne wissen warum das so ist? Eine mögliche Lösung wäre, die Umlaute zu Codieren (zB. &auml ), wobei das auch nicht Ideal wäre weil nicht alle möglichkeiten abgedeckt werden können. Sonst kommt auf einmal irgendsoein Hanswurst, der ein paar Kryptische Zeichen gefunden hat und schon ist der komplette Highscore gelöscht!

Ich suche also nach einer anderen Lösung, ich will den Spielern aber trotzdem auch die möglichkeit geben Umlaute eingeben zu können.
Wenn sich also einer mit DOMDocument auskennt soll er mir bitte helfen :-)

Gruß
Lukas
 
Wenn in UTF-8 gearbeitet wird dürfte sowas nicht passieren.
Ich arbeite aktuell viel mit XSLT (XML + HTML) und habe keine Probleme mit Umlauten in den XML Files.

Code:
<?xml version="1.0" encoding="utf-8"?>
 
Hi,

du nimmst einfach die Werte ohne vorherige Prüfung und ohne Escaping - das ist absolut bad practice! Prüfe Eingaben von außen IMMER ab bevor du etwas damit machst.

In deinem Fall dürfte es mit relativ einfachem UTF8 Encoding getan sein - zumindest das "Umlauteproblem"...

VG,
Mad
 
1.) was Madman sagte
2.) htmlentities sollte auch bei XML wunderbar funktionieren

UTF-8 ist zwar eine gute und richtige Idee, aber reicht noch nicht. Sonst nennt sich ein Spieler mal Tod & Teufel... Blizzard hatten das Problem mal im WoW-Forum. Da gabs ne Gilde mit nem &. Jedes Mal, wenn ein Spieler dieser Gilde was gepostet hat, hats danach das Forum zur Hölle geschickt. Firefox quittierte direkt mit ner Fehlermeldung, Chrome renderte bis zum & und hörte dann auf. Nur der IE dachte sich: Ey, ich mach so viele Fehler, da kann ich den auch noch machen... und zeigte den Rest an.
Steuerzeichen müssen immer in Entities umgewandelt werden.

Viel interessanter ist die Frage: Warum wird hier XML als Speicherformat verwendet? Wäre ne kleine SQLite-Datenbank nicht einfacher?
 
[ChAoZ] schrieb:
Wenn in UTF-8 gearbeitet wird dürfte sowas nicht passieren.
Code:
<?xml version="1.0" encoding="utf-8"?>

Ich arbeite mit iso-8859-1, weil bei utf-8 aus irgendeinem Grund die Auslese mit DOMDocument nicht Funktioniert :-/
Code:
<?xml version="1.0" encoding="iso-8859-1"?>

Madman1209 schrieb:
du nimmst einfach die Werte ohne vorherige Prüfung und ohne Escaping - das ist absolut bad practice! Prüfe Eingaben von außen IMMER ab bevor du etwas damit machst.

Ich weiß, aber wenn etwas nicht über $_GET übertragen werden kann, dann wird einfach kein Highscore gespeichert. Und damit war ich zufrieden ^^ . Trotzdem werde ich jetzt auch mal über eine Codierung von Java aus nachdenken.

Danke für eure Vorschläge, aber ich brauche mehr!
 
Hi,

wie du es überträgst spielt keine Rolle! Du kannst nicht einfach einen GET Wert nehmen und den ungeprüft irgendwo verarbeiten!

Ich arbeite mit iso-8859-1, weil bei utf-8 aus irgendeinem Grund die Auslese mit DOMDocument nicht Funktioniert

Den solltest du ausfindig machen und beheben.

VG,
Mad
 
nintendoluk schrieb:
Ich arbeite mit iso-8859-1, weil bei utf-8 aus irgendeinem Grund die Auslese mit DOMDocument nicht Funktioniert
Es funktioniert nicht, weil du irgendwo totale Suppe geschrieben hast und du dann in UTF-8 auf die Nase fliegst. Ich verweise mal auf die PHP-Dokumentation:
The DOM extension uses UTF-8 encoding. Use utf8_encode() and utf8_decode() to work with texts in ISO-8859-1 encoding or Iconv for other encodings.

Ich weiß, aber wenn etwas nicht über $_GET übertragen werden kann, dann wird einfach kein Highscore gespeichert. Und damit war ich zufrieden ^^ . Trotzdem werde ich jetzt auch mal über eine Codierung von Java aus nachdenken.
Du hast es nicht verstanden.
Du darfst NIEMALS etwas, das in GET oder POST steht, blind vertrauen, egal in welcher Sprache. Du musst immer auf Sinnhaftigkeit prüfen. Dein Highscore wird z.B. wohl immer Integer sein, also prüfe darauf.
 
An das mit den Integer-Überprüfung hab ich noch gar nicht gedacht, danke. (Grad ausprobiert, des verursacht tatsächlich Probleme) Hab einfach eine is_numeric() Prüfung eingebaut, des sollte reichen damit er rechnen kann.

Aber utf8_encode() und utf8_decode() hab ich beides schon probiert gehabt, geht nicht :-/
Außerdem hab ich Probiert:
PHP:
Header('Content-type: text/html; charset=utf-8');
oder:
PHP:
$doc = new DOMDocument('1.0', 'UTF-8');

Interessant ist vielleicht auch, dass DOMDocument es schafft die Umlaute zu schreiben (wenn XML auf UTF-8), jedoch immer nur den 1. Platz ändert, weil er es anscheinend nicht schafft den Inhalt der nodes auszulesen.
 
Ist deine XML denn korrektes BOM-loses UTF-8? Jede Wette, du hast n Schrott-Editor verwendet, der BOM drankleistert oder standardmäßig in ISO speichert
 
Guter Einfall!

Ich benutze den Editor von http://www2ftp.de/ der muss nicht unbedingt sonderlich gut sein. (Der markiert auch nicht farbig, deshalb tu ich vom Notepad++ da reinkopieren)

Ich teste mal die ganzen Methoden nochmal lokal mitm Apache

(Notepad++ sollte O.K. sein oder?)

EDIT:

Funktioniert auch nicht, dafür zeigt er aber einen Fehler an:

Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in C:\xampp\htdocs\guestbook\geths.php on line 58

Was genau damit jetzt gemeint ist versteh ich aber nicht.

Noch etwas: Könnte der Fehler auch daran liegen, dass ich den Internet Explorer 8 verwende? (Normalerweise nicht, immerhin wird PHP doch vom Server übersetzt, und im Seitenquellcode steht auch nichts aufschlussreiches)
 
Zuletzt bearbeitet:
Ich habs schon die ganze Zeit so:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<highscores>
	<highscore>
		<name>Sieger</name>
		<score>11</score>
	</highscore>
	<highscore>
		<name>First</name>
		<score>10</score>
	</highscore><highscore>
		<name>Second</name>
		<score>9</score>
	</highscore><highscore>
		<name>Third</name>
		<score>8</score>
	</highscore><highscore>
		<name>Fourth</name>
		<score>7</score>
	</highscore><highscore>
		<name>Fifth</name>
		<score>6</score>
	</highscore><highscore>
		<name>Sixth</name>
		<score>5</score>
	</highscore><highscore>
		<name>Seventh</name>
		<score>4</score>
	</highscore><highscore>
		<name>Eighth</name>
		<score>3</score>
		</highscore><highscore>
		<name>Ninth</name>
		<score>2</score>
	</highscore>
</highscores>

Und so meint der Typ aus deinem Link ja, dass ich es machen soll. Deshalb verstehe ich nicht wieso die Fehlermeldung bleibt. (Ich vermute, dass die XML nicht richtig geöffnet wird)

Ich benutze Internet Explorer 8 weil ich im Betrieb sitze und da der Standard ist... ^^' Aber wir steigen (vielleicht) bald auf ie11 um.
 
Ich kann deine XML als String problemlos einlesen.

PHP:
<?php
$xml = '
<?xml version="1.0" encoding="UTF-8"?>
<highscores>
	<highscore>
		<name>Sieger</name>
		<score>11</score>
	</highscore>
	<highscore>
		<name>First</name>
		<score>10</score>
	</highscore><highscore>
		<name>Second</name>
		<score>9</score>
	</highscore><highscore>
		<name>Third</name>
		<score>8</score>
	</highscore><highscore>
		<name>Fourth</name>
		<score>7</score>
	</highscore><highscore>
		<name>Fifth</name>
		<score>6</score>
	</highscore><highscore>
		<name>Sixth</name>
		<score>5</score>
	</highscore><highscore>
		<name>Seventh</name>
		<score>4</score>
	</highscore><highscore>
		<name>Eighth</name>
		<score>3</score>
		</highscore><highscore>
		<name>Ninth</name>
		<score>2</score>
	</highscore>
</highscores>';

$doc = new DOMDocument();
$doc->loadXML($xml);

Öffne deine XML in Notepad++.
Stell das Encoding auf UTF-8 ohne BOM (achte auf Veränderungen).
Speicher neu ab.
Lese neu ein.
 
Erstes Zeichen löschen und neu schreiben...

Aber insgesamt nochmal der Tip: Weg von XML, hin zu Datenbanken. SQLite ist nicht so schwer und läuft quasi überall.
Alternativ: Nimm JSON statt XML. Weniger Platzbedarf, weniger Querelen mit der Maskierung, weniger Zicken bei der Iteration.
 
Ich habs jetzt:

Mein Problem war, dass ich die XML-Variable in 'einfachen Anführungsstrichen' dem DOMDocument übergeben habe (Ich glaube zumindest, dass es das war ;-) ). Entweder keine oder "doppelte" funktionieren ^^ .

Ich frage mich trotzdem warum es vorher mit iso-8839 kodierung funktioniert hat...

Ich danke euch für eure Unterstützung :-)

Gruß

Lukas

EDIT:
Und mir fiel grad auf, ein weiteres Problem war die Encodierung vom Editor. Als ich es einfach in den Online Editor reinkopiert hatte ging es wieder nicht. Aber ihr hattet mich ja schon drauf hingewiesen deshalb war es kein Problem des Zeug lokal zu schreiben und hochzuladen ^^
 
Zuletzt bearbeitet:
Zurück
Oben