您好我正在尝试将名称存储到 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
,但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 == é
= 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……所以我们将看看会发生什么,希望它可以工作。