您好我正在嘗試將名稱存儲到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 ......因此,我們將看到會發生什麼,希望它能起作用。
什麼字符集是你的數據庫?您可以使用'select property_value from database_properties where property_name = 'NLS_CHARACTERSET'; 「 – 2010-03-01 17:36:02
你可以回答你自己的問題;) – 2010-03-01 17:38:07
我會等你自己回答這個問題,可能還有更好的方法來做到這一點...... – 2010-03-01 17:46:22