seltsame Zeichencodierung gespeicherter Daten, altes Skript zeigt sie gut an, neues nicht

Lesezeit: 4 Minuten

seltsame Zeichencodierung gespeicherter Daten altes Skript zeigt sie gut an
max

Ich versuche, eine alte Website neu zu schreiben.
Es ist auf Persisch, das perso/arabische Zeichen verwendet.

CREATE DATABASE `db` DEFAULT CHARACTER SET utf8 COLLATE utf8_persian_ci;
USE `db`;

Fast alle meine Tabellen/Spalten sind auf COLLATE eingestellt utf8_persian_ci

Ich verwende Codeigniter für mein neues Skript und ich habe

'char_set' => 'utf8',
'dbcollat' => 'utf8_persian_ci',

In den Datenbankeinstellungen gibt es also kein Problem.

Hier ist also der seltsame Teil

Das alte Skript verwendet eine Art Datenbank-Engine namens TUBADBENGINE oder TUBA DB ENGINE … nichts Besonderes .

Wenn ich einige Daten in die Datenbank (auf Persisch) mit dem alten Skript eingebe, wenn ich in die Datenbank schaue, werden Zeichen wie gespeichert عمران .

Das alte Skript holt/zeigt diese Daten gut an, aber das neue Skript zeigt sie mit der gleichen seltsamen Schriftart/Zeichensatz wie die Datenbank

Also wenn ich eintrete اااا sieht Datenbank gespeicherte Daten aus عمرا٠wenn ich es im neuen Skript abrufe, sehe ich عمرا٠aber im alten Skript sehe ich اااا

CREATE TABLE IF NOT EXISTS `tnewsgroups` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `fName` varchar(200) COLLATE utf8_persian_ci DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=11 ;

--
-- Dumping data for table `tnewsgroups`
--

INSERT INTO `tnewsgroups` (`ID`, `fName`) VALUES
(1, 'عمران'),
(2, 'معماری'),
(3, 'برق'),
(4, 'مکانیک'),
(5, 'test'),
(6, 'test2');

Andererseits, wenn ich eintrete ااااا direkt in der Datenbank

Das gleiche habe ich natürlich auch اااا in der Datenbank gespeichert

Das neue Skript zeigt es gut

Aber im alten Skript bekomme ich ????

Kann jemand etwas Sinn daraus machen?

Hier ist der Tuba-Engine

https://github.com/maxxxir/mz-codeigniter-crud/blob/master/tuba.php

Anwendungsbeispiel aus altem Skript:

define("database_type" , "MYSQL");
define("database_ip" , "localhost");
define("database_un" , "root");
define("database_pw" , "");
define("database_name" , "nezam2");
define("database_connectionstring" , "");
$db = new TUBADBENGINE(database_type , database_ip , database_un , database_pw , database_name , database_connectionstring);
$db->Select("SELECT * FROM tnews limit 3");
if ($db->Lasterror() != "") { echo "<B><Font color=red>ÎØÇ ! áØÝÇ ãÌÏøÏÇ ÊáÇÔ ˜äíÏ";  exit(); }
for ($i = 0 ; $i < $db->Count() ; $i++) {
    $row = $db->Next();
    var_dump($row);
}

seltsame Zeichencodierung gespeicherter Daten altes Skript zeigt sie gut an
verzeihen

Kurz gesagt, weil dies schon tausendmal diskutiert wurde:

  1. PHP hält beispielsweise einen String "漢字", kodiert in UTF-8. Die Bytes dafür sind E6 BC A2 E5 AD 97.
  2. Es sendet diese Zeichenfolge über a Datenbankverbindung, die eingestellt ist latin1.
  3. Die Datenbank empfängt die Bytes E6 BC A2 E5 AD 97denkend, dass diese darstellen latin1 Zeichen.
  4. Die Datenbank speichert die Zeichen æ¼¢å­ (die Charaktere, die E6 BC A2 E5 AD 97 Karten nach innen latin1).
  5. Der gleiche umgekehrte Prozess führt dazu, dass PHP die gleichen Bytes empfängt, die es dann als UTF-8 behandelt. Der Roundtrip funktioniert gut für PHP, obwohl die Datenbank die Zeichen nicht so behandelt, wie sie sollte.

Das Problem hier war also, dass die Datenbankverbindung beim Eintragen der Daten in die Datenbank falsch gesetzt wurde. Sie müssen die Daten in der Datenbank in die richtigen Zeichen umwandeln. Versuche dies:

SELECT CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8) FROM table_name

Vielleicht utf8 ist nicht das, was Sie hier brauchen, experimentieren Sie. Wenn das funktioniert, ändern Sie dies in eine UPDATE Anweisung, die Daten permanent zu aktualisieren.

  • Danke für dieses Skript!!

    – Lukas

    26. März 2014 um 9:34 Uhr

  • @Deceze: Gibt es eine einfache Möglichkeit, eine solche Konvertierung für jedes Feld in der Datenbank durchzuführen?

    – Abdel5

    8. September 2015 um 18:49 Uhr

  • @Abdel5 Das Sichern der Datenbank und das erneute Importieren mit der richtigen/falschen Kombination aus Import-/Export-Zeichensatz ist wahrscheinlich der einfachste Weg.

    – verzeihen

    8. September 2015 um 19:31 Uhr

Die Antwort von Deceze ist ausgezeichnet, aber ich kann einige Informationen hinzufügen, die helfen können, viele Datensätze zu handhaben, ohne sie manuell zu testen.

Wenn die Konvertierung CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8) schlägt fehl, es druckt NULL anstatt des field_name Inhalt.

Also benutze ich diesen, um diese Aufzeichnungen zu finden:

SELECT IFNULL(
    CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8)
    , '**************************************************')
FROM table_name

oder dieses:

SELECT id, field_name, CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8)
FROM table_name
WHERE CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8) IS NULL

Und das UPDATE mit der Klausel, dass nur Datensätze betroffen sind, bei denen der Konvertierungserfolg:

UPDATE table_name
SET
field_name = CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8mb4 )
WHERE
CONVERT(BINARY CONVERT(field_name USING latin1) USING utf8mb4) IS NOT NULL

1002690cookie-checkseltsame Zeichencodierung gespeicherter Daten, altes Skript zeigt sie gut an, neues nicht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy