Oracle、PHP、Oci8 を使用した eacute およびその他の特殊文字の処理
-
23-09-2019 - |
質問
こんにちは、Oracle データベースに名前を保存し、PHP と oci8 を使用してそれらを取得しようとしています。
ただし、 é
Oracle データベースに直接アクセスし、oci8 を使用してそれをフェッチバックします。 e
すべての特殊文字 (含む) をエンコードする必要がありますか? é
) を HTML エンティティに変換します (つまり: é
) データベースに挿入する前に ...それとも何かが足りないのでしょうか?
THX
アップデート:3月1日 18:40
この関数を見つけました:http://www.php.net/manual/en/function.utf8-decode.php#85034
function charset_decode_utf_8($string) {
if(@!ereg("[\200-\237]",$string) && @!ereg("[\241-\377]",$string)) {
return $string;
}
$string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e","'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",$string);
$string = preg_replace("/([\300-\337])([\200-\277])/e","'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'",$string);
return $string;
}
うまくいくようですが、最適な解決策かどうかはわかりません
アップデート:3月8日15時45分
Oracle の文字セットは ISO-8859-1 です。
PHP で次のように追加しました。
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1");
oci8 接続でその文字セットを使用するように強制します。を取得する é
PHP から oci8 を使用すると機能するようになりました。(のために varchars
, 、 だがしかし CLOBs
しなければならなかった utf8_encode
それを抽出します)
それで、PHPからOracleにデータを保存しようとしました...そしてそれは機能しません..PHPからOracleへの途中のどこかで、 é
になる ?
アップデート:3月9日14時47分
ということで近づいてきました。NLS_LANG 変数を追加した後、次のコマンドを使用して直接 oci8 挿入を実行します。 é
動作します。
実は問題はPHP側にあります。ExtJs フレームワークを使用すると、フォームを送信するときに次を使用してエンコードされます。 encodeURIComponent
.
それで é
として送信されます %C3%A9
そして再エンコードされて é
.
でも今の長さは 2 (strlen($my_sent_value) = 2)
そして1ではありません。そして、PHP で試してみると、次のようになります。$my_sent_value == é
= 間違い
PHP でこれらすべての文字をバイト サイズ 1 の長さに再エンコードして、Oracle に挿入できれば、うまくいくはずです。
まだ運が悪いけど
アップデート:3月10日 11:05
自分はとても近い(遠い)と思い続けています。
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
非常に散発的に動作します。
テストするための小さな php スクリプトを作成しました。
header('Content-Type: text/plain; charset=ISO-8859-1');
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
$conn= oci_connect("user", "pass", "DB");
$stmt = oci_parse($conn, "UPDATE temp_tb SET string_field = '|é|'");
oci_execute($stmt, OCI_COMMIT_ON_SUCCESS);
これを一度実行してOracle Databaseに直接ログインすると、STRING_FIELDが次のように設定されていることがわかります。 |¿|
. 。明らかに、私が以前の経験から期待していたものではありませんでした。
ただし、その PHP ページをすばやく 2 回更新すると...出来た !!!
Oracleでは正しく見ました |é|
.
おそらく環境変数が正しく設定されていないか、スクリプトの最初の実行に間に合うように送信されていないようですが、2 回目の実行では使用可能です。
次の実験は変数を PHP 環境にエクスポートすることですが、そのためには Apache をリセットする必要があります...それで何が起こるか見てみましょう。うまくいけばうまくいきます。
解決 2
これは私が最終的にこの問題を解決するためにやってしまったものです。
持つようにPHPを実行しているデーモンのプロフィールを修正
NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
OCI8接続がISO-8859-1を使用していますので、ます。
そして、私のPHPの設定でISO-8859-1にデフォルトのコンテンツタイプを設定します:
default_charset = "iso-8859-1"
私はPHPからOCI8経由のOracle表に挿入していたとき、私はます:
utf8_decode($my_sent_value)
また、Oracleからデータを受信したときに、変数を印刷するだけのように動作するはずます:
echo $my_received_value
しかし、私が使用しなければならなかったAJAXを介してそのデータを送信するときます:
utf8_encode($my_received_value)
他のヒント
皆さんは次の事実をご存知かと思います。
- さまざまな文字セットがあります。どちらかを選択する必要があり、もちろん、どれを使用しているかを把握する必要があります。
- Oracle は、HTML エンティティなしでテキストを完全に保存できます (
é
)。HTML エンティティは、HTML で使用されます。Oracle は Web ブラウザではありません ;-)
また、HTML エンティティは特定の文字セットにバインドされていないことも知っておく必要があります。逆に、文字セットに依存しないコンテキストで文字を表すために使用されます。
ISO-8859-1 と UTF-8 について漠然と話しています。どの文字セットを使用したいですか?ISO-8859-1 は使いやすいですが、一部のラテン語 (スペイン語など) のテキストしか保存できず、€ 記号などの一般的な文字がいくつかありません。UTF-8 は使用するのが難しいですが、Unicode コンソーシアムによって定義されたすべての文字 (必要なものすべてが含まれます) を保存できます。
決定したら、そのような文字セットでデータを保持し、適切な列タイプを選択するように Oracle を構成する必要があります。たとえば、VARCHAR2 はプレーン ASCII に適しており、NVARCHAR2 は UTF-8 に適しています。
あなたが本当にOracleがどのようにBase64では、データベースに格納する前にデータを符号化については、次に使用することを文字セットを変更できない場合。その方法は、あなたが任意の文字セットの文字を受け入れ、ISO-8859-1として保存することができます(理由のBase64意志出力ISO-8859-1に正確にマップするASCII文字セットのサブセット)。 Base64エンコードは、平均で、37%
で文字列の長さを増加させます あなたのデータは唯一のこれまでのHTMLとして表示されようとしている場合は、あなたは同様にあなたが示唆したようにHTMLエンティティを格納しますが、単一のエンティティは、例えば、最大符号化されていない文字あたり10文字になることがあるので注意してくださいかもしれませんθであるϑ
私はこの問題に直面しなければならなかった:LatinAmerican特殊文字は次のように保存されています「?」または「¿」私たちは、データベースの所有者ではないだから私のOracleデータベースに...私はNLS_CHARACTER_SETを変更することはできません。
だから、私は回避策を見つけます:
1)ASP.NETコード 機能を作成することを16進文字に変換する文字列:
public string ConvertirStringAHex(String input)
{
Encoding encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
Byte[] stringBytes = encoding.GetBytes(input);
StringBuilder sbBytes = new StringBuilder(stringBytes.Length);
foreach (byte b in stringBytes)
{
sbBytes.AppendFormat("{0:X2}", b);
}
return sbBytes.ToString();
}
2)この
のように、あなたがエンコードしたい変数に上記の関数を適用します myVariableHex = ConvertirStringZHex( myVariable );
はでORACLEは、以下を使用します
PROCEDURE STORE_IN_TABLE( iTEXTO IN VARCHAR2 )
IS
BEGIN
INSERT INTO myTable( SPECIAL_TEXT )
VALUES ( UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW( iTEXTO ));
COMMIT;
END;
もちろん、iTEXTOは、ASP.NETコードから "myVariableHex" の値を受信するOracleパラメータである。
ホープは役立ちます...あなたのコメントを投稿することを躊躇しないplsはを改善するための何かがあるかどうます。
ソース: のhttp:/ /www.nullskull.com/faq/834/convert-string-to-hex-and-hex-to-string-in-net.aspxする https://forums.oracle.com/thread/44799する