5

こんにちは、名前を Oracle データベースに保存し、PHP と oci8 を使用してそれらを取得しようとしています。

ただし、éOracle データベースに直接挿入し、oci8 を使用してそれを取得すると、e

データベースに挿入する前に、すべての特殊文字 ( を含むé) を html エンティティ (つまり: ) にエンコードする必要がありますか? それとも何か不足していますか?é

どうも


更新: 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 からの using oci8 の取得が機能するようになりました! (のために、しかしそれを抽出する必要はありませんでした)それでvarchars、 PHPからOracleにデータを保存しようとしました...そしてそれはうまくいきません..PHPからOracleへの途中のどこかでCLOBsutf8_encode
é?


更新: 3 月 9 日 14:47

だから近づいて。NLS_LANG 変数を追加した後、直接 oci8 挿入を行うとé動作します。

問題は実際には PHP 側にあります。ExtJs フレームワークを使用することで、フォームを送信するときに .xml を使用してエンコードしencodeURIComponentます。
Soéは として送信され%C3%A9、 に再エンコードされéます。
ただし、長さは1 ではなく2 (strlen($my_sent_value) = 2)になりました。PHP で試してみると、次のようになります。 $my_sent_value == é= FALSE

これらすべての文字を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 データベースに直接ログインすると、STRING_FIELD が に設定されていることがわかります|¿|。明らかに、以前の経験から期待していたものではありませんでした。
ただし、その PHP ページをすばやく 2 回更新すると、うまくいきました !!!
Oracleでは、正しく見ました|é|

環境変数が正しく設定されていないか、スクリプトの最初の実行に間に合うように送信されていないようですが、2 回目の実行では使用できます。

私の次の実験は、変数を PHP の環境にエクスポートすることですが、そのためには Apache をリセットする必要があります。

4

4 に答える 4

2

次の事実を認識していると思います。

  • 多くの異なる文字セットがあります。1 つを選択する必要があり、もちろん、使用している文字セットを把握する必要があります。
  • Oracle は、HTML エンティティなしでテキストを完全に格納できます ( é)。HTML エンティティは HTML で使用されます。Oracle は Web ブラウザではありません ;-)

また、HTML エンティティは特定の文字セットにバインドされないことも知っておく必要があります。逆に、文字セットに依存しないコンテキストで文字を表すために使用されます。

ISO-8859-1 と UTF-8 についてあいまいに話しています。どの文字セットを使用しますか? ISO-8859-1 は使いやすいですが、一部のラテン語 (スペイン語など) のテキストしか格納できず、€ 記号などの一般的な文字がいくつかありません。UTF-8 は使い方がややこしいですが、Unicode コンソーシアムによって定義されたすべての文字を格納できます (これには、必要なすべての文字が含まれます)。

決定したら、そのような文字セットでデータを保持するように Oracle を構成し、適切な列の型を選択する必要があります。たとえば、VARCHAR2 はプレーン ASCII に適しています。NVARCHAR2 は UTF-8 に適しています。

于 2010-03-03T11:06:38.023 に答える
2

これは、この問題を解決するために最終的に行ったことです。

PHP を実行するデーモンのプロファイルを次のように変更しました。

NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1

oci8 接続が ISO-8859-1 を使用するようにします。

次に、私の PHP 構成で、デフォルトの content-type を 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)
于 2010-03-11T16:33:39.153 に答える
0

私はこの問題に直面しなければなりませんでした:ラテンアメリカの特殊文字は「?」として保存されます。または "¿" 私の 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 パラメータです。

お役に立てば幸いです...改善すべき点があれば、遠慮なくコメントを投稿してください。

ソース: http://www.nullskull.com/faq/834/convert-string-to-hex-and-hex-to-string-in-net.aspx https://forums.oracle.com/thread/44799

于 2013-10-24T21:26:32.257 に答える
0

Oracleが使用する文字セットを本当に変更できない場合は、データをデータベースに格納する前にBase64でエンコードしてみてください。そうすれば、任意の文字セットの文字を受け入れて、それらを ISO-8859-1 として保存できます (Base64 は、ISO-8859-1 に正確にマップされる ASCII 文字セットのサブセットを出力するため)。Base64 エンコーディングでは、文字列の長さが平均で 37% 増加します。

データが HTML としてのみ表示される場合は、提案したように HTML エンティティを保存することもできますが、1 つのエンティティはエンコードされていない文字ごとに最大 10 文字になる可能性があることに注意してください。ϑ

于 2010-03-08T21:55:54.143 に答える