PDO OCI截断大型多字节CLOB

时间:2015-10-08 21:56:56

标签: php oracle pdo utf-8 oci

当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中可能会破坏LOB> 8192bytes的分块读取,并且PDO OCI可能具有相同的错误。在我的一些测试中,我的直觉认为读取可能在多字节字符的中间结束,如果它尝试下一次恢复它看作无效的UTF-8字节,则默默地失败。

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

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

1 个答案:

答案 0 :(得分:1)

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