<?php
namespace lqf;
use DirectoryIterator;
use Exception;
use think\Db;
use ZipArchive;
class Zip
{
protected $zip;
protected $root;
protected $ignored_names;
public function __construct()
{
$this->zip = new ZipArchive;
}
public function unzip($zipfile, $path)
{
if ($this->zip->open($zipfile) === true) {
$file_tmp = @fopen($zipfile, "rb");
$bin = fread($file_tmp, 15); fclose($file_tmp);
if (true === $this->getTypeList($bin)) {
$result = $this->zip->extractTo($path);
$this->zip->close();
return $result;
} else {
return false;
}
}
return false;
}
public function zip($zipfile, $folder, $ignored = null)
{
$this->ignored_names = is_array($ignored) ? $ignored : $ignored ? array($ignored) : array();
if ($this->zip->open($zipfile, ZIPARCHIVE::CREATE) !== true) {
throw new Exception("cannot open <$zipfile>\n");
}
$folder = substr($folder, -1) == '/' ? substr($folder, 0, strlen($folder) - 1) : $folder;
if (strstr($folder, '/')) {
$this->root = substr($folder, 0, strrpos($folder, '/') + 1);
$folder = substr($folder, strrpos($folder, '/') + 1);
}
$this->createZip($folder);
return $this->zip->close();
}
private function createZip($folder, $parent = null)
{
$full_path = $this->root . $parent . $folder;
$zip_path = $parent . $folder;
$this->zip->addEmptyDir($zip_path);
$dir = new DirectoryIterator($full_path);
foreach ($dir as $file) {
if (!$file->isDot()) {
$filename = $file->getFilename();
if (!in_array($filename, $this->ignored_names)) {
if ($file->isDir()) {
$this->createZip($filename, $zip_path . '/');
} else {
$this->zip->addFile($full_path . '/' . $filename, $zip_path . '/' . $filename);
}
}
}
}
}
public function fileList($zipfile)
{
$file_dir_list = array();
$file_list = array();
if ($this->zip->open($zipfile) == true) {
for ($i = 0; $i < $this->zip->numFiles; $i++) {
$numfiles = $this->zip->getNameIndex($i);
if (preg_match('/\/$/i', $numfiles)) {
$file_dir_list[] = $numfiles;
} else {
$file_list[] = $numfiles;
}
}
}
return array('files' => $file_list, 'dirs' => $file_dir_list);
}
private function getTypeList($bin)
{
$array = array(
array("504B0304", "zip")
);
foreach ($array as $v) {
$blen = strlen(pack("H*", $v[0])); $tbin = substr($bin, 0, intval($blen)); $unpack=unpack("H*", $tbin);
if (strtolower($v[0]) == strtolower(array_shift($unpack))) {
return true;
}
}
return false;
}
}