1

私は次の問題を抱えています: 非常に単純な php-mysqli クエリ:

if ( $result = $mysqli->query( $sqlquery ) )
{
    $res = $result->fetch_all();
    $result->close();
}

utf8_general_ciデータベース、テーブル、および列が照合されているにもかかわらず、文字列が西洋のエンコードされた文字列として誤ってエンコードされます。php スクリプト自体は utf-8 でエンコードされており、スクリプトの mysql を使用しない部分は正しいエンコーディングを取得します。つまりecho "ő"、完全に機能すると言いますがecho $res[0]、前の例からEF BF BD、ファイルが正しい UTF-8 エンコーディングで表示されたときに文字が出力されます。ブラウザのエンコーディングを手動で西洋に切り替えると、西洋以外の文字が「?」に置き換えられることを除いて、mysqli ソースの文字列は適切にデコードされます。

さらに奇妙なのは、私の開発環境ではこれが起こっていないのに、私の Web サーバーでは起こっているということです。開発者環境は LAMP スタック (The Uniform Server) であり、Web サーバーは nginx を使用します。

この場合、phpMyAdmin を使用してデータベースにデータを入力すると、 phpmyadmin 内で完全に表示されます。phpMyAdmin の照合も utf-8 です。問題はこのあたりのどこかにあるに違いないと思います.同じWebサーバーのように、phpを介して(POSTを使用して)データを入力する他のサイトでは、同じ問題は発生しません. その場合、データは入力中と表示中の両方で正しく表示されますが (php で生成された Web ページを意味します)、特殊文字は phpMyAdmin で正しくありません。

どこからデバッグを開始するのを手伝ってもらえますか? phpmysqlnginx、またはphpMyAdminに接続されていますか?

4

2 に答える 2

1

mysqli::set_charset 関数を使用します。

$mysqli->set_charset('utf8'); //returns false if the encoding was not valid... won't happen

http://php.net/manual/en/mysqli.set-charset.php

私はしばらく mysqli を使用していませんが、状況が同じであれば、接続はデフォルトでラテン語のスウェーデン語エンコーディング (ISO 8859 1) を使用します。

あなたのページはすでに utf8 エンコーディングを使用していると見なします:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<head>タグの内側。

ラテン語スウェーデン語エンコーディングの文字列が既にある場合は、mk_convert_encoding を使用できます。

http://php.net/manual/en/function.mb-convert-encoding.php

$fixedStr = mb_convert_encoding($wrongStr, 'UTF-8', 'ISO-8859-1');

iconv非常によく似たことを行います: 正直なところ、違いはわかりませんが、関数リファレンスへのリンクは次のとおりです: http://php.net/manual/en/function.iconv.php

utf8 の文字列とラテン語のスウェーデン語の文字列があることに気付きました。そのために mb_detect_encoding を使用できます: http://php.net/manual/en/function.mb-detect-encoding.php

データベースがインストールされている場合は、データベースをダンプして iconv (コマンドライン) を使用することもできます。

iconv -f latain -t utf-8 < currentdb.sql > fixeddb.sql
于 2012-10-05T00:27:40.793 に答える
1

mysqli_set_charset接続直後にクライアントのエンコードを UTF-8 に変更するために使用します。

$mysqli->set_charset("utf8");

クライアント エンコーディングは、MySql が入力を予期するもの (たとえば、ユーザーが指定したテキストを検索クエリに挿入するとき) であり、結果を返すものです (したがって、echo正しく表示するには、出力エンコーディングと一致する必要があります)。 )。

上記の 2 つのシナリオとPHP ソース ファイルのエンコーディングを考慮して、Web ページのエンコーディングと一致させる必要があります (クエリのハードコーディングされた部分が正しく解釈されるようにするため)。

更新: latin-1 を使用して挿入されたデータを utf-8 に変換する方法

間違った接続エンコーディングを使用して既に挿入されたデータに関しては、問題を解決するための便利な解決策があります。この種のデータを含む列ごとに、次のことを行う必要があります。

ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET latin1;
ALTER TABLE table_name MODIFY column_name BLOB;
ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET utf8;

プレースホルダーとはtable_name、毎回データベースからの正しい値に置き換える必要があります。column_nameexisting_column_type

これが行うことは

  1. latin1 のその列にデータを格納する必要があることを MySql に伝えます。この文字セットには utf8 の小さなサブセットしか含まれていないため、一般にこの変換にはデータの損失が伴いますが、この特定のシナリオでは、データは入力時に latin1 として既に解釈されているため、副作用はありません。ただし、MySql は、最初に PHP から送信されたものと一致するように、データのバイト表現を内部的に変換します。
  2. BLOB列を、エンコード情報が関連付けられていないバイナリ型 ( ) に変換します。この時点で、列には適切な utf8 文字列である raw バイトが含まれます。
  3. 列を以前の文字型に変換し、未加工のバイトを utf8 エンコーディングと見なす必要があることを MySql に伝えます。

警告: 問題の列に誤って挿入されたデータのみが含まれている場合にのみ、この無差別なアプローチを使用できます。正しく挿入されたデータは、ASCII 以外の文字が最初に出現した時点で切り捨てられます。

したがって、PHP 側の修正が有効になる前に、今すぐ実行することをお勧めします。

于 2012-10-05T00:27:52.617 に答える