处理eacute和其他特殊字符使用Oracle,PHP and Oci8
-
23-09-2019 - |
题
嗨我想商店的名字到Oracle数据库和获取他们回来使用PHP和oci8.
然而,如果我插入 é
直接到Oracle数据库和使用oci8取后我只收到一个 e
我必须要编码所有特殊字符的(包括 é
)成html实体(即: é
)之前插入数据库...或者我是不是错过什么?
Thx
更新:Mar1至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;
}
似乎工作,虽然不确定,如果其最佳解决方案
更新:Mar8至15:45
Oracle's character set是ISO-8859-1.
在PHP我补充:
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1");
强制oci8连接使用的字符组。检索的 é
使用oci8从PHP现在的工作!(对 varchars
, 但不 CLOBs
不得不做 utf8_encode
来提取它)
所以然后我试图拯救数据PHP to Oracle...它不工作..沿途的某个地方从PHP to Oracle的 é
变成一个 ?
更新:马9至14:47
所以越来越近。之后添加NLS_LANG变量,这样做直接oci8刀片 é
工程。
该问题实际上是在PHP侧。通过使用过测试框架,在提交形式,它对它进行编码使用 encodeURIComponent
.
所以 é
发送 %C3%A9
然后重新编码的成 é
.
然而,它的长度是现在 2 (strlen($my_sent_value) = 2)
并不1.如果在PHP我尝试:$my_sent_value== é
= 假
我想如果我能够重新编码所有这些角色在PHP回到长字节1号,然后插入Oracle,它应的工作。
仍然没有运气,虽然
更新:Mar10至11:05
我一直在想我是这么近(却又如此遥远).
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
工作非常sporadicly.
我创建了一个小php script测试:
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为那个...所以我们就看看会发生什么事情,希望它的工作。
解决方案 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不是一个网络浏览器;-)
还必须知道HTML实体不是结合一个具体charset;相反,他们是用来代表人物,在一个charset独立的上下文。
你隐约谈ISO-8859-1和UTF-8。什么charset你想使用?ISO-8859-1易于使用,但只能储存的文本在一些拉丁语言(例如西班牙)和它缺乏一些共同字样的欧元的象征。UTF-8是棘手的使用,但它可以存储所有的人物定义通过一编码联合会(其中包括的一切,你永远需要).
一旦你已经采取的决定,必须配置Oracle举行的数据,在这样的字符集和选择适当列类型。E.g., VARCHAR2是纯ASCII,NVARCHAR2是良好的UTF-8。
如果你真的无法改变的字符集,甲骨文将利用再怎么样Base64编码存储在数据库中之前编码数据。这样的话,你可以从任何字符集字符接受,并将其保存为ISO-8859-1(因为Base64编码将输出的ASCII字符集,其准确映射到ISO-8859-1的子集)。 Base64编码会增加由字符串的长度,平均37%的
如果您的数据仅是以往任何时候都显示为HTML,那么你还不如保存HTML实体如你所说,但是要知道,一个单一的实体可高达每未编码字符10个字符例如θ为ϑ
我不得不面对这个问题:“?”的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