2012-01-22 3 views
1

Я пытаюсь получить число байтов в строке PHP. Кажется, у меня возникла проблема с отправкой необработанных HTTP-запросов (PROPFIND, REPORT) и получением правильной длины содержимого. С какого момента, следуя заголовкам, я начинаю подсчитывать содержимое? И в какой момент я останавливаюсь?PHP: количество байтов в строке, raw HTTP

+0

Я не очень понял, но если это не связано с динамическим контентом, вы можете просто прочитать заголовок 'Content-Length'. – Christian

ответ

4

Сосчитав полное содержание, начиная после двух переносов, которые разграничивают раздел заголовка:

$contentlength_bytes = strlen(strstr($http, "\r\n\r\n")) - 4; 

Если вы делаете это таким образом уже я думаю, вы могли бы столкнуться с проблемами с кодировкой ...

Если ваш контент имеет многобайтовые символы, использование strlen() для возврата его bytelength может работать некорректно, так как многобайтовые символы могут интерпретироваться как один байт при определенных конфигурациях системы (см. Ниже, и комментарии для этой части).

Это даст вам правильный bytelength любого содержимого строки вы кормите его под любой конфигурации системы:

$contentlength_bytes = mb_strlen(strstr($http, "\r\n\r\n"), 'latin1') - 4; 

Edit:
Как Джон отметил в комментариях, это не всегда необходимо так как strlen() вернет правильный бит строки в большинстве случаев.

Я просто добавил этот метод измерения как в многобайтовых системах, так и при определенных обстоятельствах (например, mbstring.func_overload установлен в 2) strlen() небезопасен для использования с двоичными строками.

Вышеуказанный метод является единственным известным (для меня) способом полностью двоичного безопасного вычисления байтовой длины данной строки. И я споткнулся об этом пару раз уже.

+0

'latin1' содержит только 8 символов, поэтому. Для этого вы можете использовать любую однобайтную кодировку символов. Заголовки 'Content-Type' для этого не имеют значения, так как вам нужно указать длину содержимого в байтах, а не в символах. PHP немного упрям, когда дело доходит, чтобы определить длину байта для строки. Это все, что стоит за этим решением. Это просто многобайтная безопасная версия 'strlen()', которая всегда будет давать вам bytelength независимо от кодировки. – bardiir

+3

-1: ** Это фактически неправильно. ** Многобайтные символы будут считаться как несколько байтов с чистым 'strlen', так работает эта функция. Вам нужно только 'mb_strlen', если вы хотите * длину символа *. – Jon

+0

@Jon: wrong - 'strlen()' не всегда безопасен в использовании - например, см. Эту проблему, которую я обнаружил при выталкивании Google: http://php.bigresource.com/size-of-binary-string-on -multi-byte-system - PAWEYTMl.html - у меня была эта проблема сама собой пару раз. 'strlen()' можно использовать только в том случае, если вы работаете в среде с байтовым кодированием. Использование 'mb_strlen' с явной кодировкой 8byte является единственным двоичным безопасным способом. (За исключением записи в файл и использования 'filesize()'). Использование 'strlen()' в системах с включенным 'mbstring.func_overload = 2' также небезопасно и возвращает символы. – bardiir

3

Если у вас есть весь ваш запрос в переменной, скажем $request, то:

list($headers,$body) = explode("\r\n\r\n",$request,2); 

В основном, два CRLFs отметить конец заголовков, и содержимое начинают после этого.

+0

Это хороший факт, на который можно положиться (и это звучит как правильный ответ). – Christian

Смежные вопросы