Пригодится тем у кого php без --with-zip
Поддерживает только методы сжатия deflate и no_compression.
Большинство зипов по умолчанию зажаты именно deflate, так что 95% архивов открывает без проблем. Запароленные не распаковывает.
Распаковывает также и вордовский docx (для чего, собственно, и был сделан, т.к. популярная либа PclZip, спотыкалась на куче нулей, которые ворд щедро пихает в свои файлы, видимо для того, чтобы размер файла не казался подозрительно маленьким :))
Поддерживает только методы сжатия deflate и no_compression.
Большинство зипов по умолчанию зажаты именно deflate, так что 95% архивов открывает без проблем. Запароленные не распаковывает.
Распаковывает также и вордовский docx (для чего, собственно, и был сделан, т.к. популярная либа PclZip, спотыкалась на куче нулей, которые ворд щедро пихает в свои файлы, видимо для того, чтобы размер файла не казался подозрительно маленьким :))
<?php // Radchand (C) radchand(a)mail.ru $GLOBALS['unzip_error'] = 'Ok'; // Строка с описанием ошибки /** Главная (и единственная) низкоуровняя ф-я для распаковки архива // @desc Распаковывает текущий файл в архиве. // Предназначана для работы в цикле. // Если $target не задан, то просто перемещает указатель на следующий файл в архиве не распаковывая. // Чтобы распаковать все файлы в архиве нужно вызывать эту ф-ю с одним и тем же handle до тех пор пока она не вернет false // Аргументы: // @param $file - имя файла или handle (возвращает fopen) // @param $target - имя файла для распаковки, если не совпадает, то просто перемещает указатель в архиве на следующий файл, но возващает имя файла, его размер и пр. // true - распаковывает любой файл // @return Возвращает ассоциативный массив: // FName - имя файла, // Date, Time - дата и время в 2-х байтном MS-DOS формате, // ExtractedLen - размер, // Data - содержимое файла, // Extra - дополн. данные // если произошла какая-то ошибка, то возвращает false, скорее всего, последующие вызовы тоже вернут false, т.к. наверняка указатель сползет // в случае ошибки из-за неподдерживаемого алгоритма распаковки, все же можно прочитать список файлов ($target=false) */ function Unzip($file, $target=false) { $h = is_string($file) ? fopen($file, 'rb') : $file; if($h===false) { $GLOBALS['unzip_error'] = "Can't open file"; return FALSE; } $offset = ftell($h); // ReadLocalFileHeader $hdr = unpack('V1Sign/v1Ver/v1Flags/v1Method/v1Time/v1Date/V1CRC/V1DataLen/V1ExtractedLen/v1FNameLen/v1ExtraLen', fread($h, 30)); if($hdr['Sign'] == 0x02014b50) { $GLOBALS['unzip_error'] = 'End of file'; return FALSE; } if($hdr['Sign'] != 0x04034b50) { $GLOBALS['unzip_error'] = 'Invalid sign!'; return FALSE; } if($hdr['Flags'] & 0x0008) // Descriptor after data. Need read directory at first. { $GLOBALS['unzip_error'] = 'Descriptor after data'; return FALSE; } $hdr['Offset'] = $offset; $hdr['FName'] = fread($h, $hdr['FNameLen']); if($target == $hdr['FName'] || $target === true) { if($hdr['Method']!=8 && $hdr['Method']!=0) // only deflate & no_compression method implemented { $GLOBALS['unzip_error'] = 'Only deflate & no_compression method implemented'; return FALSE; } if($hdr['ExtraLen']>0) $hdr['Extra'] = fread($h, $hdr['ExtraLen']); if($hdr['DataLen']>0) { $hdr['Data'] = fread($h, $hdr['DataLen']); if($hdr['Flags'] & 0x0001) { $GLOBALS['unzip_error'] = 'Encrypted'; return FALSE; } if($hdr['Method'] == 8) $hdr['Data'] = gzinflate($hdr['Data']); // deflate } if(strlen($hdr['Data']) != $hdr['ExtractedLen']) // bad length { $GLOBALS['unzip_error'] = 'Bad length'; return FALSE; } if(crc32($hdr['Data']) != $hdr['CRC']) { $GLOBALS['unzip_error'] = 'Bad CRC'; return FALSE; } } else fseek($h, $hdr['ExtraLen']+$hdr['DataLen'], SEEK_CUR); if(is_string($file)) fclose($h); return $hdr; } // Пара утилиток /** @desc возвращает список файлов в архиве * @param путь к архиву */ function ZipList($file) { $ret = array(); $h = fopen($file,'rb'); do { $data = Unzip($h); if(isset($data['FName'])) $ret[] = $data['FName']; } while($data && !feof($h)); fclose($h); return $ret; } /** @desc возвращает содержимое заданного файла из архива * @param путь к архиву * @param путь (имя файла) в архиве */ function UnzipFile($arcfile, $file) { $h = fopen($arcfile, 'rb'); do { $data = Unzip($h, $file); if(isset($data['Data'])) { fclose($h); return $data['Data']; } } while($data && !feof($h)); fclose($h); return false; } /** @desc возвращает ассоц. массив [имяфайла]=содержимое со всеми файлами из архива * @param путь к архиву */ function UnzipAll($arcfile) { $ret = array(); $h = fopen($arcfile, 'rb'); do { $data = Unzip($h, $file); if($data && isset($data['FName'], $data['Data'])) $ret[$data['FName']] = $data['Data']; } while($data && !feof($h)); fclose($h); return $ret; } ?>
Комментариев нет:
Отправить комментарий