web-dev-qa-db-ja.com

データベーステキスト内の奇妙な文字:Ã、Ã、¢、â、€、

これが最初にいつ発生したかはわかりません。

新しいドロップアフィリエイトWebサイトを作成し、卸売業者から製品カタログのエクスポートされたコピーを受け取ります。これをフォーマットしてPrestashop 1.4.4にインポートします。

Webサイトのフロントエンドには、製品テキスト内の奇妙な文字の組み合わせが含まれています:Ã、Ã、¢、â、など。一般的な文字の代わりに表示など、-:など.

これらの文字は、ps_product_langなどの製品固有のテーブルだけでなく、データベーステーブルの約40%に存在します。

別のWebサイトスレッドと言いますが、データベース接続文字列が誤った文字エンコードタイプを使用している場合にも同じ問題が発生します。

/config/setting.incには、文字エンコード文字列は記載されていません。InnoDBに設定されているMySQL Engineのみがあり、PHPMyAdminで表示されるものと一致します。

Ps_product_langをエクスポートし、これらの文字のすべてのインスタンスを正しい文字に置き換え、CSVファイルをUTF-8形式で保存し、言語としてUTF-8を指定してPHPMyAdminを使用して再インポートしました。

しかし、PHPMyAdminで新しい検索を行った後、ps_product_langにはこれらの悪い文字のインスタンスが最初の約10倍あります。

問題がデータベース接続文字列で正しい言語属性を指定するだけの単純な場合、これをどこで/どのように設定しますか?

偶然、 this thread に記載されているPHPMyAdminでこのコマンドを実行しようとしましたが、問題は残ります:

SET NAMES utf8

