使用Oracle,PHP和Oci8处理eacute和其他特殊字符 [英] Dealing with eacute and other special characters using Oracle, PHP and Oci8

查看:181
本文介绍了使用Oracle,PHP和Oci8处理eacute和其他特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



但是,如果我插入 é直接导入Oracle数据库,并使用oci8取回它,我只是收到一个 e



我必须将所有特殊字符(包括é)编码为html实体(即:& eacute;







$ b

更新: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 + \\\3') - 128))。';',$ string);
$ string = preg_replace(/([\300-\337])([\200-\277])/ e,'&#'。 \\\1') - 192)* 64 +(ord('\\2') - 128))。';',$ string);
return $ string;
}

似乎有效,但不确定其最佳解决方案






更新:3月8日15:45
$ b

Oracle的字符集是ISO-8859-1。

在PHP中我添加:

 code> putenv(NLS_LANG = AMERICAN_AMERICA.WE8ISO8859P1); 

强制oci8连接使用该字符集。
从PHP中获取é现在可以使用oci8了! ( varchars ,但不是 CLOBs 必须执行 utf8_encode 提取它)

所以,然后我尝试将数据从PHP保存到Oracle ...它不工作。在从PHP到Oracle的方法中,é成为






em> UPDATE:Mar 9 at 14:47



更接近。
添加NLS_LANG变量后,使用é进行直接oci8插入。



在PHP端。
通过使用ExtJs框架,当提交表单时,它使用 encodeURIComponent 对其进行编码。

因此é作为%C3%A9 发送,然后重新编码为é

但是它的长度现在是 2 (strlen($ my_sent_value)= 2)而不是1.
如果在PHP I try:$ my_sent_value == é = FALSE



将所有这些字符在PHP中重新编码为字节大小1的长度,然后将它们插入Oracle,它应该工作。



仍然没有运气






> UPDATE:Mar 10 at 11:05



我一直认为我离这么近



putenv(NLS_LANG = AMERICAN_AMERICA.WE8ISO8859P9); 非常零星地工作。



我创建了一个小的php脚本来测试:

  '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的...所以我们会看到会发生什么,希望它工作。

解决方案

这是我最后为解决这个问题所做的:



修改运行PHP的守护程序的配置文件:

  NLS_LANG = AMERICAN_AMERICA.WE8ISO8859P1 

以便oci8连接使用ISO-8859-1。



然后在我的PHP配置中将默认内容类型设置为ISO-8859-1:

  default_charset =iso-8859-1 



当我通过oci8从PHP插入Oracle表时,我会:

  utf8_decode($ my_sent_value)


$ b b

当从Oracle接收数据时,打印变量应该这样工作:

  echo $ my_received_value 

但是当通过ajax发送数据时,我不得不使用:

  utf8_encode($ my_received_value)


Hi I am trying to store names into an Oracle database and fetch them back using PHP and oci8.

However, if I insert the é directly into the Oracle database and use oci8 to fetch it back I just receive an e

Do I have to encode all special characters (including é) into html entities (ie: é) before inserting into database ... or am I missing something ?

Thx


UPDATE: Mar 1 at 18:40

found this function: 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;
}

seems to work, although not sure if its the optimal solution


UPDATE: Mar 8 at 15:45

Oracle's character set is ISO-8859-1.
in PHP I added:

putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1");

to force the oci8 connection to use that character set. Retrieving the é using oci8 from PHP now worked ! (for varchars, but not CLOBs had to do utf8_encode to extract it )
So then I tried saving the data from PHP to Oracle ... and it doesnt work..somewhere along the way from PHP to Oracle the é becomes a ?


UPDATE: Mar 9 at 14:47

So getting closer. After adding the NLS_LANG variable, doing direct oci8 inserts with é works.

The problem is actually on the PHP side. By using ExtJs framework, when submitting a form it encodes it using encodeURIComponent.
So é is sent as %C3%A9 and then re-encoded into é.
However it's length is now 2 (strlen($my_sent_value) = 2) and not 1. And if in PHP I try: $my_sent_value == é = FALSE

I think if I am able to re-encode all these characters in PHP back into lengths of byte size 1 and then inserting them into Oracle, it should work.

Still no luck though


UPDATE: Mar 10 at 11:05

I keep thinking I am so close (yet so far away).

putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9"); works very sporadicly.

I created a small php script to test:

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);

After running this once and loggin into the Oracle Database directly I see that STRING_FIELD is set to |¿|. Obviously not what I had come to expect from my previous experience.
However, if I refresh that PHP page twice quickly.... it worked !!!
In Oracle I correctly saw |é|.

It seems like maybe the environment variable is not being correctly set or sent in time for the first execution of the script, but is available for the second execution.

My next experiment is to export the variable into PHP's environment, however, I need to reset Apache for that...so we'll see what happens, hopefully it works.

解决方案

This is what I finally ended up doing to solve this problem:

Modified the profile of the daemon running PHP to have:

NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1

So that the oci8 connection uses ISO-8859-1.

Then in my PHP configuration set the default content-type to ISO-8859-1:

default_charset = "iso-8859-1"

When I am inserting into an Oracle Table via oci8 from PHP, I do:

utf8_decode($my_sent_value)

And when receiving data from Oracle, printing the variable should just work as so:

echo $my_received_value

However when sending that data over ajax I have had to use:

utf8_encode($my_received_value)

这篇关于使用Oracle,PHP和Oci8处理eacute和其他特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