Creating zip or tar.gz archive without exec

前端 未结 5 1226
感情败类
感情败类 2020-12-13 00:49

Is there is any safe way to create a zip archive, or tar.gz from php without using exec command ?

thanks

相关标签:
5条回答
  • 2020-12-13 01:17

    If you want to create tar.gz and you are using PHP 5.3+, you can use PharData class:

    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;
    }
    
    0 讨论(0)
  • 2020-12-13 01:22

    There is a very simple way to create Tar-archives directly within PHP - you can find a CLASS at sourceforge from Dennis Wronka under LGPL so you can use also in commercial scripts.

    <?php
    /**
     * @package PHPClassCollection
     * @subpackage Tar
     * @link classes
     * @author Dennis Wronka <reptiler@users.sourceforge.net>
     */
    /**
     * @package PHPClassCollection
     * @subpackage Tar
     * @link classes
     * @author Dennis Wronka <reptiler@users.sourceforge.net>
     * @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;
    }
    }
    ?>
    

    I also have a simple and pure PHP class for 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";
      }
    } 
    
    0 讨论(0)
  • 2020-12-13 01:24

    You can use PHP's Zip class to create zip files, and ZLib to create gzip files.

    Creating a .zip file:

    $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();
    

    Creating a .gz file:

    $file = "test.txt";
    $gzfile = "test.gz";
    $fp = gzopen($gzfile, 'w9'); // w == write, 9 == highest compression
    gzwrite($fp, file_get_contents($file));
    gzclose($fp);
    
    0 讨论(0)
  • 2020-12-13 01:26

    You can also use PHP compression stream wrappers to compress and uncompress files in one line:

    // 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 讨论(0)
  • 2020-12-13 01:32

    Use the system command instead

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

    Pay attention to the notes section on how to protect from malicious input.

    EDIT: Use the ZipArchive class to create a new zip via the open() command http://www.php.net/manual/en/class.ziparchive.php

    0 讨论(0)
提交回复
热议问题