12

シリアル化して MySql データベースに保存したい大きな php オブジェクトがあります。テーブルのエンコーディングはUTF-8で、シリアル化されたオブジェクトのエンコーディングを保持する列もUTF-8です。

問題は、オブジェクトがフランス語の文字を含むテキスト文字列を保持していることです。

例えば:

Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande 

オブジェクトをシリアル化してから再度シリアル化を解除すると、文字列が維持され、正しい形式になります。

ただし、シリアル化されたオブジェクトを MySql データベースに保存し、再度取得してからシリアル化を解除すると、文字列は次のようになります。

Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande 

オブジェクトをデータベースに保存すると、何か問題が発生します。

ノート:

  • オブジェクトは propel ORM を使用して保存されます。
  • 列タイプはtext.
  • 文字列が保存され、html ファイルから読み取られます。
4

4 に答える 4

16

によって作成される文字serialize列はバイナリ文字列であり、特定の文字セット エンコーディングはありませんが、単なるバイトの「配列」です (1 バイトは 8 ビット、つまりオクテットです)。

このような文字列を取得し、それが LATIN-1 エンコードされていることをデータベースに伝え、データベースがそれを UTF-8 エンコードでテキスト フィールドに格納すると、データベースは透過的にエンコードを LATIN-1 から UTF-8 に変更します。UTF-8 は、一部の文字 (たとえば、質問でé.

文字はデータベース内にé格納されます。これは、 の UTF-8 バイトシーケンスです。éé

必要なエンコーディングを指定せずにデータベースからデータをフェッチすると、データベースはデータを UTF-8 として返します。

unserializeバイナリ文字列が無効になるように変更されたため、問題が発生しました。

代わりに、シリアル化された文字列を格納するときにエンコーディングを変更しないようにデータベースに指示する必要があります。たとえば、適切な列タイプとエンコーディング (バイナリ フィールド、BLOB - Binary Large Object MySQL Docs 、 Binary Types Propel Docs参照) を選択します。 ) - または - データベースからデータを取得するときに、文字セットのエンコードを元の形式に戻します。最初のアプローチ (バイナリ フィールド) は、まさに探しているものであるため、優れています。

間違った形式でデータベースに既に格納されているデータについては、データを修正する必要があります。これを行うには、最初に、どの文字セットからどの文字セットへなど、どの再エンコードが適用されたかを調べる必要があります。LATIN-1 だと思いますが、保証はありません。確認するには、現在のアプリケーション データとプロセスのエンコーディングを確認する必要があります。

確認したら、値を UTF-8 から元のエンコーディングに戻します。

于 2012-02-02T09:10:10.147 に答える
5

どこでもutf-8 を使用するようにしてください - 何かを見逃したようです。

SET NAMESあなたの場合、(ステートメントまたはmysql_set_charset()を使用して)データベース接続に正しい文字セットを設定するのを忘れたと思います-しかし、それはあなたのコードを見ずに言うのは難しいです(そして私は推進力を知りません)。

以下は、完全にUTF-8で答えたchazomaticusからの引用であり、注意が必要なすべてのポイントをリストしています。

保管所:

  • データベース内のすべてのテーブルとテキスト列で (または同等の) 照合順序を指定utf8_unicode_ciします。これにより、MySQL は UTF-8 でネイティブに値を物理的に格納および取得します。

検索:

  • PHP では、どの DB ラッパーを使用する場合でも、接続文字セットを utf8 に設定する必要があります。このように、MySQL はデータを PHP に渡すときにネイティブ UTF-8 からの変換を行いません。* DB ラッパーを使用しない場合は、クエリを発行して MySQL に結果を UTF-8 で返すように指示する必要があることに注意してください: SET NAMES 'utf8' (接続直後)。

配達:

  • 適切なヘッダーをクライアントに配信するように PHP に指示する必要があるため、テキストは UTF-8 として解釈されます。PHP では、php.ini オプションを使用するdefault_charset か、ヘッダーを自分で手動で発行でき Content-Typeます。これは手間がかかりますが、同じ効果があります。

提出:

  • ブラウザから送信されるすべてのデータを UTF-8 にする必要があります。残念ながら、これを確実に行う唯一の方法は、 すべてのタグにaccept-charset属性を 追加することです: .<form><form ... accept-charset="UTF-8">
  • W3C HTML 仕様では、クライアントはデフォルトで、サーバーが提供する文字セットでフォームをサーバーに返すように「すべき」であると述べていますが、これは明らかに推奨事項にすぎないため、すべての<form>タグで明示的に指定する必要があります。
  • ただし、その点では、送信されたすべての文字列が有効な UTF-8 であることを確認してから、保存または使用する必要があります。PHP mb_check_encoding()はこのトリックを実行しますが、宗教的に使用する必要があります。

処理:

  • 残念ながら、これは難しい部分です。UTF-8 文字列を処理するたびに、安全に処理する必要があります。mbstringこれを行う最も簡単な方法は、PHP の拡張機能を多用することです。
  • PHP の文字列操作は、デフォルトでは UTF-8 セーフではありません。通常の PHP 文字列操作 (連結など) で安全に実行できることがいくつかありますが、ほとんどの場合、同等のmbstring関数を使用する必要があります。
  • 自分が何をしているのかを知るには (読んでください: めちゃくちゃにしないでください)、UTF-8 とそれが可能な限り低いレベルでどのように機能するかを知る必要があります。utf8.comのリンクをチェックして、知っておくべきことをすべて学ぶための優れたリソースを確認してください。
  • また、明らかなように思われるかもしれませんが、これはどこかで言われるべきだと思います。提供するすべての PHP または HTML ファイルは、有効な UTF-8 でエンコードする必要があります。

utf-8 を使用する必要がないことに注意してください。重要な部分は、どの文字セットであるかに関係なく、どこでも同じ文字セットを使用することです。とにかく何かを変更する必要がある場合は、utf-8 を使用してください。

于 2012-02-02T08:31:58.537 に答える
2

を使用して、常に esrialized データを保存していbase64_encode()ます。シリアル化されたデータが問題を引き起こすことがありますが、その base64 値を使用すると、単純な文字だけが残ります。

于 2012-02-02T08:33:32.127 に答える