2009-06-11 4 views
11

私のdelicious-to-wp perl scriptは動作しますが、より奇妙な出力でさえ、すべての "奇妙な"文字を与えます。 だから私はPerlのDBIでUnicodeを処理するにはどうすればよいですか?

$description = decode_utf8($description); 

それdoesntの違いを作ることを試してみました。私は好きです。これは動作するように私はPerlでどのようにUnicodeを処理できますか?

UPDATE:

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

私はトリッキー、設定しなければならなかった部分だった:私はこの問題は、私はPerlで設定する必要がありましたDBIのUTFを設定することがわかりました。ありがとう!

+0

まだ問題を呈する最短のスクリプトにあなたのコードを蒸留します。方程式からデータベースを取り出し、問題がPerlと何か関係があるかどうかを調べます。他の人がテストやデバッグをすることができます。 Schema->接続(: –

答えて

3

Perlとは関係ありません。該当するMySQLテーブルの列にUTFエンコーディングを使用していることを確認してください。

+0

テーブルがUTFにあったが、私は私のような怠け者ためのPerl ... – edelwater

17

DBD :: mysqlの新しいバージョン(3.0008)を実行している場合は、次のようにすることができます。$dbh->{'mysql_enable_utf8'} = 1;すべてのdecode()ed/encode()ed DBIから/への出方。

+5

にDBIにセット名を追加する必要がありました、これはDBIC変異体である「DBI:mysqlの:」$ {デシベル。 db}、$ db {user}、$ db {pass}、{mysql_enable_utf8 => 1}); –

+0

解決策の解決策は私のためには機能しませんが、上記のコメントの解決策は@alによって解決されます。魅力のように働く。 –

3

間違いなくあなたがのデシベルそれがだろうからobatined任意のデータを任意のperlの処理を行おうとしている場合は、通知を取るUTF-8宣言したデータベースにアクセスするための一日を保存しますが、

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

用語この操作は暗黙的ではないので、perl varにutf8文字列として格納することをお勧めします。当然の

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

、UTF8文字列の扱いO適切に私は/(読み込み、印刷、出力への書き込み)、後者は必須で

use open ':utf8'; 

binmode STDOUT, ":utf8"; 

を設定することを忘れないためにutf8文字列を出力します。お役に立てれば。

+0

デコード機能を取得するには? Perlは、decode()ルーチンが見つからないというエラーを表示します。ありがとう! – Arsenii

+0

は、これは私のproblem..Have XHRを使ってクライアントにJSON文字列を返すPostgresのUTF-8データベースに接続perlのcgiスクリプトを修正しました。文字列がクライアント側に表示されていて、 'my $ final_utf8 = Encode :: encode_utf8($ treeJSON);を追加するまで文字化けしました。 CGI-> header( 'application/json; charset = UTF-8')を出力します。あなたの投稿に示唆されているように "$ final_utf8";を印刷してください。 これを使うには、perlスクリプトの先頭に 'Use Encode;'が必要であることを覚えておいてください。 – GoinOff

1

はこの1つを残す:

binmode STDOUT, ":utf8"; 

を使用している場合:

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

をそうしないと、あなたの出力が読めない、ダブルバイト文字で、その結果、二重のUTF8エンコーディングを持つことになります!それは、これを理解するために私に数時間を要した ...

+0

何を言うことは、その後のPerlは、データベースから取得したデータはUTF-8でエンコードされた知らないと、単にそれがバイトであると考えてtrueの場合。確かにDBD :: Mysql(またはあなたが使用しているDBD)は、データベースからデータをデコードしているので、PerlはUnicode文字を持っていることを知っていなければならず、utf8レイヤーでstdoutに書き込まれたときにはすべてうまくいくでしょう。あなたの記述が何が起こったのか、私はあなたのDBDが壊れていることを示唆しています。しかし、最新のDBD :: Mysqlを見ると、 "sv_utf8_decode(sv);"少なくとも一部のデータでは – bohica

+0

bohica、DBD :: mysqlは通常バイトを提供しますが、[暗黙的なデコード](http://p3rl.org/DBD::mysql#mysql_enable_utf8)はデフォルトではオンになっていません。 – daxim

11

あなたは、このようにデータベースに接続するとき、UTF8を有効にします。

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."; 

これは、必要に応じて設定されUTF8フラグであなたの文字モードの文字列を取得する必要があります。 DBI General Interface Rules & Caveatsから

:ユニコード(UTF8内部)と非Unicode(符号化を前提とすることを余儀なく場合はISO-8859-1デフォルト):

Perlは文字列の2種類をサポートしています。ドライバは、両方の種類の文字列を受け入れ、必要に応じて、使用されているデータベースの文字セットに変換します。同様に、データベースからiso-8859-1でない文字データをフェッチする場合、ドライバはutf8に変換する必要があります。 mysql_enable_utf8

ため

そしてDBD::mysqlから詳細また、このフラグをオンにすると、着信データは、UTF-8として扱われるべきであるとMySQLを伝えます。これは、connect()の呼び出しの一部として使用された場合にのみ有効です。接続後にフラグをオンにする場合は、SET NAMES utf8コマンドを発行して同じ効果を得る必要があります。

0

デフォルトでは、ドライバPerl/MySQLはバイナリデータを処理します(少なくとも、MySQL 5.1と5.5のいくつかの実験でこれを結論付けました)。

mysql_enable_utf8を設定せずに、私はエンコード/に/読み取り、データベースから/書き込む前に/ UTF-8から文字列をデコード。

これは、バイトの配列としてPerlの内部文字列表現に依存すべきではありません。内部 'utf8'は標準UTF-8であることが保証されていないことに注意してください。逆に、シングルバイトエンコーディングはISO-8859-1であるとは保証されません。実際にはUTF-8(とは 'utf8'ではなく)から/へのエンコード/デコードを行います。

MySQLのいくつかの設定もあります(上記のSET NAMESのように、クライアントのエンコーディング、接続エンコーディング、サーバーエンコーディングがあることを覚えていれば、エンコーディングに関しては同じ値を持つ)。それらのすべてをUTF-8に設定し、上記のレシピは私のために働いていました。