PHP 8.4.24 Released!

Voting

: max(eight, four)?
(Example: nine)

The Note You're Voting On

wdtemp at seznam dot cz
16 years ago
Hi,
if you have the RAW CONTENT OF THE ZIP FILE IN A STRING ONLY and you can't create files on your server (because of the SAFE MODE) to be able to create a file which you can then pass to zip_open(), you'll be having hard times getting the uncompressed content of your ZIP data.
This may help:
I've written simple ZIP decompression function for decompressing the first file from the archive stored in a string (no matter what file it is). It's just about parsing a local file header of the first file, getting raw compressed data of that file and decompression of that data (usually, data in ZIP files are compressed by 'DEFLATE' method, so we'll just decompress it by gzinflate() function then).

<?php
function decompress_first_file_from_zip($ZIPContentStr){
//Input: ZIP archive - content of entire ZIP archive as a string
//Output: decompressed content of the first file packed in the ZIP archive
    //let's parse the ZIP archive
    //(see 'http://en.wikipedia.org/wiki/ZIP_%28file_format%29' for details)
    //parse 'local file header' for the first file entry in the ZIP archive
    if(strlen($ZIPContentStr)<102){
        //any ZIP file smaller than 102 bytes is invalid
        printf("error: input data too short<br />\n");
        return '';
    }
    $CompressedSize=binstrtonum(substr($ZIPContentStr,18,4));
    $UncompressedSize=binstrtonum(substr($ZIPContentStr,22,4));
    $FileNameLen=binstrtonum(substr($ZIPContentStr,26,2));
    $ExtraFieldLen=binstrtonum(substr($ZIPContentStr,28,2));
    $Offs=30+$FileNameLen+$ExtraFieldLen;
    $ZIPData=substr($ZIPContentStr,$Offs,$CompressedSize);
    $Data=gzinflate($ZIPData);
    if(strlen($Data)!=$UncompressedSize){
        printf("error: uncompressed data have wrong size<br />\n");
        return '';
    }
    else return $Data;
}

function binstrtonum($Str){
//Returns a number represented in a raw binary data passed as string.
//This is useful for example when reading integers from a file,
// when we have the content of the file in a string only.
//Examples:
// chr(0xFF) will result as 255
// chr(0xFF).chr(0xFF).chr(0x00).chr(0x00) will result as 65535
// chr(0xFF).chr(0xFF).chr(0xFF).chr(0x00) will result as 16777215
    $Num=0;
    for($TC1=strlen($Str)-1;$TC1>=0;$TC1--){ //go from most significant byte
        $Num<<=8; //shift to left by one byte (8 bits)
        $Num|=ord($Str[$TC1]); //add new byte
    }
    return $Num;
}
?>

ENJOY!!!
wdim

<< Back to user notes page

To Top