まず、ó や î のような分音符号を持つ文字 (あなたの例から) は、自動的に「utf-8 文字」ではないことを理解する必要があります。基本的なシングルバイト ASCII 部分 (つまり、英語のアルファベット、数字、最も一般的な句読点、およびさらにいくつかの)。「問題のある文字」と呼ぶことはできますが、「utf-8 文字」とは言えません。
したがって、フッターを書いたとき、<div>
UTF-8 エンコードされたものではありませんでした。エディターは、これらの文字をISO 8859-1またはその関連の 1 つなどのシングルバイト エンコーディングで保存しました。
ブラウザは通常、指定されていない場合、ページで使用されているエンコーディングを自動的に検出します。これが、エディタで書いたものを正確にブラウザで最初に見ることができた理由です。
次に、ユーザー名に「問題のある文字」を使用してログインしようとしました。ブラウザーはページをシングルバイト エンコーディングとして解釈したため、フォーム入力を同じ方法でエンコードし、シングルバイト エンコードしてサーバーに送り返しました。PHP コードは、この可能性を念頭に置いて作成されていなかったようですhtmlspecialchars()
。これは"UTF-8"
、デフォルトである の 3 番目のパラメータが正しく設定されていなかったためです (PHP 5.4.0 以降 - それ"ISO-8859-1"
以前)。「問題のある文字」を含むシングルバイトでエンコードされた文字列が有効な UTF-8 文字列になることはほとんどないため (質問に対する私のコメントを参照してください。2 番目のコメントです)、 htmlspecialchars() はそれを拒否しました。
header('Content-Type: text/html; charset=utf-8');
次に、ブラウザによる自動文字セット検出を無効にするを正しく追加しました。この時点で、フッターを含むファイル<div>
が UTF-8 でエンコードされていないことが明らかになりました (「問題のある文字」の代わりに表示される疑問符の説明については、私のコメントをもう一度参照してください)。
あとは、編集者に UTF-8 でエンコードされたファイルを保存するよう説得するだけです。他の人が指摘したように、ファイルを別のエンコーディングで保存しても、すべてのエディターで機能するとは限りません。エディターのデフォルトのエンコーディングを UTF-8 に設定した後など、新しいファイルから開始することが解決策になる場合があります。
file
エンコーディングを確認するには、シェルでコマンドを使用できます。その出力は次のようになります
main.php: PHP script, UTF-8 Unicode text
またはod -tx1z
、ファイル (おそらく| less
) をダンプするコマンドを、対応する文字列を横に並べた 16 進バイトのシーケンスとして使用することもできます。ファイルがシングルバイトでエンコードされている場合、「問題のある文字」はシングルバイト >= 0x80 になります。UTF-8 でエンコードされている場合、それらは 2 バイトのシーケンス (その他は 3 バイト以上) で、すべて >= 0x80 ですが、「問題のない文字」は 0x80 未満の単一バイトのままです。
あなたが言及した記事はよく書かれているようです。それに従ってください。
ただし、すべてのページがHTTP ヘッダーで生成されている場合AddDefaultCharset
は、ファイルにディレクティブは必要ありません。これは、Apache ディレクティブの効果がまったく同じであるためです (また、PHP 内でエンコーディングを制御することをお勧めします)。.htaccess
Content-Type: text/html; charset=utf-8
を追加する<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
と、ブラウザーに対して、上記の HTTP ヘッダーと同じ効果があります (http- equivに注意してください)。HTTP ヘッダーはよりクリーンですが、この追加のメタ タグは、ページがヘッダーの情報なしで保存された場合に役立ちます。
最も重要なことは、 UTF-8を恐れないことです。これはあなたの友達だからです!
(...しかし、あなたの報奨金を得た答えから、あなたは多くの人と同じように、文字エンコーディングを理解することはあなたにとって難しすぎると考え続けていることがわかります☹)