【问题标题】:PHP OCI8 Unable to read Unicode chars from NCHAR (Oracle 11g)PHP OCI8 无法从 NCHAR 读取 Unicode 字符(Oracle 11g)
【发布时间】:2016-12-12 13:12:15
【问题描述】:

我花了几天时间尝试在 Linux Ubuntu 服务器 14.04 上通过 PHP7 OCI8(尝试使用 PDO_OCI 和 ODBC 以及 PHP5,同样的问题)从 Oracle 11g 读取 Unicode 字符(简体中文名称)。

这是 Oracle 11g 设置:

NLS_LANGUAGE    AMERICAN
NLS_TERRITORY   AMERICA
NLS_CHARACTERSET    WE8MSWIN1252
NLS_SORT    BINARY
NLS_NCHAR_CHARACTERSET  AL16UTF16
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE

重要 我要读取的表列定义为 NCHAR(40)。 我使用 php-7.0.8 NTS、oci8-2.0.11(来自 PECL)并安装了 Oracle Instantclient

这是我正在使用的 php 代码:

<?php
$fp = fopen('output.txt','w');
$conn = oci_connect('MYUSER', 'MYPASSWORD', 'xxx.xxx.xxx.xxxx/DBTEST','AL32UTF8');

$query = "SELECT ABALPH FROM CRPDTA.F0101 WHERE ROWNUM <= 1 ORDER BY NULL";
$stid = oci_parse($conn, $query);
oci_execute($stid, OCI_NO_AUTO_COMMIT);

while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
    fwrite($fp, $row['ABALPH']."\n");
}
fclose($fp);
?>

然后我可以看到英文名称,但我将 ¿¿¿¿¿¿¿¿¿¿¿¿¿ 放入我的 txt 文件(UTF8 w/o BOM 格式)中以获取中文名称。我认为这与 NCHAR(40) 数据类型有关。

请注意,我已经直接设置了 Oracle 环境变量(通过 export 和/或 putenv())。当我使用 sqlplus 命令时,我可以将可读的中文名称导出到我设置的文件中 export NLS_LANG ="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

关于如何解决这个问题的任何想法?我将不胜感激! 问候,塞尔吉奥

【问题讨论】:

    标签: php unicode oracle11g oci8


    【解决方案1】:

    在 PHP OCI8 或 PDO_OCI 中没有对 NCHAR 或 NCLOB 的原生支持。现在很多人都在使用 UTF8,所以他们不需要 N* 支持。

    【讨论】:

      【解决方案2】:

      我想我在this blog post 中找到了解决方案。

      看了文章的cmets,基本上NCHAR字段需要转换为RAW/HEX:

      $query = "SELECT UTL_RAW.cast_to_raw(convert(ABALPH,'AL32UTF8')) FROM CRPDTA.F0101 WHERE ROWNUM <= 1 ORDER BY NULL";
      

      如果您在 PHP 中使用 oci8 扩展,则无需进一步将十六进制转换为 UTF8,因为根据帖子,它是由 PHP 自动完成的。但是,如果您使用 PDO_OCI,则需要先使用 hex2bin() 转换十六进制字段,然后再将其用作 UTF8 字符串。

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2022-06-10
        • 2017-07-23
        • 1970-01-01
        • 2015-02-15
        • 1970-01-01
        • 2017-03-20
        • 2012-05-22
        • 1970-01-01
        • 2016-08-28
        相关资源
        最近更新 更多