php は Unicode をサポートしていません。これは、PHP 文字列が文字のエンコード情報を保存しないことを意味します。そのため、ネイティブ操作関数は、バイナリ データがテキストにどのように対応するかを認識せず、1 つの文字がテキストに対応すると仮定することしかできません。このように、処理中に英語などの ASCII コードの場合は十分ですが、中国語などのマルチバイト文字の場合はエラーが発生します。
この記事の動作環境: Windows7 システム、PHP7.1 バージョン、DELL G3 コンピューター
これはどういう意味ですか? phpはUnicodeをサポートしていないのでしょうか? PHP は Unicode エンコーディングをサポートしていないと言われるのはなぜですか?
PHP は Unicode をサポートしていない、または PHP は最下位レベルで Unicode をサポートしていないという主張をよく見かけます。 PHP のエンコードが非常に面倒で、さまざまな文字列処理関数が非常に非標準であることは知っていますが、それでも中国語は表示できます。この情報を整理するのに時間を費やしました。
例から始めましょう:
PHP スクリプトは次のとおりです。ファイルのエンコーディングが UTF-8 であると仮定します:
//文件编码UTF-8 echo strlen("中文"); // 6 echo substr("中文",0,1) // 乱码 echo substr("中文",0,3) // 中
これは非常に奇妙です。上記では漢字1文字を3文字とみなしているようです。これは、PHP の文字列の保存から始まります。
これを次のように要約しました。
PHP の文字列はバイトの配列で構成されます。つまり、C言語のchar a[3] = "abc"と同様に、1文字が1バイトを占有します。
さらに、テキストを保存するためのエンコード情報がありません。つまり、PHP はこれらの文字列のバイナリ データがどのエンコードに対応する必要があるのかわかりません。
さらに一歩進んで、PHP はスクリプト ファイルのエンコーディングに従って文字列のエンコーディングを決定します。例: $string = " Chinese"; 、スクリプト ファイルが UTF-8 の場合、中国語 UTF-8 エンコード: E4B8ADE69687 が保存されます。
さらに、前述したように、PHP は文字列のエンコード情報を保存しません。したがって、中国語が E4B8ADE69687 として保存されたとしても、文字列ネイティブ関数から見ると、それは単なる 2 進数の文字列です。したがって、PHP ネイティブ文字列関数はシングルバイト文字でのみ操作できます。バイトを文字として扱うだけです。
上記の点を理解していれば、上記のコード例も自然に理解できるでしょう:
//文件编码UTF-8 echo bin2hex("中文"); // 可以看到,"中文"对应的二进制就是:e4b8ade69687 echo strlen("中文"); // 所以按照单字节来统计长度,就是6 echo substr("中文",0,1) // 取0到1个字节,也就是e4,并不对应某个字符的编码,所以乱码 echo substr("中文",0,3) // 取0到3个字节,刚好把`中`的编码取出来
同様に、ファイルのエンコーディングを GBK などに変更しても、さらに実験すると同様の結果が得られます。結果として、GBK の 1 つの漢字は 2 バイトを占有します。
これで、PHP の最下層が Unicode をサポートしていないことが基本的に理解できました。要約は次のとおりです:
PHP 文字列は文字のエンコーディング情報を保存しません。とてもネイティブ 操作関数は、バイナリ データがテキストにどのように対応するかを知りません。1 つの文字が 1 バイトに対応すると仮定することしかできません。英語などの ASCII コードを処理する場合はこれで十分ですが、中国語などの [マルチバイト文字] の場合はエラーが発生します。
逆に、Unicode をサポートするいわゆる基礎となる言語に注目してみましょう:
var string = "中文" console.log(string.length); // 2 string.substr(0,1) // 中
JS ではマルチバイト文字が正しく認識されることがわかります。認識され、処理されます。つまり、保存する際には、テキストのエンコード情報も保存されます。 (ここではテキストの Unicode 値が保存されていると思いますが、JS の基本原理を理解していないのでわかりません)
ここで質問があります。どうすればマルチバイトにできるのですか?文字は PHP で正しく処理されますか?答えは mbstring 拡張子です (詳細については、http://php.net/manual/zh/book.mbstring.php を参照してください)。いわゆる mbstring は、マルチバイト文字列、マルチバイト文字列です。
この拡張機能セットには、マルチバイト文字を正しく処理するために使用できる、ネイティブ文字列関数に対応する一連の関数があります。例: strlen は mb_strlen に対応します... これらの対応する関数のうち、これらは基本的にネイティブ関数と同じですが、通常は追加のオプション パラメーターであるエンコーディングがある点が異なります。
例は次のとおりです:
// 脚本类型为UTF-8 echo strlen("中文"); // 6 echo mb_strlen("中文","UTF-8"); //2 使用mb_strlen ,并传入编码 utf-8, 就会把二进制E4B8ADE69687当做utf-8的处理能正确处理 echo mb_strlen("中文"); //2 如果不传编码UTF-8,则函数会自动确定编码,文档说:如果省略,则使用内部字符编码。所以这里也当做UTF-8来处理。 echo mb_strlen("中文","GBK"); //3,如果传入编码GBK,则:e4b8ade69687会被当做gbk来处理,一个gbk字符占2字节,所以为:3
推奨される学習: 「PHP ビデオ チュートリアル 」
以上がphp が Unicode をサポートしていないというのはどういう意味ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。