6

ソース コードを分析するツールを作成します。このようなツールは、特に文字エンコーディングに関して、ソース コード ファイルを正しく読み取る必要があります。たとえば、「文字列リテラルの正確なバイト文字列は何ですか?」(PHP リテラルと HTML テキストの両方)。

私のおそらく間違った理解は、PHP ソース ファイルは 8 ビット文字のみであるということです (つまり、PHP エンジンは、8 ビット文字のみを含むと想定されているため、そのように読み取ります [正しい]?)。しかし、どのエンコーディングの 8 ビット文字ですか? (私は、ISO-8859-1 (-x?) に一致させることを意図していると思います [誰かが章と節を引用できますか?]。つまり、ウムラウトはウムラウトであることを意図していますよね? これに続いて、HTML で PHP スクリプトを書くことができます。ほとんどのヨーロッパの国/文字セットの文字列を簡単に。

しかし、これが Unicode の問題であることは明らかです。私が知る限り、ほとんどの PHP アプリケーションは基本的に、8 ビットの PHP 文字列に挿入できる UTF-8 バイト シーケンスを含む文字列を使用して Unicode を処理します。これに続いて、サーバーに UTF-8 テキストを生成していることを伝えれば、HTML に Unicode UTF-8 シーケンスが含まれるスクリプトを生成できます。

上記の状況では、PHP ファイルを 8 ビットの文字テキストとして読み取ることができ、これは言語と一致するように思えます。

私が困惑しているのは、UTF-8 としてエンコードされた PHP ソース ファイルです (Joomla パッケージには約 1800 のソース ファイルがあり、そのうちの 10 は UTF-8 で、残りはそうではありません)。UTF-8 レンダリングで正しく表示される (非 ASCII) ヨーロッパ文字は、実際にはマルチバイト シーケンスとしてエンコードされます。UTF-8 として提供されるページは、HTML が正しくレンダリングされると思います。しかし、ヨーロッパ文字やその他の Unicode 文字の文字列比較は、テキスト エディターで正しく表示されるようで、まったく機能しません。また、文字列リテラルには、含まれているように見えるものが含まれません。エディターが提供しているため、プログラマーは UTF-8 ファイルを使用しますか? 彼らは意図的にこれを行っていますか?それとも、ほとんどの仕事に関係のない単なる事故ですか?

では、PHP ソースファイルはどのように読めばよいのでしょうか? (具体的には、どの文字エンコーディングでしょうか?) 考えられる答えの 1 つは、実際のコンテンツや BOM に関係なく、常に ISO-8859-1 8 ビット コードとして使用することです (多くの UTF-8 BOM マーク付き PHP ファイルを目にします)。別の答えは、そのようにマークされている場合、UTF-8 です。

[私たちのツールは、任意のエンコーディングを読み書きします。「些細な」ツールは、1文字のエンコーディングでファイルを読み取り、別のエンコーディングで同一のコードポイントを書き込みます。多くの UTF-8 コード ポイント (ユーロ記号など) は ISO8859-x でエンコードできないため、UTF-8 PHP ファイルをそのように読み取ると、ISO8859-1 と同等のファイルを書き込む際に問題が発生します。]

8 月 30 日編集: PHP ファイルをチェックして、UTF-8 BOM があるかどうか、またはすべて合法な UTF-8 シーケンスがあるように見えるかどうかを確認します。どちらの場合も、ファイルを UTF-8 として読み取ります。それ以外の場合は、デフォルトで ISO8859-1 として読み取ります。ファイルのエンコーディングを変更しても保持されるようになりました。(これをすべて正しく行うには、かなりの作業が必要です)。これは安全な戦略のように見えますが、PHP プログラマーが期待しているものとは異なる可能性があります。

4

3 に答える 3

9

何度も繰り返しますが、PHP ファイルには x7f を超えるバイトのエンコーディングはありません。x00 から x7f までのバイトが ASCII であることがわかります。

先頭に BOM マーカーがあるファイルは有効な PHP ではありません。したがって、iso-8859-1 または utf-8 の PHP ファイルのようなものはありません。プレーンな 8 ビットです。

PHP ファイルは iso-8859-x ではありません。これらのエンコーディングには可能なすべてのバイト値が含まれているわけではないからです。ご存じのとおり、x7f から x9f は iso-8859-1 では有効ではありませんが、どの PHP ファイルにもそれらを含めることができます。

PHP ファイルも utf-8 ではありません。これは、無効ではなく、無効な utf-8 シーケンスが含まれている可能性があるためです。

大きな絵

執筆時の慣習による文字セット

PHP ファイルは慣例によりエンコーディングを持つことができますが、これはプログラマーの裁量に任されています。彼は編集者に、そのようなプロジェクトは utf-8 や iso-8859-1 などであると伝えます。

しかし、繰り返しますが、これはプログラマーの慣例にすぎません。彼の編集者は、あたかもこれがエンコードされているかのように、PHP ファイルを脅かしています。エンコーディングは、エディターでファイルを表示する目的を果たしているだけで、プログラマーがファイルを編集できるようにします。

コンパイル中に文字セットがありません

上で説明したように、コンパイラーは、プログラマーが想定したエンコーディングを知る必要はありません。重要なのは、ファイル内のバイト シーケンスが何であるかだけです。

消費時に定義された暗黙的または明示的な文字セット

PHP は、インターネット経由でブラウザに送信されるデータを生成します。ブラウザがデータを表示する時点で、エンコーディングは明確に定義されていますが、どのように?

  • エンコーディングは、次のように HTTP ヘッダーで定義できます。Content-Type: text/html; charset=utf-8
  • HTML 出力自体で定義できます。<meta charset="utf-8">
  • または、文字セットが明示的に定義されていない場合、ブラウザーはドキュメントに存在するバイト シーケンス (有効な utf-8 シーケンスまたは BOM など) に応じて、知識に基づいた推測を行います。

もちろん、PHP アプリケーションでブラウザーに選択させないのは良い習慣ですが、エンコーディングをどこかに定義する必要はありません。

詳細

通常、プログラマーが選択するエンコーディングは、ブラウザのチェーンの最後で使用されるエンコーディングと同じであり、PHP ファイル内のすべての文字列はこの同じエンコーディングを使用します。

しかし、そうである必要はありません。これが当てはまらない正当な理由があります。例を見てみましょう:

異なる言語、異なるエンコーディング

バージョン 1.0 の Joomla を使用しています。このバージョンでは、言語ファイルにはそれぞれ独自のエンコーディングがありました。フランス語のファイルは iso-8859-1 で、アラブのファイルは windows-1256 で、ロシア語のファイルは koi8-r でした。これらのエンコーディングは重要でしたが、utf-8 または iso-5598-1 として同等に扱うことができる他のすべてのファイルでは重要ではありませんでした。(その間、Joomla は utf-8 に切り替えました。)

異種データベース

私たちの Web アプリケーションの 1 つは 2 つの異なるデータベースに接続します。1 つはたまたま utf-8 にあり、もう 1 つは windows-1252 にあります。これは、このプロジェクトのすべての文字列が同じエンコーディングではないことを意味します。mb_*私は可能な限り utf-8 を使用しますが、PHP の一連の関数を使用してエンコーディングを前後にタンスレートする必要があります。

PHPの変換関数

エンコーディング変換関数mb_convert_encodingiconvutf8_encodeなどの存在は、同じプロジェクト文字列に異なるエンコーディングが存在する可能性があることを示唆しています。

いい練習

エンコーディングを定義し、それに固執してください! 最良の選択は、utf-8 の使用です。他のエンコーディングの他の文字列が必要な場合は、いつでも次のように書くことができます$s=mb_convert_encoding('Уровень','ucs-2','utf8');

繰り返しますが、PHP では BOM マーカーを使用できません。理由は簡単です。BOM マーカーは、開始タグの前に 2 バイトあります<?php。したがって、それらはブラウザに送信されます。header()その後にを送信しようとすると、エラーが発生し、ヘッダーは送信されません。

結論

  • 通常、PHP ファイルのエンコーディングを決定する必要はありません。最終的にレンダリングされた HTML ファイルのエンコーディングだけが重要です。
  • 最終結果の表示に使用されるのと同じエンコーディングですべてのファイルを編集することをお勧めします。しかし、それは言語ファイルにとってのみ重要です (i18n のシステムを使用している場合)。
  • 実際には、1 つのファイル内のすべての文字列は同じエンコーディングですが、悪意のあるプログラマーが同じファイル内に異なるエンコーディングで文字列を書き込んでも、動作するプログラムを取得することはできません。

最後に、PHP でのエンコーディングは、執筆時に使用される規則と、ページをレンダリングするためにブラウザーで使用される文字セットの問題にすぎません。その間、PHP ファイルには特定のエンコーディングがなく、単純な 8 ビットです。

于 2013-09-07T21:16:54.107 に答える
3

PHP ソースファイルのエンコーディングを確実に伝える方法は実際にはありません。本当に何でもありです。ご存じのように、唯一の一般的な識別子は BOM ですが、出力時に問題が発生する可能性があるため、ほとんどの人はソース ファイルから BOM を削除します。

これに対処する方法は、何をしたいかによって異なります。Content-type通常、PHP ファイルはヘッダーを送信するなどしてエンコーディング自体を宣言するため (または、特定のエンコーディングを使用することが慣例となっているプロジェクトの一部であるなどの理由で、暗黙的に定義されているため) 問題になりません。エンコーディングの問題は、ファイルが実行時にそれ自体を整理するため、実際には発生しません。

PHP ソース ファイルを何らかの形式で操作または分析するツールを構築している場合、エンコーディングはそれほど重要ではない可能性がありますが、それを評価するには、状況について詳しく知る必要があります。

ほとんどの IDE がこの不確実性に対処する方法は、プロジェクト、フォルダー、および/またはファイルがどのエンコーディングに含まれているかを開発者に手動で指定するように依頼することです。おそらく、それもオプションです。

于 2013-08-31T19:03:54.737 に答える