【问题标题】:PDO OCI truncates large multibyte CLOBsPDO OCI 截断大型多字节 CLOB
【发布时间】:2016-01-06 17:09:15
【问题描述】:

当 PDO OCI 通过 PDO::fetch() 返回我的行时,我的 CLOB 列已经是一个 PHP 流。在长 CLOB 中包含多字节 UTF-8 字符的情况下,当我读取此流时,它会被截断。

例子

  • 我的 CLOB 是一串 8,193 个英镑符号 ("£")... 16,386 字节
  • 我返回的行数组将列显示为“resource type='stream'”
  • 我执行 stream_get_contents() 以从流中取出字符串
  • 我的字符串是 8,192 个字符... 16,384 个字节
  • 因此我失去了一个角色

另一个:

  • 我的 CLOB 是一串 100,000 磅符号... 200,000 字节
  • 与上述步骤相同
  • 我的字符串是 50,848 个字符... 101,696 个字节
  • 因此我丢失了 49,152 个字符

我可以使用三字节字符(“の”)看到类似的结果,其中正常工作的最大长度是 2730 个字符(8192 个字节)。

我在使用原始 OCI 时遇到了同样的问题,我在 LOB 对象本身上使用了读取循环:

while !lob->eof() then lob->read(8192)

我能够通过获取整个 CLOB (lob->size()) 的完整大小并将其用作我的 LOB 读取大小来解决此问题,从而将其全部集中在一次大读取中。

我认为在 PDO OCI 中没有办法做到这一点。

我的预感是 PDO OCI 中的内部代码可能正在执行相同类型的读取循环以将 LOB 转换为 PHP 流。

似乎在原始 OCI 中对超过 8192 字节的 LOB 进行分块读取可能会被破坏,并且可能 PDO OCI 具有相同的错误。在我的一些测试中,我的直觉认为读取可能在一个多字节字符的中间结束,并且如果它尝试下一次恢复它认为无效的 UTF-8 字节,则会静默失败。

有没有人遇到过这样的行为? PDO OCI 的任何解决方法?

我的环境:
- RHEL6 上的 PHP 5.5.24,oci8 v1.4.10 - Win7 上的 PHP 5.5.11,oci8 v1.4.10

【问题讨论】:

  • 由于 PDO OCI 似乎正在返回已被截断的流,因此在此之前我无能为力。
  • 嗯,我在之前的搜索中没有发现这个错误 -- bugs.php.net/bug.php?id=60994
  • 是的,我已经提到要使用原始 OCI 使其工作,我必须显式传递给 LOB->read() 一个大于实际 CLOB 值的长度大小值,从而强制读取发生在一大块而不是“LOB->eof() 然后 LOB->read()”loopl

标签: php oracle pdo utf-8 oracle-call-interface


【解决方案1】:

事实证明这可能确实是一个 PDO_OCI 错误:“基本错误需要修复(还没有 ETA)”(https://github.com/php/php-src/pull/1566,指的是(https://bugs.php.net/bug.php?id=60994)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2016-09-03
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多