PHPは内部的にどのように文字列を表しますか?


18

UTF8?
UTF16?

PHPの文字列も使用されているエンコーディングを追跡しますか?

たとえば、このスクリプトを見てみましょう。私が実行すると言う:

$original = "शक्नोम्यत्तुम्";

実際に何が起こりますか?

明らかに、$original7文字しか含まれないと思います。それらのグリフはそれぞれ、数バイトで表される必要があります。

それから私は:

$converted = mb_convert_encoding ($original , "UTF-8");

どうなり$convertedますか?とどう$converted違うの$original

それはまったく同じバイトシーケンス$originalですが、異なるエンコーディングを使用していますか?


1
PHPのどのバージョンですか?PHP <6は、ネイティブUTF-8を処理できません。ただし、この問題を解決/解決するパッケージとメソッドがあります。utf-8とphpでGoogleを楽しもう。次に、PHPではなく別のプラットフォームに切り替えます。:)
アンドリューTフィネル

4
PHP <6?これには、これまでにリリースされたPHPのすべてのバージョンが含まれます
...-tdammers

1
また、PHP UTF-8 処理できますが、専用のデータ型がないため、実行している内容を確認する必要があります。
-tdammers

回答:


22

PHP文字列はバイトシーケンスであり、タグ付けされたエンコーディングは一切ありません。文字列値は、クライアント(HTTP経由)、データベース、ファイル、またはソースコードの文字列リテラルなど、さまざまなソースから取得できます。PHPはこれらすべてをバイトシーケンスとして読み取り、エンコード情報を抽出しません。

すべてのデータソースと宛先が同じエンコーディングを使用している限り、PHPが文字ではなくバイトをカウントするため、起こりうる最悪の事態は文字列の位置が間違っていることです(マルチバイトエンコーディングを使用する場合)。

ただし、エンコードが一致しない場合(たとえば、UTF-8として保存されたソースファイルに文字列リテラルを記述し、Latin-1を予期するデータベースに送信する場合)、PHPは変換を実行しません。幸いにもraw経由でバイトをコピーします。

最も簡単な解決策は次のとおりです。

  • PHPの内部エンコーディングをUTF-8に設定します。
  • すべてのソースファイルをUTF-8として保存します。
  • 出力エンコードとしてUTF-8を使用します(適切なContent-typeヘッダーを送信することを忘れないでください)。
  • UTF-8を使用するようにデータベース接続を設定します(SET NAMES UTF8MySQLで)。
  • 可能な限り、他のすべてをUTF-8に構成します。
  • 制御できないもの(サードパーティのWebサービスなど)については、エンコードを確認し、できるだけ早くUTF-8に変換し、できるだけ遅く他のエンコードに戻します。

なぜUTF-8なのか?すべてのUnicode文字を表現できるため、既存のすべての7ビットおよび8ビットエンコーディングに取って代わり、ASCIIとバイナリ互換性があるため、つまり、すべての有効なASCII文字列は有効なUTF-8文字列でもあります(vvではありません) 。)。

あなたの例では、これが起こります。

まず、ソースファイルを保存します。テキストエディターはおそらくUTF-8を使用するように構成されているため、文字列リテラルはディスク上でエンコードされたUTF-8になります。PHPはこのファイルを読み取り、文字列を一連のバイトとして解釈します。$originalUTF-8でエンコードされた7文字の文字列を保持するようになりました。これは単なるバイトシーケンスです(ただし、各文字は2バイト以上で表されるため、7バイト以上含まれています)。次にを呼び出すecho $originalと、エンコードされた文字列がそのままクライアントに送信されます。クライアントにUTF-8を期待するように指示した場合、すべては問題ありませんが、そうでない場合、PHPは違いを伝える方法がなく、ブラウザでゴミが発生します。実験として、これを試してください:

$original = "शक्नोम्यत्तुम्";
echo strlen($original);

strlen はエンコードに依存せず、固定幅の8ビットエンコード、つまり文字ごとに1バイトを想定しているため、文字ではなくバイトをカウントします。


したがって、$ convertedは同じ文字列を表しますが、他のエンコーディングを使用します。実際の生のエンコードは、PhPが保存するものとは異なります。
user4951

2
私はあなたのためにそれを繰り返します:PHPは文字ではなくバイトを保存し、エンコーディングについてはまったく知りません(ただし、いくつかのライブラリ関数は
保存

1
ああ、それは「PhP」ではなく「PHP」です。
-tdammers

2
生のバイトが同じ場合、$ originalと$ convertedの違いは何ですか。これが私が求めていることです。
user4951

2
ああ、それはあなたが言うことです。はい、生のバイトはエンコード変換に従って変化します。PHPはエンコーディングを記憶していません。したがって、たとえばutf-8からlatin-1に文字列を変換し、その結果をutf-8として扱うと、奇妙な結果が表示されます。
-tdammers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.