PDO OCI усекает большие многобайтовые сгустки


Когда PDO OCI возвращает мою строку через PDO::fetch(), мой столбец CLOB уже является потоком PHP. В случаях длинных блоков с многобайтовыми символами UTF-8 в них, когда я читаю этот поток, он усекается.

Примеры

  • мой CLOB - это строка из 8 193 знаков британского фунта ("£")... 16 386 байт
  • мой возвращенный массив строк показывает столбец как "тип ресурса='поток'"
  • Я выполняю stream_get_contents(), чтобы извлечь строку из потока
  • моя строка 8192 символы... 16 384 байта
  • таким образом, я потерял одного персонажа

Другой:

  • мой УДАР - это цепочка знаков в 100 000 фунтов... 200 000 байт
  • те же шаги, что и выше
  • моя строка состоит из 50 848 символов... 101 696 байт
  • таким образом, я потерял 49 152 символа

Я вижу аналогичные результаты, используя трехбайтовый символ ("の"), где максимальная длина, которая работает правильно, составляет 2730 символов (8192 байта).

У меня была такая же проблема с использованием raw OCI, где я использовал цикл чтения для самого объекта LOB:

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

Я смог обойти эту проблему, получив полный размер всего блока (lob->size()) и используя его в качестве размера для чтения больших объектов, таким образом, собрав все это в одно большое чтение.

Я не вижу способа сделать это в PDO OCI.

Я подозреваю, что внутренний код в PDO OCI, вероятно, выполняет тот же цикл чтения, чтобы превратить LOB в поток PHP.

Похоже, что выполнение фрагментированных чтений большого объема >8192 байт может быть нарушен в необработанном OCI, и, возможно, PDO OCI имеет ту же ошибку. В некоторых моих тестированиях моя интуиция подсказывает, что, возможно, чтение заканчивается в середине многобайтового символа, и молчаливо терпит неудачу, если он попытается в следующий раз возобновить то, что он считает недопустимым байтом UTF-8.

Кто-нибудь сталкивался с таким поведением? Есть ли обходной путь для PDO OCI?

Мое окружение:
- PHP 5.5.24 на RHEL6, oci8 v1.4.10 - PHP 5.5.11 на Win7, oci8 v1.4.10

Author: ashnazg, 2015-10-09

1 answers

Оказывается, это действительно может быть ошибка PDO_OCI: "базовая ошибка должна быть исправлена (пока нет ETA по этому поводу)" (https://github.com/php/php-src/pull/1566 , ссылаясь на (https://bugs.php.net/bug.php?id=60994).

 1
Author: ashnazg, 2017-01-25 22:26:37