PDO OCI 截断大型多字节 CLOB

PDO OCI truncates large multibyte CLOBs

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

例子

另一个:

我可以使用三字节字符(“の”)看到类似的结果,其中正确工作的最大长度是 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 有任何解决方法吗?

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

事实证明这可能确实是一个 PDO_OCI 错误:"the base bug needs to be fixed (no ETA on this yet)" (https://github.com/php/php-src/pull/1566, referring to (https://bugs.php.net/bug.php?id=60994).