19 Stimmen

Wie kann ich Unicode mit Perl's DBI behandeln?

Meine lecker-zu-wp Perl-Skript funktioniert, gibt aber für alle "seltsamen" Zeichen eine noch seltsamere Ausgabe. Also habe ich versucht

$description = decode_utf8( $description ); 

aber das macht keinen Unterschied. Ich möchte z.B., dass "go live" zu "go live" wird und nicht zu "go live". Wie kann ich Unicode in Perl behandeln, damit das funktioniert?

UPDATE: Ich fand das Problem war, um utf von DBI musste ich in Perl gesetzt:

my $sql = qq{SET NAMES 'utf8';};
$dbh->do($sql);

Das war der Teil, den ich einstellen musste, der schwierig war. Danke!

0 Stimmen

Reduzieren Sie Ihren Code auf das kürzestmögliche Skript, das das Problem noch immer aufweist. Nehmen Sie die Datenbank aus der Gleichung heraus, um herauszufinden, ob das Problem etwas mit Perl zu tun hat. Entwickeln Sie etwas, das andere testen und debuggen können.

23voto

Penfold Punkte 2438

Es ist erwähnenswert, dass Sie Folgendes tun können, wenn Sie eine neue Version von DBD::mysql verwenden (ab 3.0008): $dbh->{'mysql_enable_utf8'} = 1; und dann wird alles für Sie auf dem Weg von/nach DBI decodiert()ed/encode()ed.

7 Stimmen

Für Faule wie mich ist dies die dbic-Variante: Schema->connect("dbi:mysql:".$db{db}, $db{user}, $db{pass}, {mysql_enable_utf8 => 1} );

0 Stimmen

Die Lösung in der Antwort funktioniert bei mir nicht, aber die Lösung im obigen Kommentar von @al. funktioniert wie ein Zauber.

0 Stimmen

Según die Dokumentation es kann während des Verbindungsaufbaus erfolgen, der weitere Aktionen erfordert. Wenn Sie es nach der Verbindung tun, wie in der Antwort vorgeschlagen, müssen Sie auch einen zusätzlichen Befehl ausführen: SET NAMES utf8 .

14voto

LucaS Punkte 153

Aktivieren Sie UTF8, wenn Sie eine Verbindung zur Datenbank wie folgt herstellen:

my $dbh = DBI->connect(
    "dbi:mysql:dbname=db_name", 
    "db_user", "db_pass",
     {RaiseError => 0, PrintError => 0, mysql_enable_utf8 => 1}
 ) or die "Connect to database failed.";

Damit sollten Sie Zeichenketten im Zeichenmodus mit gesetztem UTF8-Flag nach Bedarf erhalten.

Desde DBI Allgemeine Schnittstellenregeln und Vorbehalte :

Perl unterstützt zwei Arten von Zeichenketten: Unicode (intern utf8) und Nicht-Unicode (standardmäßig iso-8859-1, wenn eine Kodierung angenommen werden muss). Treiber sollten beide Arten von Strings akzeptieren und, falls erforderlich, in den Zeichensatz der verwendeten Datenbank konvertieren. Ebenso sollte der Treiber beim Abrufen von Zeichendaten aus der Datenbank, die nicht iso-8859-1 sind, diese in utf8 konvertieren.

Und die Einzelheiten aus DBD::mysql für mysql_enable_utf8

Außerdem teilt das Einschalten dieses Flags MySQL mit, dass eingehende Daten als UTF-8 behandelt werden sollen. Dies wird nur wirksam, wenn es als Teil des Aufrufs von connect() verwendet wird. Wenn Sie das Flag nach dem Verbindungsaufbau einschalten, müssen Sie den Befehl SET NAMES utf8 eingeben, um den gleichen Effekt zu erzielen.

1 Stimmen

