2010-03-01 81 views
4

您好我正在嘗試將名稱存儲到Oracle數據庫中,並使用PHP和oci8將其取回。使用Oracle,PHP和Oci8處理eacute和其他特殊字符

但是,如果我直接將é到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發送,然後重新編碼爲é
然而,它的長度是現在 (strlen($my_sent_value) = 2)而不是1 如果在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頁面兩次......它工作!
在Oracle中,我正確地看到了|é|

看來也許環境變量沒有被正確地設置或發送及時的腳本的第一次執行,但可用於第二次執行。

我的下一個實驗是將變量導出到PHP的環境中,但是,我需要重置Apache ......因此,我們將看到會發生什麼,希望它能起作用。

+1

什麼字符集是你的數據庫?您可以使用'select property_value from database_properties where property_name = 'NLS_CHARACTERSET'; 「 – 2010-03-01 17:36:02

+0

你可以回答你自己的問題;) – 2010-03-01 17:38:07

+0

我會等你自己回答這個問題,可能還有更好的方法來做到這一點...... – 2010-03-01 17:46:22

回答

1

這是我最後落得這樣做來解決這個問題:

修改運行PHP守護程序的配置文件有:

NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 

這樣的OCI8連接使用ISO-8859 -1。

在設置默認內容類型爲ISO-8859-1我的PHP配置

然後:

default_charset = "iso-8859-1" 

當我通過OCI8從PHP插入到一個Oracle表,我做的:

utf8_decode($my_sent_value) 

而且從Oracle接收數據時,輸出變量,應該只是工作像這樣:

echo $my_received_value 

然而W¯¯母雞發送數據阿賈克斯我不得不使用:

utf8_encode($my_received_value) 
2

我相信大家都知道這些事實:

  • 有許多不同的字符集:你必須選擇一個,當然,知道你使用的是哪一個。
  • Oracle完全有能力存儲沒有HTML實體的文本(é)。 HTML實體被用在HTML中。 Oracle不是網絡瀏覽器;-)

您還必須知道HTML實體沒有綁定到特定的字符集;相反,它們用於在獨立於字符集的上下文中表示字符。

你模糊地談論ISO-8859-1和UTF-8。你想使用什麼字符集? ISO-8859-1易於使用,但它只能以一些拉丁語言(如西班牙語)存儲文本,並且缺少像€符號這樣的常見字符。 UTF-8使用起來比較麻煩,但它可以存儲由Unicode聯盟定義的所有字符(其中包括您需要的所有內容)。

一旦你做出了決定,你必須配置Oracle來保存這樣的字符集中的數據並選擇適當的列類型。例如,VARCHAR2適用於純ASCII,NVARCHAR2適用於UTF-8。

+0

Thx回覆。我正在使用的Oracle數據庫使用的是ISO-8859-1,我無法改變這一點。我想這意味着我的PHP也必須使用它...但手動將數據存儲到數據庫並使用oci8檢索它後,我只收到e(不是é) – ddallala 2010-03-08 21:38:49

0

如果你真的不能更改oracle將使用的字符集,那麼在將數據存儲到數據庫之前,Base64如何編碼數據。這樣,您可以接受來自任何字符集的字符並將它們存儲爲ISO-8859-1(因爲Base64將輸出ASCII字符集的一個子集,該字符集完全映射到ISO-8859-1)。 Base64編碼將使字符串的長度平均增加37%如果您的數據只會以HTML格式顯示,那麼您也可以按照您的建議存儲HTML實體,但請注意,一個單一的實體每個未編碼字符最多可以包含10個字符,例如ϑ爲ϑ

0

我不得不面對這個問題:「?」的LatinAmerican特殊字符被存儲爲或「¿」在我的Oracle數據庫中......我無法更改NLS_CHARACTER_SET,因爲我們不是數據庫所有者。

於是,我找到了一個解決辦法:

1)ASP.NET代碼 創建一個字符串轉換爲十六進制字符的功能:

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