Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > некорректная работа substr и mb_substr с бинарника


Автор: Acraft 3.9.2008, 23:37
Доброго времени суток.
Возникла следующая проблема

из потока получаем данные: 
Код

$data = file_get_contents("php://input");

По протоколу согласно которому обрабатываются эти данные, строка представляет собой смесь строковых (utf-8) и бинарных последовательностей, часть которых подлежит преобразованию функцией unpack()
Код

$p=2;  
$size=unpack("L", substr($data,$p,4));   // В таком dword поле хранится информация о длине следующего за ним поля
$p+=4;
/* в нашем случае, substr или mb_substr, результат одинаков */

Другая часть вырезается из строки "как есть" и вставляется в файл (изображение). 
Код

$str = substr($data, $p, $size);
$p+=$size;

И третья часть представляющая собой обычную строку в кодировке utf-8
Код

// обрабатывается как и предыдущaя часть
$str = substr($data, $p, $size);


Проблема заключается в том, что в PHP 5.2.6 функции mb_substr() и substr() некорректно вырезают часть данных, если эти данные имеют хоть один символ кириллицы, не закодированный в UTF8.
Из-за этого этими функциями невозможно вырезать нужный кусок из бинарных данных.
Этого бага нет в версии PHP 5.2.5 и 4.4.1 

p.s.: вариант через fopen читать фрагменты нужной длинны не подходит

Автор: Sannis 4.9.2008, 00:00
Цитата(Acraft @  3.9.2008,  23:37 Найти цитируемый пост)
если эти данные имеют хоть один символ кириллицы, не закодированный в UTF8.


Цитата(Acraft @  3.9.2008,  23:37 Найти цитируемый пост)
По протоколу согласно которому обрабатываются эти данные, строка представляет собой смесь строковых (utf-8) и бинарных последовательностей

Или вы себе противоречите, или неточно выразились.

С юникодом нужно использовать только mb_* функции. Я бы на вашем месте привёл весь код и пример файла smile

Добавлено через 1 минуту и 8 секунд
Да, а нужно ли вообще обрабатывать бинарные данные с помощью PHP?

Автор: Acraft 5.9.2008, 10:37
Простое описание, ниже будет еще особенность:
Код

$str="testабв"; //строка в Win1251
echo substr($str,0,5);

выводит: testабв, а должен testа

а вот это, естественно, работает:
Код

$str=iconv("Win1251","UTF8","testабв"); //строка в UTF
echo substr($str,0,5);

выводит: testа

и
Код

$str=iconv("Win1251","UTF8","testабв"); //строка в UTF
echo mb_substr($str,0,5);

выводит: testа

Проблема в том, что в его проекте $str содержит бинарные данные, например, тело JPG файла. И, если в этом теле есть хоть одна русская буква, то substr() из такой строки $str возвращает не то, что его просят.

И вот особенность- баг наблюдается только тогда, когда позиция, начиная с которой надо вернуть строку, находится после хотябы одной русской буквы, т.е.:
Код

$str="testабв"; //строка в Win1251
echo substr($str,0,3);

выводит: tes

а вто это:
Код

$str="testабвtest"; //строка в Win1251
echo substr($str,8,3);

выводит: строку из космоса, а должен: est

В php.ini прописано mbstring.internal_encoding = UTF-8
----

Еще раз напомню- в версиях PHP 5.2.5, 5.1.6, 4.4.1 бага нет, т.е. в указанных версиях
Код

$str="testабв"; //строка в Win1251
echo substr($str,0,5);

выводит: testа

P.S.:
Сегодня из портов установили патч php5-5.2.6_2. Первые тесты показали отсутствие проблемы.

Автор: Acraft 16.9.2008, 12:08
http://bugs.php.net/bug.php?id=45311

Автор: chiv 23.9.2008, 15:37
У меня такая же проблема функицией substr.
Причем возникает периодически 2-3 раза в сутки. Все файлы в Win1251.

На хостинге PHP 5.2.6
Кто нибудь знает как обойти эту проблему?
Можно использовать какую-нибудь другую функцию?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)