Ich danke Ihnen dafür. Ich habe versucht, den Content-Type und charset.... zu aktualisieren. Ich habe über die serverseitige Kodierung und Dekodierung.... nachgedacht, aber es schien, als ob ich etwas übersehen hätte. Mein Problem war das einzelne Hochkomma in einem Eingabefeld. Auf meinem Laptop funktionierte es gut, aber bei einer Eingabe von meinem iPhone aus (beide Geräte verwenden übrigens Chrome) erhielt ich ein komisches Zeichen, das sogar in der Datenbank vorhanden war. Aber Hooray für Ihre Antwort. Diese einfache Korrektur an meiner get_database_handle()-Routine hat mein Problem gelöst. Großes Lob an Sie.

6voto

Spirit Electric Punkte 51

Der Begriff

$dbh->do(qq{SET NAMES 'utf8';});

rettet definitiv den Tag für den Zugriff auf eine utf-8 deklarierte Datenbank, aber beachten Sie, wenn Sie irgendeine Perl-Verarbeitung von alle aus der Datenbank gewonnenen Daten wäre es ratsam, sie in einer Perl-Var als utf8-String mit zu speichern, da diese Operation nicht implizit ist.

$utfstring = decode('utf8',$string_from_db);

Natürlich muss für die korrekte Verarbeitung von utf8-Zeichenfolgen (Lesen, Drucken, Schreiben in die Ausgabe) die Einstellung

use open ':utf8';

y

binmode STDOUT, ":utf8";

Letzteres ist für den Ausdruck von utf8-Strings unerlässlich. Ich hoffe, das hilft.

0 Stimmen

Wie erhält man die Dekodierfunktion? Perl zeigt einen Fehler an, der besagt, dass die decode()-Routine nicht gefunden werden kann. Danke!

1 Stimmen

Dies behebt mein Problem Habe ein Perl-Cgi-Skript, das eine Verbindung zu einer Postgres utf-8-Datenbank, die eine JSON-Zeichenfolge an den Client mit XHR zurückgibt. Die Zeichen wurden auf der Client-Seite alle verstümmelt angezeigt, bis ich hinzugefügt my $final_utf8 = Encode::encode_utf8($treeJSON); print CGI->header('application/json;charset=UTF-8'); print "$final_utf8"; wie in Ihrem Beitrag vorgeschlagen. Denken Sie daran, Sie brauchen use Encode; am Anfang Ihres Perl-Skripts, um dies zu verwenden.

1 Stimmen

Keine der Antworten bis zu dieser konnte mein UTF8-DB-Problem lösen, aber diese schon. Danke!

3voto

Richard Simões Punkte 11699

Das hat vielleicht nichts mit Perl zu tun. Stellen Sie sicher, dass Sie UTF-Kodierungen in den entsprechenden MySQL-Tabellenspalten verwenden.

1voto

Michel Punkte 11

Lassen Sie diese Öne weg:

binmode STDOUT, ":utf8";

bei der Verwendung:

$dbh->do(qq{SET NAMES 'utf8';});

Andernfalls wird Ihre Ausgabe eine doppelte utf8-Kodierung aufweisen, was zu unlesbaren Doppelbyte-Zeichen führt! Ich habe ein paar Stunden gebraucht, um das herauszufinden

0 Stimmen

Wenn das, was Sie sagen, wahr ist, dann weiß Perl nicht, dass die aus der Datenbank abgerufenen Daten UTF-8 kodiert wurden und denkt einfach, dass es Bytes sind. Sicherlich dekodiert DBD::Mysql (oder welches DBD auch immer Sie verwenden) die Daten aus der Datenbank für Sie, in diesem Fall sollte Perl wissen, dass Sie Unicode-Zeichen haben und wenn sie mit dem utf8-Layer nach stdout geschrieben werden, wird alles gut sein. Wenn das, was Sie beschreiben, passiert, würde ich vermuten, dass Ihre DBD defekt ist. Wie auch immer, wenn man sich die neueste DBD::Mysql ansieht, macht sie "sv_utf8_decode(sv);", zumindest bei einigen Daten.

0 Stimmen

Bohica, DBD::mysql liefert normalerweise Bytes, implizite Dekodierung ist standardmäßig nicht aktiviert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X