web-dev-qa-db-ja.com

execなしでZipまたはtar.gzアーカイブを作成する

Execコマンドを使用せずにZipアーカイブまたはphpからtar.gzを作成する安全な方法はありますか?

ありがとう

27
Ali AlNoaimi

Tar.gzを作成する必要があり、PHP 5.3+)を使用している場合は、 PharData クラスを使用できます。

try
{
    $a = new PharData('archive.tar');

    // ADD FILES TO archive.tar FILE
    $a->addFile('data.xls');
    $a->addFile('index.php');

    // COMPRESS archive.tar FILE. COMPRESSED FILE WILL BE archive.tar.gz
    $a->compress(Phar::GZ);

    // NOTE THAT BOTH FILES WILL EXISTS. SO IF YOU WANT YOU CAN UNLINK archive.tar
    unlink('archive.tar');
} 
catch (Exception $e) 
{
    echo "Exception : " . $e;
}
43

PHPの Zip クラスを使用してZipファイルを作成し、 ZLib を使用してgzipファイルを作成できます。

.Zipファイルの作成:

$Zip = new ZipArchive();
$res = $Zip->open('test.Zip', ZipArchive::CREATE);
$Zip->addFromString('test.txt', 'file content goes here');
$Zip->addFile('data.txt', 'entryname.txt');
$Zip->close();

.gzファイルの作成:

$file = "test.txt";
$gzfile = "test.gz";
$fp = gzopen($gzfile, 'w9'); // w == write, 9 == highest compression
gzwrite($fp, file_get_contents($file));
gzclose($fp);
22
foxy

代わりにsystemコマンドを使用してください

http://php.net/manual/en/function.system.php

悪意のある入力から保護する方法に関する注意セクションに注意してください。

編集:ZipArchiveクラスを使用して、open()コマンドで新しいZipを作成します http://www.php.net/manual/en/class.ziparchive.php

4
Jesus Ramos

PHP-内でtar-archiveを直接作成する非常に簡単な方法があります-LGPLの下でDennis Wronkaから sourceforge でクラスを見つけることができるので、商用でも使用できますスクリプト。

<?php
/**
 * @package PHPClassCollection
 * @subpackage Tar
 * @link classes
 * @author Dennis Wronka <[email protected]>
 */
/**
 * @package PHPClassCollection
 * @subpackage Tar
 * @link classes
 * @author Dennis Wronka <[email protected]>
 * @version 1.1
 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPL 2.1
 */
class tar
{
/**
 * The name of the tar-file to create.
 *
 * @var string
 */
var $filename;
/**
 * The list of files to add to the archive.
 *
 * @var array
 */
var $filelist=array();

/**
 * Constructor
 *
 * @param string $filename
 */
function tar($filename)
{
    $this->filename=$filename;
}

/**
 * Add a file.
 *
 * @param string $filename
 */
function add($filename)
{
    if ((file_exists($filename)) && (is_readable($filename)))
    {
        $this->filelist[]=$filename;
    }
}

/**
 * Write the tar-file.
 *
 * @return bool
 */
function write()
{
    sort($this->filelist);
    $tarfile=@fopen($this->filename,'w');
    if ($tarfile==false)
    {
        return false;
    }
    for ($x=0;$x<count($this->filelist);$x++)
    {
        $filename=$this->filelist[$x];
        if ((is_dir($this->filelist[$x])) && (substr($this->filelist[$x],-1)!='/'))
        {
            $filename.='/';
        }
        while (strlen($filename)<100)
        {
            $filename.=chr(0);
        }
        $permissions=sprintf('%o',fileperms($this->filelist[$x])).chr(0);
        while (strlen($permissions)<8)
        {
            $permissions='0'.$permissions;
        }
        $userid=sprintf('%o',fileowner($this->filelist[$x])).chr(0);
        while (strlen($userid)<8)
        {
            $userid='0'.$userid;
        }
        $groupid=sprintf('%o',filegroup($this->filelist[$x])).chr(0);
        while (strlen($groupid)<8)
        {
            $groupid='0'.$groupid;
        }
        if (is_dir($this->filelist[$x]))
        {
            $filesize='0'.chr(0);
        }
        else
        {
            $filesize=sprintf('%o',filesize($this->filelist[$x])).chr(0);
        }
        while (strlen($filesize)<12)
        {
            $filesize='0'.$filesize;
        }
        $modtime=sprintf('%o',filectime($this->filelist[$x])).chr(0);
        $checksum='        ';
        if (is_dir($this->filelist[$x]))
        {
            $indicator=5;
        }
        else
        {
            $indicator=0;
        }
        $linkname='';
        while (strlen($linkname)<100)
        {
            $linkname.=chr(0);
        }
        $ustar='ustar  '.chr(0);
        if (function_exists('posix_getpwuid'))
        {
            $user=posix_getpwuid(octdec($userid));
            $user=$user['name'];
        }
        else
        {
            $user='';
        }
        while (strlen($user)<32)
        {
            $user.=chr(0);
        }
        if (function_exists('posix_getgrgid'))
        {
            $group=posix_getgrgid(octdec($groupid));
            $group=$group['name'];
        }
        else
        {
            $group='';
        }
        while (strlen($group)<32)
        {
            $group.=chr(0);
        }
        $devmajor='';
        while (strlen($devmajor)<8)
        {
            $devmajor.=chr(0);
        }
        $devminor='';
        while (strlen($devminor)<8)
        {
            $devminor.=chr(0);
        }
        $prefix='';
        while (strlen($prefix)<155)
        {
            $prefix.=chr(0);
        }
        $header=$filename.$permissions.$userid.$groupid.$filesize.$modtime.$checksum.$indicator.$linkname.$ustar.$user.$group.$devmajor.$devminor.$prefix;
        while (strlen($header)<512)
        {
            $header.=chr(0);
        }
        $checksum=0;
        for ($y=0;$y<strlen($header);$y++)
        {
            $checksum+=ord($header[$y]);
        }
        $checksum=sprintf('%o',$checksum).chr(0).' ';
        while (strlen($checksum)<8)
        {
            $checksum='0'.$checksum;
        }
        $header=$filename.$permissions.$userid.$groupid.$filesize.$modtime.$checksum.$indicator.$linkname.$ustar.$user.$group.$devmajor.$devminor.$prefix;
        while (strlen($header)<512)
        {
            $header.=chr(0);
        }
        fwrite($tarfile,$header);
        if ($indicator==0)
        {
            $contentfile=fopen($this->filelist[$x],'r');
            $data=fread($contentfile,filesize($this->filelist[$x]));
            while (strlen($data)%512!=0)
            {
                $data.=chr(0);
            }
            fwrite($tarfile,$data);
        }
    }
    fclose($tarfile);
    return true;
}
}
?>

