http://qs1969.pair.com?node_id=1165170


in reply to Convert special characters in UTF8

When dealing with UTF-8, you usually end up having to exhaustively track and verify the format of your text at each layer. With Perl, you will also often have to worry about whether strings are considered "utf8" or not by Perl.

When things are working properly, you shouldn't have to worry about Perl's "utf8" flag for strings. And the p5p community (the authors of Perl) tends to cater toward the "things working properly" case and so just being able to tell what format the string is really in and whether the "utf8" flag is on keeps getting trickier.

One of the easiest tools to aid such investigations, in my experience, is Devel::Peek. It will nicely dump the byte format of a string, whether the "utf8" flag is on, and, if it is on, the UTF-8 char format of the string.

So you might want to update your code to something like:

#!/usr/bin/perl -w use strict; use warnings; use Encode; use DBI; use feature 'unicode_strings'; use Devel::Peek qw< Dump >; binmode(STDOUT, ":utf8"); my $db = "..."; my $user = "..."; my $pw = '...'; my $host = "..."; my $options = {RaiseError => 1, AutoCommit => 1, mysql_enable_utf8 => +1}; my $dbh = DBI->connect("DBI:mysql:$db:$host", $user, "$pw", $options) +|| die "Could not connect to database!"; my $sql = 'select post_id, post_text from phpbb_posts where post_id = +24358'; my $sth = $dbh->prepare($sql); $sth->execute() or die "Error: $DBI::errstr"; my ($id, $text) = $sth->fetchrow_array; print "id: $id text: $text"; Dump( $text ); $text =~ s/&#9500;â&#9516;ñ/ä/g; $text =~ s/&#9500;â&#9516;Â/ö/g; $text =~ s/&#9500;â&#9532;©/ß/g; $text =~ s/&#9500;â&#9516;&#9565;/ü/g; print "\nid: $id text: $text"; Dump( $text );

You should also do some tests where you put a specific UTF-8 string into your DB and then pull it back out, using Dump() on both what you sent in and what you got back.

You may need to fiddle with more MySQL-specific options or even update DBD::mysql, or, if you are using something very old, upgrade Perl itself. You might even find that DBD::mysql misuses Perl's "utf8" flag for strings so you may end up testing taking a proper UTF-8 string but telling Perl that it is a string of bytes ("utf8" off) before sending it off to MySQL. Or find that MySQL is giving back to you such a string.

- tye