Mailinglisten-Archive |
Hallo zusammen, ich habe mir vor einiger Zeit selber mal eine Funktion geschrieben, die einen String als Zip-Datei behandelt und entpacken kann. Ich hatte zwar auch mal mit der ZipLib rumprobiert, und war auch zufrieden, musste jedoch feststellen, dass die nicht auf jedem x-beliebigen Server installiert ist. Also hab ich mir das Zip-Format mal angesehn, und eine Funktion geschrieben, die Zip-Strings entpackt und als Array zurückliefert. Ein Aufruf könnte so aussehen: $content = file_get_contents('mein_zip.zip'); $data = getZipFileContents($content); Wenn man ausführliche Informationen erhalten möchte, ruft man die Funktion mit dem zusätzlichen (optionalen) Parameter TRUE auf. Die Struktur des Ergebnis-Arrays ändert sich jeweils, ist aber per print_f einfach rauszubekommen. Weiterer Vorteil dieser Funktion: Man könnte auch eine per HTTP abgerufene Zip-Datei somit einfach entpacken. Das Anlegen einer temporären Datei entfällt. Da die Funktion so kurz gehalten ist, arbeitet sie auch schnell. Nachteil: Die Funktion ist reduziert auf die nötigsten Funktionen und unterstützt z.B. keine Passwort-Entschlüsselung oder gesplittete Archive. Ausserdem wird die zlib Bibliothek von Jean-loup Gailly und Mark Adler benutzt, die jedoch auf den meisten (Low-Cost) Host Servern installiert ist. /* * zip file extraction function * * REDUCED TO THE MOST COMMON OPTIONS: * - no password decryption * - no splitted archives * * Copyright (C) 2004 Niels Jäckel <niels.jaeckel at silice.de> * * * @param string $file_contents this is the *full* content of the .zip file * @param $full_information optional parameter to get full information (TRUE | FALSE) * * @return array $contents * */ function getZipFileContents($file_contents, $full_information = FALSE) { /* getting position of central directory */ $file_size = strlen($file_contents); $pointer = $file_size - 277; if ($pointer < 0) { $pointer = 0; } $pointer = strpos($file_contents, "\x50\x4b\x05\x06\x00\x00\x00\x00", $pointer) + 4; /* reading central directory */ $central_directory = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', substr($file_contents, $pointer, 18)); $pointer = $central_directory['offset']; $archive_data = array(); /* getting archive data */ for ($t = $central_directory['disk_start']; $t < $central_directory['disk_entries']; $t++) { /* reading central file header */ $central_file_header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', substr($file_contents, $pointer, 46)); /* extracting filename */ $filename = substr($file_contents, $pointer + 46, $central_file_header['filename_len']); /* extracting extrafield */ $extra = substr($file_contents, $pointer + 46 + $central_file_header['filename_len'], $central_file_header['extra_len']); /* extracting comment */ $comment = substr($file_contents, $pointer + 46 + $central_file_header['filename_len'] + $central_file_header['extra_len'], $central_file_header['comment_len']); $pointer += 46 + $central_file_header['filename_len'] + $central_file_header['extra_len'] + $central_file_header['comment_len']; /* filter directories */ if ($filename{strlen($filename) - 1} != '/') { /* calculating position of compressed content */ $content_start = $central_file_header['offset'] + 30 + $central_file_header['filename_len'] + $central_file_header['extra_len']; if ($central_file_header['compression'] == 0) { /* extracting uncompressed content */ $content = substr($file_contents, $content_start, $central_file_header['compressed_size']); } else { /* extracting compressed content */ $content = substr($file_contents, $content_start, $central_file_header['compressed_size']); $content .= pack('VV', $central_file_header['crc'], $central_file_header['size']); /* decompressing content */ $content = @gzinflate($content); } /* getting filestatus */ $status = 'ok'; if ($content === FALSE && $status == 'ok') { $status = 'err_decompress'; } if (crc32($content) != $central_file_header['crc'] && $status == 'ok') { $status = 'err_crc'; } if (strlen($content) != $central_file_header['size'] && $status == 'ok') { $status = 'err_length'; } /* saving information */ if ($full_information) { if ($central_file_header['mdate'] && $central_file_header['mtime']) { $hour = ($central_file_header['mtime'] & 0xF800) >> 11; $minute = ($central_file_header['mtime'] & 0x07E0) >> 5; $seconde = ($central_file_header['mtime'] & 0x001F)*2; $year = (($central_file_header['mdate'] & 0xFE00) >> 9) + 1980; $month = ($central_file_header['mdate'] & 0x01E0) >> 5; $day = $central_file_header['mdate'] & 0x001F; $timestamp = mktime($hour, $minute, $seconde, $month, $day, $year); } else { $timestamp = time(); } $i = count($archive_data); $archive_data[$i] = array(); $archive_data[$i]['filename'] = $filename; $archive_data[$i]['timestamp'] = $timestamp; $archive_data[$i]['comment'] = $comment; $archive_data[$i]['extrafield'] = $extra; $archive_data[$i]['status'] = $status; if ($status == 'ok') { $archive_data[$i]['content'] = $content; } else { $archive_data[$i]['content'] = FALSE; } } else { if ($status == 'ok') { $archive_data[$filename] = $content; } else { $archive_data[$filename] = FALSE; } } } } return $archive_data; }
php::bar PHP Wiki - Listenarchive