また、シンプルで純粋なPHP Zipのクラス:

<?php /* 110 Lines */
/*
//  Zip File Creation Class - http://www.pkware.com/appnote.txt

//  Download Zip File
    include_once 'Zip.inc.php';
    $zipfile = new zipfile();
    $fileonserver = 'path/to/file/oldfilename.txt';
    $fileinarchive = 'newfilename.txt';
    $zipfile->addFile(file_get_contents($fileonserver), $fileinarchive);
    header('Content-type: application/octet-stream');
    header('Content-disposition: attachment; filename=archive.Zip');
    echo $zipfile->file();

//  Save Zip File To Server
    include_once 'Zip.inc.php';
    $zipfile = new zipfile();
    $fileonserver = 'path/to/file/oldfilename.txt';
    $fileinarchive = 'newfilename.txt';
    $zipfile->addFile(file_get_contents($fileonserver), $fileinarchive);
    $contents = $zipfile->file();
    file_put_contents('archive.Zip', $contents);
*/

$zipfile = new zipfile();
$zipfile->addFile(file_get_contents(dirname(__FILE__).'/Zip.inc.php'), 'Zip.inc.php');
file_put_contents('archive.Zip', $zipfile->file());

class zipfile { 
  var $datasec = array(); 
  var $ctrl_dir = array(); 
  var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; 
  var $old_offset = 0; 
  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['seconds'] = 0;
    } 
    return 
      (($timearray['year'] - 1980) << 25) | 
      ($timearray['mon'] << 21) | 
      ($timearray['mday'] << 16) | 
      ($timearray['hours'] << 11) | 
      ($timearray['minutes'] << 5) | 
      ($timearray['seconds'] >> 1);
  }
  function addFile($data, $name, $time = 0) { 
    $name = str_replace('\\', '/', $name); 
    $dtime = dechex($this->unix2DosTime($time)); 
    $hexdtime = '\x' . $dtime[6] . $dtime[7] . 
                '\x' . $dtime[4] . $dtime[5] . 
                '\x' . $dtime[2] . $dtime[3] . 
                '\x' . $dtime[0] . $dtime[1]; 
    eval('$hexdtime = "' . $hexdtime . '";'); 
    $fr = "\x50\x4b\x03\x04"; 
    $fr .= "\x14\x00"; 
    $fr .= "\x00\x00"; 
    $fr .= "\x08\x00"; 
    $fr .= $hexdtime; 
    $unc_len = strlen($data); 
    $crc = crc32($data); 
    $zdata = gzcompress($data); 
    $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); 
    $c_len = strlen($zdata); 
    $fr .= pack('V', $crc); 
    $fr .= pack('V', $c_len); 
    $fr .= pack('V', $unc_len); 
    $fr .= pack('v', strlen($name)); 
    $fr .= pack('v', 0); 
    $fr .= $name; 
    $fr .= $zdata; 
    $this -> datasec[] = $fr; 
    $cdrec = "\x50\x4b\x01\x02"; 
    $cdrec .= "\x00\x00"; 
    $cdrec .= "\x14\x00"; 
    $cdrec .= "\x00\x00"; 
    $cdrec .= "\x08\x00"; 
    $cdrec .= $hexdtime; 
    $cdrec .= pack('V', $crc); 
    $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 ); 
    $cdrec .= pack('v', 0 ); 
    $cdrec .= pack('V', 32 ); 
    $cdrec .= pack('V', $this -> old_offset ); 
    $this -> old_offset += strlen($fr); 
    $cdrec .= $name; 
    $this -> ctrl_dir[] = $cdrec;
  }
  function 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)) . 
      pack('V', strlen($data)) . 
      "\x00\x00";
  }
} 
1
adilbo

PHP圧縮ストリームラッパー を使用して、ファイルを1行で圧縮および解凍することもできます。

// Reads file.txt, passes it throyuh the zlib wrapper and writes the archive file.txt.gz
copy('data.xls', 'compress.zlib://' . 'data.xls.gz');

// Reads the archive file.txt.gz using zlib wrapper, writes uncompressed file
copy('compress.zlib://' . 'data.xls.gz', 'data.xls');
0
SilverFire