PHP、MSSQL2005、およびコードページ
-
19-08-2019 - |
質問
MSSQL2005データベースにアクセスし、そこからデータを読み取り、結果をメールで送信するphpスクリプトがあります。
一部の列名とフィールド自体の両方に特殊文字があります。
ブラウザ(Webサーバーiis)からスクリプトにアクセスすると、クエリが正しく実行され、メールの内容が(対象ユーザー向けに)正しくエンコードされます。 ただし、コンソールからphpを実行すると、クエリは失敗します(列名の特殊文字のため)。クエリの特殊文字をchr()の呼び出しとlatin-1の文字コードに置き換えると、クエリは正しく実行されますが、結果もlatin-1でエンコードされるため、メールに正しく表示されません。 なぜPHP / MSSQLドライバー/ <!>#8230; 2つのシナリオで異なるエンコードを使用していますか?それを回避する方法はありますか?
不思議な場合は、SQLAgent(またはtaskmanagerなど)を使用してスクリプトをスケジュールするため、コンソールが必要です。
解決
データベースにある文字の種類によっては、コンソールの制限かもしれません。コンソールでchcp
と入力すると、アクティブなコードページが表示されます。これは、 CP437 は拡張ASCIIとも呼ばれます。 UTF8のように、このコードページに文字が含まれている場合、問題が発生する可能性があります。 chcp 65001
を入力してUTF8に切り替えると、現在アクティブなコードページを変更できます。
すべてのフォントが拡張文字をサポートしているわけではないため、必要な文字に応じてデフォルトのラスターフォントをLucida Consoleに変更することもできます(コマンドプロンプトウィンドウのタイトル、プロパティ、フォントを右クリックします)。
すでに述べたように、PHPのUnicodeサポートは理想的ではありませんが、 utf8_decode 。文字エンコーディングの秘密は、使用しているツールの現在のエンコーディングが何であるかをよく理解することです:データベース、データベース接続、PHP変数の現在のバイト、コンソール画面への出力、メールボディエンコーディング、メールクライアントなど...
現代では、特殊文字を含むすべてのものに対して、UTF8のようなものがしばしば推奨されます。途中のすべてがUTF8に設定されていることを確認し、必要な場合にのみ変換します。
他のヒント
英語以外の世界に対するPHPの不十分なサポートはよく知られています。基本的なASCII領域外の文字を含むデータベースを使用したことはありませんが、明らかに回避策があり、そのまま使用する必要があるようです。
さらに一歩進めたい場合は、次のことができます。 1.すべての特殊文字とそれに相当するCHRを含む配列を作成します 2.配列のforeachとクエリのstr_replace
しかし、クエリがハードコーディングされている場合、あなたが持っているものは大丈夫だと思います。また、少なくとも4.4.xの最新のPHPを使用していることを確認してください。これは常に修正されていますが、4.x.xのリリースノートをざっと読みましたが、問題に関連するものは見当たりません。
PHP文字列について覚えておくべきことは、それらがバイトストリームであることです。正しい文字セットでデータを取得したい場合(何をしている場合でも)、何らかの関数またはフィルターを使用して明示的にこれを行う必要があります。すべてかなり低レベルです。
設定によっては、データベース内の文字列の内部文字セットを知る必要があるかもしれませんが、少なくともデータベースがPHPに送信している文字セットを知る必要があります(PHPにはバイトのストリーム)。
次に、ターゲットの文字セットを知る必要があります(そして、おそらくそれを指定する必要があります。たとえば、データベースからutf-8を取得しているが、latin-1(したがって、 'Content-transfer-encoding'としてエンコードされたbase64またはq-printable)を送信したいとします。
$send_string = base64_encode(utf8_decode($database_string));
もちろん、この場合、すべてのutf-8文字がlatin-1文字セットに存在することを知っておく必要があり、おそらくbase64は本当に必要ないでしょう(残念ながらPHPには良いq-不思議なことに、印刷可能なエンコード関数)、それはデコードのために行います)、そしてあなたがutf-8について話していなければ<!> lt; = <!> gt; latin-1の場合は、代わりにmbstring関数を作成する必要があります。
コンソールに関しては、コンソールから特殊文字を入力しているときにPHPが何を取得しているかを知る必要がありますが、これはおそらくシェルやPHPの設定に依存します。ただし、PHPは文字列をバイトバイトバイトとしてしか認識しないため、うまく処理できるはずです。