2012-04-03 3 views
7

После создания запроса GZIP выкачать в PHP, я получаю спущенную строку в офсетных кусках, которые выглядят следующим образомКак декодировать/раздувать стробированную строку gzip?

Пример сильно укороченный, чтобы показать формат:

00001B4E 
¾”kŒj…Øæ’ìÑ«F1ìÊ`+ƒQì¹UÜjùJƒZ\µy¡ÓUžGr‡J&=KLËÙÍ~=ÍkR 
0000102F 
ñÞœÞôΑüo[¾”+’Ñ8#à»0±R-4VÕ’n›êˆÍ.MCŽ…ÏÖr¿3M—èßñ°r¡\+ 
00000000 

Я не может надуть, что предположительно из-за фрагментированного формата. Я могу подтвердить, что данные не повреждены после ручного удаления смещений с помощью редактора Hex и чтения архива gzip. Мне интересно, есть ли подходящий метод для анализа этого chunked gzip deblated response в читаемой строке?

Я мог бы разделить эти смещения и объединить данные в одну строку, чтобы вызвать gzinflate, но, похоже, должен быть более простой способ.

ответ

9

правильный метод, чтобы выкачать Chunked ответ примерно следующим образом:

initialise string to hold result 
for each chunk { 
    check that the stated chunk length equals the string length of the chunk 
    append the chunk data to the result variable 
} 

Вот удобная функция PHP, чтобы сделать это для вас (FIXED):

function unchunk_string ($str) { 

    // A string to hold the result 
    $result = ''; 

    // Split input by CRLF 
    $parts = explode("\r\n", $str); 

    // These vars track the current chunk 
    $chunkLen = 0; 
    $thisChunk = ''; 

    // Loop the data 
    while (($part = array_shift($parts)) !== NULL) { 
    if ($chunkLen) { 
     // Add the data to the string 
     // Don't forget, the data might contain a literal CRLF 
     $thisChunk .= $part."\r\n"; 
     if (strlen($thisChunk) == $chunkLen) { 
     // Chunk is complete 
     $result .= $thisChunk; 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) == $chunkLen + 2) { 
     // Chunk is complete, remove trailing CRLF 
     $result .= substr($thisChunk, 0, -2); 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) > $chunkLen) { 
     // Data is malformed 
     return FALSE; 
     } 
    } else { 
     // If we are not in a chunk, get length of the new one 
     if ($part === '') continue; 
     if (!$chunkLen = hexdec($part)) break; 
    } 
    } 

    // Return the decoded data of FALSE if it is incomplete 
    return ($chunkLen) ? FALSE : $result; 

} 
+0

Отлично, работает так, как ожидалось. Это удобная функция PHP, я искал ее некоторое время. Большое спасибо! – user1309276

+0

@ user1309276 Я обновил вышеуказанную функцию, у нее была ошибка, окружающая поведение, когда строка содержит литерал CRLF. Это теперь исправлено, и это также обеспечило лучшее обнаружение неверных строк. – DaveRandom

+0

Еще раз спасибо! Для тех, у кого до сих пор возникают проблемы, после вызова unchunk_string все, что мне нужно сделать, это удалить первые 10 байтов, используя: $ data = gzinflate (substr ($ data, 10)); – user1309276

0

Чтобы декодировать строки использовать gzinflate, Zend_Http_Client Lib поможет сделать этот вид общих задач, его WASY использовать, обратитесь Zend_Http_Response code, если вам нужно сделать это на своем собственном

+0

К сожалению, я уже пробовал метод, который использует lib, но он содержит некоторый код, который мне может понадобиться в будущем, спасибо! – user1309276

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