php 文件在在压缩代码
class PHPZip
{
function Zip($dir, $zipfilename)
{
if (@function_exists('gzcompress'))
{
$curdir();
if (is_array ($dir))
{
$filelist = $dir;
}
else
{
$filelist = $this -> GetFileList($dir);
}
if ((!empty($dir))&&(!is_array($dir))&&(file_exists
($dir))) chdir($dir);
else chdir( $curdir);
if (count($filelist)>0)
{
foreach($filelist as $filename)
{
if (is_file($filename))
{
$fd = fopen ($filename,
"r");
$content = @fread ($fd,
filesize ($filename));
fclose ($fd);
if (is_array($dir))
$filename = Basename( $filename);
$this -> addFile($content,
$filename);
}
}
$out = $this -> file();
chdir($curdir);
$fp = fopen($zipfilename, "w");
fwrite($fp, $out, strlen($out));
fclose($fp);
}
return 1;
}
else return 0;
}
function GetFileList($dir)
{
if (file_exists($dir))
{
$args = func_get_args();
$pref = [ 1];
$dh = opendir($dir);
while($files = readdir($dh))
{
if (($files!=".")&&($files!=".." ))
{
if (is_dir($dir.$files))
{
$curdir = getcwd();
chdir($dir.$files);
$file = array_merge($file,
$これは - > GetFileList("", "$pref$files/"));
chdir($curdir);
}
else $file[]=$pref.$files;
}
}
closedir($dh);
}
return $file;
}
var $datasec = array();
var $ctrl_dir = array();
var $eof_ctrl_dir = "x50x4bx05x06x00x00x00x00";
var $old_offset = 0;
/**
* Unix タイムスタンプを 4 バイトの DOS 日付と時刻形式に変換します
(日付
* 上位 2 バイト、下位 2 バイトの時間で大きさ
の比較が可能)。
*
* @param integer 現在の Unix タイムスタンプ
*
* @return integer 4 バイト DOS 形式の現在の日付
*
* @access private
*/
function unix2DosTime($unixtime = 0) {
$timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
if ($timearray['year'] < 1980) {
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$ timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray[' minutes'] = 0;
$timearray['秒'] = 0;
} // end if
return (($timearray['年'] - 1980) << 25) | ($timearray['mon'] <<
21) | ($timearray['mday'] <16) |
($timearray['hours'] <11) | ($timearray[' minutes'] << 5) |
($timearray['秒'] >> 1);
} // 'unix2DosTime()' メソッドの終了
/* *
*「ファイル」をアーカイブに追加します *
* @param文字列ファイルコンテンツ * @param文字列アーカイブ内のファイルの名前(
pathが含まれる場合があります) * @param integer現在のタイムスタンプ *
*/
function addFile($data, $name, $time = 0)
{
$name = str_replace('', '/', $name);
$dtime = dechex($this- >unix2DosTime($time));
$hexdtime = 'x' 。 $dtime[6] 。 $dtime[7]
。 'バツ' 。 $dtime[4] 。 $dtime[5]
。 'バツ' 。 $dtime[0] 。 $dtime[1];
eval('$hexdtime = "' . $hexdtime . '";');
$fr = "x50x4bx03x04";
$fr .= "x14x00"; // 抽出するにはverが必要です
$fr .= "x00x00"; // 生成目的ビットフラグ
$fr .= $hexdtime; //最後のmod時間と日付
// "ローカルファイルヘッダー"segment
$ unc_len = strlen($ data);
$ crc = crc32($ data); = strlen($zdata);
crc バグ
$fr .= Pack('V', $crc); // crc32
$fr .= Pack('V', $c_len); // 圧縮ファイルサイズ
$fr .= Pack('V', $unc_len); // 非圧縮ファイルサイズ
$fr .= Pack('v', strlen($name)); // ファイル名の長さ
$fr .= $name;
// 「ファイルデータ」セグメント
$fr .= $zdata;
// 「データ記述子」セグメント (オプションですが、アーカイブが
の場合は必要です)
not
// ファイルとして機能します)
$fr .= Pack('V', $crc); // crc32
$fr .= Pack('V', $c_len); // 圧縮ファイルサイズ
$fr .= Pack('V', $unc_len); // 非圧縮ファイルサイズ
// このエントリを配列に追加します
$this -> datasec[] = $fr;
$new_offset = strlen(implode('', $this->datasec));
// 中央ディレクトリレコードに追加します
$cdrec = "x50x4bx01x02";
$cdre c .= "x00x00"; // 作成者:
$cdrec .= "x14x00"; // 抽出に必要なバージョン
$cdrec .= "x00x00"; // 生成目的ビットフラグ
$cdrec .= "x08x00"; // 圧縮方法
$cdrec .= $hexdtime; // 最終更新日時
$cdrec .= Pack('V', $crc); // crc32
$cdrec .= Pack('V', $c_len); // 圧縮ファイルサイズ
$cdrec .= Pack('V', $unc_len); // 非圧縮ファイルサイズ
$cdrec .= Pack('v', strlen($name) ); // ファイル名の長さ
$cdrec .= Pack('v', 0 ); // 追加のフィールド長
$cdrec .= Pack('v', 0 ); // ファイルコメントの長さ
$cdrec .= Pack('v', 0 ); // ディスク番号 start
$cdrec .= Pack('v', 0 ); // 内部ファイル属性
$cdrec .= Pack('V', 32 ); // 外部ファイル属性 -
'archive' ビット set
$cdrec .= Pack('V', $this -> old_offset ); //
ローカルヘッダーの相対オフセット
$this -> old_offset = $new_offset;
$cdrec .= $name;
// オプションの追加フィールド、ここにファイルのコメントが入ります
// 中央のディレクトリに保存します
$this -> ctrl_dir[] = $cdrec;
} // 'addFile()' メソッドの終わり
/**
* ファイルをダンプします
*
* @return string zip ファイル
*
* @access public
*/
関数 file()
{
$data = implode('', $this - > datasec);
$ctrldir = implode('', $this -> ctrl_dir);
return
$data .
$ctrldir .
$this -> eof_ctrl_dir .
Pack('v', sizeof($this -> ctrl_dir)) 。 // エントリの合計数
「このディスク上」
Pack('v', sizeof($this -> ctrl_dir)) 。 // エントリの合計数
全体
Pack('V', strlen($ctrldir)) 。 // 中央の dir
Pack('V', strlen($data)) のサイズ。 //
中央ディレクトリ
の先頭へのオフセット "x00x00"; // .zip ファイル コメント
length
} // 'file()' メソッドの終わり
}