� abstatt ä,ö,ü....

tklustig

Erfahrenes Mitglied
Hallo Leute, all meine Seiten sind folgendermaßen aufgebaut:

HTML:
<!Doctype html> <!-- Definition des doctype-Modus -->
<html> <!-- Definition des Stammverzeichnises -->
    <head> <!-- Definition des Kopfbereiches -->
        <meta charset="utf-8"> <!-- charset[utf-8:]  definiert den deutschen Zeichensatz -->
        <title> Votum </title> <!-- weist dem HTML-Dokument in der Registerkarte einen Namen zu -->
        <!-- Hier ggf. CSS-Link einfügen, z.B.: <link href="css/selektoren.css" rel="stylesheet"> -->
       <style></style> <!-- hier ggf. CSS direkt einfügen -->
    </head>
    <body>
    </body>
</html>
Außerdem habe ich mittels notepad++ bereits den SQLDump auf die korrekten Umlaute gesetzt.
Zu guter letzt habe ich über die Datenbank folgendes Script laufen lassen. Es wurde korrekt ausgeführt:
PHP:
<?php
$user = "root";
$pw = "";
$databasetyp = "mysql";
$hostname = "localhost";
$databasename = "votum";

try {
    //instanziere ein Objekt der Klasse PDO gemäß den Parametern des Konstruktors
    $dbh = new PDO("$databasetyp:host=$hostname;dbname=$databasename;charset=utf8", $user, $pw, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    echo"<h3>MySQL-Datenbank wurde soeben initialisiert...</h3>";
    echo"<p><font size='5'>Bitte ganz nach unten scrollen um die Zusammenfassung zu lesen!</font>";
} catch (PDOException $e) {
    print "<h3><center>Error!: " . $e->getMessage() . "<br></h3></center>";
    echo"<p><font size='5'>ERROR!!!Keine Verbindung zur Datenbank möglich. Bitte überprüfen Sie folgende Verbindungsparameter:<br>
 Benutzer:$user<br>Datenbanktypus:$databasetyp<br>Server:$hostname<br>Datenbank:$databasename<br>Passwort:";
    if ($pw == "")
        echo "keines</p>";
    else
        echo $pw . "</p>";
    exit();
}

$sql0 = "ALTER DATABASE $databasename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
$dbh->query($sql0);
$sql1 = "SET FOREIGN_KEY_CHECKS=0"; //setzt die referenzielle Integrität außer Kraft
$dbh->query($sql1);
$sql = "SHOW TABLES";

$treffer = $dbh->query($sql);
$x = 0;
foreach ($treffer as $daten) {
    $sql2 = "ALTER TABLE $daten[0] CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci";
    $dbh->query($sql2);
    $x++;
    echo"<p><font color='red'>" . $daten[0] . "</font> wurde soeben auf den richtigen Zeichensatz umgestellt<br>";
}
$sql3 = "SET FOREIGN_KEY_CHECKS=1"; //reaktiviert die referenzielle Integrität
$dbh->query($sql3);
echo"<p><font size='5'><font color='blue'>Die Datenbank $databasename wurde auf den richtigen Zeichenssatz umgestellt<br>";
echo"<p>Es wurden insgesamt $x Tabellen auf den deutschen Zeichensatz utf8_general_ci umgestellt. Umlaute sind jetzt kein Problem mehr!</font>";
?>

Nichts desto trotz werden mittels PHP generierte Links die deutschen Umlaute durch ein dargestellt. Wie kann das sein?Was fehlt denn noch, um die Umlaute korrekt darzustellen?
 
Zuletzt bearbeitet:
utf8_encode() oder utf8_decode() auf die Variable, bin mir gerade unsicher welches von beiden
Diese beiden Funktionen so zu benennen war ein Design Fehler von PHP! Es gibt nicht das Kodieren oder Dekodieren zu UTF-8 oder von UTF-8! Bei Zeichenkodierungen wird immer konvertiert, alles andere ergibt keinen Sinn.
Bei diesen beiden Funktionen ist der andere Zeichensatz ISO-8859-1 (siehe PHP Doku). utf_encode() anzuwenden ist also nur dann sinnvoll, wenn die Ursprungszeichenkodierung ISO-8859-1 ist.

  • In welcher Zeichenkodierung waren die Daten in der Datenbank initial vor Laufen deines Skriptes gespeichert? War diese Zeichenkodierung auch die beim DBMS eingestellte?
    Falls nicht, kann man nach dem CONVERT-Befehl auch nicht mehr erwarten kann, dass die Daten nun UTF-8 kodiert sind.
    Ich bin mir nicht sicher, ob ein "Rückkonvertieren" möglich ist, sodass die ursprüngliche Zeichenkodierung wieder vorherrscht. Insbesondere wenn die Daten vorher für die angenommene Zeichenkodierung ungültige Kodierungen vorweisten.
    Falls du die Daten reimportieren kannst, würde ich das als einfachste Möglichkeit sehen. Aber nun gleich dem DBMS die eigentliche Zeichenkodierung mitteilen!

  • Mit welchem HTTP Content-Type wird deine Seite vom Server ausgeliefert? Eine dort angegebene Kodierung überschreibt die im <meta>-Tag angegebene Kodierung.
 
Der ursprüngliche Zeichensatz war irgendetwas mit swedish.
Verstehe trotzdem nicht, warum das von Bedeutung sein soll. Mein Konvertierungsscript hat doch funktioniert und den korrekten Zeichensatz eingestellt.
So wurden die Tabellen erzeugt, und zwar alle:
SQL:
DROP TABLE IF EXISTS `voantworten`;
CREATE TABLE `voantworten` (
  `votenID` int(11) NOT NULL default '0',
  `AntwortNr` int(11) NOT NULL default '0',
  `Antwort` varchar(200) NOT NULL default '',
  PRIMARY KEY  (`votenID`,`AntwortNr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Die Datenbank wurde mit dem deutschen Zeichensatz erstellt(utf-8-german2-ci)
P.S.: Ich habe kein php-Content Type defniert, warum auch?
 
Zuletzt bearbeitet:
Hi

ich würde dir dringend empfehlen, nichts zu überstürzen; du kannst dir die Daten in der DB (oder Teile davon) nämlich auch dauerhaft kaputtmachen. Vor allem mit solchen schnell-und-einfach-Konvertierungsscripts wie im ersten Beitrag, die nicht einmal berücksichtigen, was aktuell in der DB in Verwendung ist.

Kann hier in Lied davon singen, wegen der Forensoftwareumstellung vor ein paar Jahren. Die Ersteller haben leider auch nicht viel Ahnung von Zeichensätzen ... gemerkt, dass ein paar hundert Beiträge in der Mitte abgeschnitten wurden, hab ich erst mehr als ein Jahr später (es gibt einfach zu viel Beiträge :D), und das Beheben, mit Berücksichtung der korrekten und/oder seitdem dazugekommenen Sachen, hat zum Glück "nur" ein paar Tage gedauert - dank vorhandenem korrektem Backup der alten Forensoftware. Der Bugreport wurde abgewiesen, viel später dann aber doch behoben :rolleyes:


So, der Reihe nach:

Ich habe kein php-Content Type defniert, warum auch?
Weil das der "normale" Weg ist, um das zu machen, und das Meta-Tag von Clients entweder nur als Alternative oder gar nicht verarbeitet wird. Und wenn, dann kann es eigentlich nicht direkt verarbeitet werden, weil man zum Text-verarbeiten das Charset schon wissen müsste - in der Realität ist es also ein Raten von ein paar üblichen Charsets, und dann prüfen ob das Metatag (falls vorhanden) dazupasst.

Und da die Infos hier etwas durcheinander und unvollständig sind...:
Welches Default-Charset haben deine Tabellen aktuell? Haben "alle" das gleiche? (Und bitte mit einer bestehenden Fremdsoftware prüfen, zB. Phpmyadmin, nicht mit eigenem Code)
Welches Default-Charset haben deine Tabellen"spalten" (die mit Text zumindest) aktuell? Haben "alle" das gleiche?
Welche Kollation haben deine Tabellenspalten aktuell? Haben "alle" das gleiche?
Welches Charset ist für die PHP-Dateien (also den PHP-Code selber) in Verwendung (NP++ zeigt das schön an)?
Welches Charset hat deine DB-Verbindung in PHP (also das PDO-Objekt, oder Mysqli-Objekt)? Ist überhaupt eins eingestellt?
Wie viel Aufwand wäre es für dich, den gesamten Text in der DB durchzuschauen, und die Korrektheit und Vollständigkeit zu prüfen?
Hast du ein Backup, das vor den ganzen Umwandlungen gemacht wurde?
Und natürlich, mit welchem Code werden die fehlerhaften Links generiert?
 
Zuletzt bearbeitet:
  1. Alle haben lt. phpmyadmin folgenden Charset: utf8_general_ci8 (logisch, nach der Konvertierung)
  2. Für die Spalten gilt dasselbe. Habe alle über phpmyadmin überprüft
  3. Folgende Rückgabe liefert die Datenbank:
    SQL:
    SELECT @@global.character_set_database union
    SELECT @@global.character_set_client union
    SELECT @@global.character_set_connection;
    
    @@global.character_set_client    
    latin1
  4. Wie zeigt mir das NP++ oder Netbeans an?
  5. Habe den gesamten Text bereits überprüft. Die umlaute sind korrekt gespeichert!
  6. So baue ich die Verbindung zur Datenbank auf:
    PHP:
        function __construct() {
            parent::__construct(self::host, self::user, self::passwd, self::mydb);
        }
  7. Yuup. Habe ein Backup
  8. hier der Code der fehlerhaften Links
    PHP:
     $result = $db->query("SELECT votenID,Frage,von,bis FROM voVoten WHERE besitzerID=$besitzerID ORDER BY Frage desc;");
        while (list($votenID, $frage, $von, $bis) = $result->fetch_row()) {
            ?><?= ("[<a href=\"votumdelete.php?votenid=$votenID\">Delete</a>]");
            ?><?= ("$von bis $bis: ");
            ?><?= ("<a href=\"votumedit.php?votenid=$votenID\">");
            ?><?=("$frage</a><br>"); //$frage enthält den inkorrekten Zeichensatz
        }
 
Zuletzt bearbeitet:
Danke für das nummerierte Beantworten fast aller Fragen ;) Das hat man nicht oft!

Wie zeigt mir das NP++ oder Netbeans an?
Im Menü unter "Kodierung". Dort sollte es "UTF-8 ohne BOM" sein.

So baue ich die Verbindung zur Datenbank auf:
Wie sieht der Superklassen Konstruktor aus? Normalerweise solltest du bei MySQLi vor Absetzen jeglicher Queries noch set_charset mit UTF-8 aufrufen.

Wie viel Aufwand wäre es für dich, den gesamten Text in der DB durchzuschauen, und die Korrektheit und Vollständigkeit zu prüfen?
Dazu noch: Kannst du eine der fehlerhaften Frage in PHPMyAdmin oder ähnlichen DB-Interfaces betrachten? Ist sie dort auch fehlerhaft dargestellt? Wenn ja, dann liegen deine Fragen in der DB falsch kodiert vor. => Reimport, siehe oben.

Welche Kollation haben deine Tabellenspalten aktuell? Haben "alle" das gleiche?
Blieb unbeantwortet ;)
 
alle haben die Collation:utf8_general_ci (lt. phpmyadmin)
Ein Absetzen des querys in phpmyadmin liefert die korrekten Zeichen zurück, also ä,ö anstatt ein ? !
Np++ zeigt unter Kodierung an:UTF-8 ohne BOM
 
Zuletzt bearbeitet:
Problem gelöst!!
Habe, wie von Dir vorgeschlagen, vor dem Absetzen des Querys folgenden Befehl auf das Datenbankobjekt abgefeuert:
PHP:
    require_once("xmysqli.php");
    $db = new xmysqli();
    $db->set_charset("utf8");

Und siehe da, das Fragezeichen ist verschwunden:D:):D

so sieht jetzt der Konstruktor aus:
PHP:
        function __construct() {
            parent::__construct(self::host, self::user, self::passwd, self::mydb);
            $this->set_charset("utf8");
        }

Dank Deiner Hilfe kann dieser Thread geschlossen werden!
Bevor ich dieses Thema als gelöst markiere noch eine Frage:
Wie vergibt man in diesem Forum Reputationspunkte für Lösungen, die zum Ziele führten? Außer 'Gefällt mir' wüßte ich nicht, wie man Lösungen gebührend honorieren könnte...
 

Neue Beiträge

Zurück