【发布时间】: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