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