1. ホーム
  2. php

[解決済み] ずっとUTF-8

2022-03-19 13:02:45

質問

新しいサーバーを立ち上げ、WebアプリケーションでUTF-8を完全にサポートしたいと考えています。過去に既存のサーバーでこれを試したことがありますが、いつもISO-8859-1にフォールバックする必要があるようです。

エンコーディング/シャーセットは具体的にどこに設定すればよいのでしょうか?Apache、MySQL、PHPを設定する必要があることは承知していますが、何か標準的なチェックリストがあるのでしょうか?

これは新しい Linux サーバーで、MySQL 5、PHP 5、Apache 2 を実行しています。

解決方法は?

データ保存 :

  • を指定します。 utf8mb4 文字セットは、データベースのすべてのテーブルとテキストカラムに設定されます。 これにより、MySQL は UTF-8 でネイティブにエンコードされた値を物理的に保存および取得することができます。 MySQL は暗黙のうちに utf8mb4 エンコーディングは utf8mb4_* 照合順序が指定されます (明示的なキャラクタセットなし)。

  • MySQL の古いバージョン (< 5.5.3) では、残念ながら、単に utf8 これは、Unicode 文字のサブセットしかサポートしていません。 冗談であってほしいのですが。

データアクセス :

  • アプリケーションのコード(PHPなど)の中で、どのようなDBアクセス方法を使うにしても、接続文字セットを utf8mb4 . この方法では、MySQL はデータをアプリケーションに渡すときにネイティブの UTF-8 から変換することはなく、その逆も同様です。

  • ドライバによっては、接続文字セットを設定する独自のメカニズムを提供し、ドライバ自身の内部状態を更新するとともに、接続で使用されるエンコーディングを MySQL に通知するものがあります。 PHP では

    • を使用している場合は PDO 抽象化レイヤーを PHP ≥ 5.3.6 で使用する場合、以下のように指定します。 charset の中に DSN :

       $dbh = new PDO('mysql:charset=utf8mb4');
      
      
    • を使用している場合 mysqli を呼び出すことができます。 set_charset() :

        $mysqli->set_charset('utf8mb4');       // object oriented style
        mysqli_set_charset($link, 'utf8mb4');  // procedural style
      
      
    • もし、プレーンな マイスル が、PHP ≥ 5.2.3 で動作している場合、以下のように呼び出すことができます。 mysql_set_charset .

  • ドライバが接続文字セットを設定する独自のメカニズムを提供しない場合、アプリケーションが接続上のデータをどのようにエンコードすることを期待しているかを MySQL に伝えるためにクエリを発行しなければならない場合があります。 SET NAMES 'utf8mb4' .

  • についても同様の配慮が必要です。 utf8mb4 / utf8 が適用されます。

出力 :

  • アプリケーションが他のシステムにテキストを送信する場合、他のシステムにも文字エンコーディングを通知する必要があります。 ウェブアプリケーションでは、ブラウザにデータ送信時のエンコーディングを通知する必要があります(HTTPレスポンスヘッダや HTMLメタデータ ).

  • PHPでは default_charset php.ini のオプションで指定するか、手動で Content-Type MIMEヘッダを自分で設定するのは、手間はかかりますが、同じ効果があります。

  • を使用して出力をエンコードする場合 json_encode() を追加します。 JSON_UNESCAPED_UNICODE を2番目のパラメータとして指定します。

入力 :

  • 残念ながら、受信した文字列をどこかに保存したり使用したりする前に、その文字列が有効なUTF-8であるかどうかを確認する必要があります。 PHP の mb_check_encoding() を使えばいいのですが、それを忠実に実行する必要があります。 悪意のあるクライアントが好きなエンコーディングでデータを送信できるため、これを回避する方法は本当にありませんし、PHPが確実にこれを行うためのトリックも見つかっていません。

  • 私が読んだ限りでは、現在の HTML仕様 以下のサブ・ブレットは、現代のHTMLでは必要ありませんし、もはや有効でさえありません。 私の理解では、ブラウザは文書に指定された文字セットで動作し、データを送信します。 しかし、古いバージョンのHTML(XHTML、HTML4など)を対象にしている場合、これらの点はまだ役に立つかもしれません。

    • HTML5以前のHTMLの場合のみ : ブラウザから送られてくるデータをすべて UTF-8 にしたい場合。 残念ながら、これを確実に実行する唯一の方法として accept-charset 属性は、すべての <form> タグを使用します。 <form ... accept-charset="UTF-8"> .
    • HTML5以前のHTML専用 W3C HTML 仕様では、クライアントはサーバーが提供するどのような文字セットでもデフォルトでサーバーにフォームを送信するようにすべきであるとされていますが、これはどうやら推奨に過ぎないようで、したがって、すべての <form> タグを使用します。

その他のコードに関する考察 :

  • 当然のことながら、提供するすべてのファイル(PHP、HTML、JavaScriptなど)は、有効なUTF-8でエンコードされている必要があります。

  • UTF-8文字列を処理するたびに、安全に処理できるようにする必要があります。 これは残念ながら、難しい部分です。 おそらく、PHP の mbstring という拡張機能があります。

  • PHP の組み込みの文字列演算は ではない はデフォルトで UTF-8 セーフです。 PHP の通常の文字列操作で安全にできること (連結など) もありますが、たいていの場合はそれに相当する mbstring 関数を使用します。

  • 自分が何をしているのかを知るために(つまり、台無しにしないために)、UTF-8とそれがどのように動作するのかを可能な限り低いレベルで知ることが本当に必要なのです。 以下のリンクのいずれかをチェックしてみてください。 utf8.com には、必要なことをすべて学べる良い資料があります。