2012-04-03 13 views
7

Nach einer gzip deflate Anfrage in PHP zu machen, erhalte ich die entleerten Zeichenfolge in Offset-Stücke, die stark Format zu zeigen, verkürzt wie folgtWie man eine chunked gzip Zeichenkette decodiert/aufbläst?

Beispiel sieht:

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 

aufzublasen Ich bin nicht in der Lage, dass vermutlich wegen des Chunked-Formats. Ich kann bestätigen, dass die Daten nicht korrupt sind, nachdem ich die Offsets manuell mit einem Hex-Editor entfernt und das gzip-Archiv gelesen habe. Ich frage mich, ob es eine richtige Methode gibt, diese chunked gzip deflationierte Antwort in eine lesbare Zeichenfolge zu analysieren?

Ich könnte in der Lage sein, diese Offsets zu teilen und die Daten in einer Zeichenfolge zusammenzufassen, um Gzinflate aufzurufen, aber es scheint, dass es einen einfacheren Weg geben muss.

Antwort

9

die richtige Methode tun müssen, eine Chunked abzulassen Antwort in etwa wie folgt:

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 
} 

Hier ist eine handliche PHP-Funktion zu tun, dass für Sie (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

Ausgezeichnet, funktioniert wie erwartet. Das ist eine praktische PHP-Funktion, ich suche das schon seit einiger Zeit. Vielen Dank! – user1309276

+0

@ user1309276 Ich habe die obige Funktion aktualisiert, es hatte einen Fehler um das Verhalten, wenn die Zeichenfolge eine literale CRLF enthält. Dies wurde nun behoben und dies hat auch eine bessere Erkennung von fehlerhaften Strings ermöglicht. – DaveRandom

+0

Danke nochmal! Für alle, die immer noch Probleme haben, nach dem Aufruf von unchunk_string, muss ich nur die ersten 10 Bytes entfernen mit: $ data = gzinflate (substr ($ data, 10)); – user1309276

0

in einen String verwenden gzinflate, Zend_Http_Client lib helfen, diese Art von gemeinsamen Aufgaben zu tun, seine wasy zu dekodieren Zend_Http_Response code zu verwenden, finden Sie, wenn Sie es auf Ihrem eigenen

+0

Leider habe ich bereits die Methode, die lib verwendet, ausprobiert, aber es enthält etwas Code, den ich in der Zukunft brauchen könnte, danke! – user1309276