[〜#〜] update [〜#〜]:PHPMyAdminのコメント:

MySQL文字セット:UTF-8 Unicode(utf8)

これは、前回のインポートファイルで使用したのと同じ文字セットであり、より多くの文字破損が発生しました。インポートプロセス中に、インポートファイルの文字セットとしてUTF-8が指定されました。

UPDATE2

サンプルを次に示します。

人々は本当につながれていない生きていますウェブ。

UPDATE3

PHPMyAdminでSQLコマンドを実行して、文字セットを表示しました。

  • character_set_client utf8
  • character_set_connection utf8
  • character_set_database latin1
  • character_set_filesystemバイナリ
  • character_set_results utf8
  • character_set_server latin1
  • character_set_system utf8

したがって、おそらく私のデータベースをUTF-8に変換(または削除して再作成)する必要があります。 MySQLサーバーがlatin1の場合、これは問題になりますか?

MySQLは、コンテンツの変換をUTF8として処理できますが、latin1として保存できますか? UTF8はlatin1のスーパーセットであるため、それができるとは思わない。私のウェブホスティングサポートは48時間以内に返信しませんでした。彼らには難しいかもしれません。

25
Steve

テーブルの文字セットがコンテンツと同じ場合は、 mysql_set_charset('UTF8', $link_identifier) を使用してください。 MySQLは、より一般的なUTF8の代わりにUTF-8を使用してUTF-8エンコーディングを指定することに注意してください。

同様の質問でも my other answer を確認してください。

17
AlexV

これは確かにエンコードの問題です。データベースとWebサイトで異なるエンコーディングを使用しており、この事実が問題の原因です。また、そのコマンドを実行した場合は、すでにテーブルにあるレコードを変更して、それらの文字をUTF-8に変換する必要があります。

Update:最後のコメントに基づいて、問題の核心は、異なるエンコードを使用するデータベースとデータソース(CSVファイル)があることです。したがって、データベースをUTF-8で変換できます。または、少なくとも、CSVにあるデータを取得したら、UTF-8からlatin1に変換する必要があります。

この記事に従って変換を行うことができます:

5
Aurelio De Rosa

これら2つのことを適用します。

  1. データベースの文字セットを_utf8_に設定する必要があります。

  2. データベースとの接続を作成したファイルでmysql_set_charset('utf8')を呼び出す必要があり、_mysql_select_db_のようなデータベースを選択した直後に_mysql_set_charset_を使用します。これにより、どの言語でも適切にデータを追加および取得できます。

2
Haisum Usman

これは、UTF-8エンコードの問題であると思われます。これは、データベースファイルの内容の二重UTF8エンコードが原因である可能性があります。

この状況は、選択された文字セットや選択されなかった文字セット(データベースバックアップファイルの作成時など)、およびファイル形式とエンコードデータベースファイルの保存などの要因により発生する可能性があります。

次のシナリオでこれらの奇妙なUTF-8文字を見ました(問題のデータベースにアクセスできなくなったため、説明が完全に正確ではない場合があります)。

  • 私が思い出すように、データベースとテーブルには「uft8_general_ci」照合がありました。
  • データベースのバックアップが作成されます。
  • バックアップファイルは、UNIXファイル形式で、ANSIエンコーディングでWindows上で開かれます。
  • データベースは、データベースバックアップファイルの内容をphpMyAdminにコピーアンドペーストすることにより、新しいMySQLサーバーに復元されます。

ファイルの内容を調べる:

  • テキストエディタでSQLバックアップファイルを開くと、SQLバックアップファイルに「sÃ¥」などの奇妙な文字が含まれていることがわかります。ちなみに、同じファイルを別のエディターで開くと、異なる結果が得られる場合があります。ここではTextPadを使用していますが、SublimeTextで同じファイルを開くと「sÃ」と言われます。SublimeTextがファイルを正しくUTF8エンコードしているためです。それでも、PHP最初はSublimeTextに正しいデータが表示されません。とにかく、ファイルの内容を表示するときにテキストエディターが使用しているエンコードを記録することで解決できます。
  • 奇妙な文字は二重エンコードされたUTF-8文字であるため、私の場合、最初の「Ã」部分は「Ã」および「Â¥」=「¥」に等しくなります(これが私の最初の「エンコード」です)。 「Ã¥」文字は「å」のUTF-8文字に相当します(これは私の2番目のエンコードです)。

そのため、問題は、「false」(UTF8エンコード2回)utf-8を「正しい」utf-8(UTF8エンコード1回のみ)に変換する必要があることです

PHPでこれを修正しようとすると、少し難しいことがわかります。

utf8_decode()は文字を処理できません。

// Fails silently (as in - nothing is output)
$str = "så";

$str = utf8_decode($str);
printf("\n%s", $str);

$str = utf8_decode($str);
printf("\n%s", $str);

iconv()は「Notice:iconv():Detected a illegal character in input string」で失敗します。

echo iconv("UTF-8", "ISO-8859-1", "så");

このシナリオでは、別の 細かい解決策 も黙って失敗します

$str = "så";
echo html_entity_decode(htmlentities($str, ENT_QUOTES, 'UTF-8'), ENT_QUOTES , 'ISO-8859-15');

mb_convert_encoding()サイレント:

$str = "så";
echo mb_convert_encoding($str, 'ISO-8859-15', 'UTF-8');
// (No output)

MySQLデータベースの文字セットと照合をUTF-8に変換する でMySQLのエンコーディングを修正しようとしても失敗しました。

ALTER DATABASE myDatabase CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE myTable CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

この問題を解決する方法はいくつかあります。

1つは、正しいエンコードでバックアップを作成することです(エンコードは、実際のデータベースおよびテーブルのエンコードと一致する必要があります)。結果のSQLファイルをテキストエディタで開くだけで、エンコードを確認できます。

もう1つの方法は、二重UTF8エンコード文字を単一UTF8エンコード文字に置き換えることです。これは、テキストエディターで手動で実行できます。このプロセスを支援するために、Try TF-8 Encoding Debugging Chart から間違った文字を手動で選択することができます(5-10のエラーを交換する必要がある場合があります)。

最後に、スクリプトがプロセスを支援できます。

    $str = "så";
    // The two arrays can also be generated by double-encoding values in the first array and single-encoding values in the second array.
    $str = str_replace(["Ã","Â¥"], ["Ã","¥"], $str); 
    $str = utf8_decode($str);
    echo $str;
    // Output: "så" (correct)
2

今日、かなり似た問題に遭遇しました。ファイル自体は通常のutf8ですが、mysqldumpはutf-8ベースエンコーディングutf-8の発音区別記号を2つのlatin1文字としてダンプしました。

たとえば、「é」は2文字「é」としてエンコードされました。これらの2つの文字は、文字のutf8 2バイトエンコーディングに対応していますが、単一の文字として解釈される必要があります。

問題を解決し、別のサーバーにデータベースを正しくインポートするには、ftfy(「Fixes Text For You」の略)を使用してファイルを変換する必要がありました。( https://github.com/LuminosoInsight/python-ftfy )python library。ライブラリは、期待どおりに動作します。正しくエンコードされていないutf-8に正しくエンコードされたutf-8を変換します。

たとえば、このlatin1の組み合わせ「é」は「é」に変換されます。

ftfyにはコマンドラインスクリプトが付属していますが、ファイルを変換するため、mysqlにインポートできません。

トリックを行うためにpython3スクリプトを作成しました。

#!/usr/bin/python3
# coding: utf-8

import ftfy

# Set input_file
input_file = open('mysql.utf8.bad.dump', 'r', encoding="utf-8")
# Set output file
output_file = open ('mysql.utf8.good.dump', 'w')

# Create fixed output stream
stream = ftfy.fix_file(
    input_file,
    encoding=None,
    fix_entities='auto', 
    remove_terminal_escapes=False, 
    fix_encoding=True, 
    fix_latin_ligatures=False, 
    fix_character_width=False, 
    uncurl_quotes=False, 
    fix_line_breaks=False, 
    fix_surrogates=False, 
    remove_control_chars=False, 
    remove_bom=False, 
    normalization='NFC'
)

# Save stream to output file
stream_iterator = iter(stream)
while stream_iterator:
    try:
        line = next(stream_iterator)
        output_file.write(line)
    except StopIteration:
        break
1
Pielo

通常、CSVの作成中にエラーが発生します。 Linuxを使用してCSVをTextCSVとして保存してみてください。 UbuntuのLibre OfficeはエンコードをUTF-8に強制できます。 Mac OSでこれを試すのに多くの時間を無駄にしました。 Linuxが鍵です。 Ubuntuでテストしました。

がんばろう

1
Achin Kumar