用php解压缩文件


198

我想解压缩文件,这很好用

system('unzip File.zip');

但是我需要通过URL传递文件名,而无法使其正常工作,这就是我所拥有的。

$master = $_GET["master"];
system('unzip $master.zip'); 

我想念什么?我知道这一定是我忽略的小而愚蠢的事情。

谢谢,


35
双引号评估变量;单引号不行。但是-注意,因为仅将一些输入传递给系统调用可能非常危险。
Wiseguy 2012年

25
必须说我不喜欢某些评论的敌意语气。如果你们意识到她/他缺少东西,那么就告诉她/他。我们都在某个时候错过了一些东西。
塞巴斯蒂安·马赫2015年

这里的错误很简单。您正在尝试使用带单引号而不是双引号的字符串插值。字符串插值不适用于简单的引号,因为它用于字符串文字。因此,将代码更改为system("unzip $master.zip");应该可以。
Asier Paz

Answers:


500

我只能假设您的代码来自在线某个地方的教程?在这种情况下,请尝试自己解决这个问题。另一方面,该代码实际上可以在线发布为解压缩文件的正确方法,这有点令人恐惧。

PHP具有用于处理压缩文件的内置扩展。不需要为此使用system调用。ZipArchivedocs是一种选择。

$zip = new ZipArchive;
$res = $zip->open('file.zip');
if ($res === TRUE) {
  $zip->extractTo('/myzips/extract_path/');
  $zip->close();
  echo 'woot!';
} else {
  echo 'doh!';
}

而且,正如其他人所评论的那样,$HTTP_GET_VARS自4.1版本起已弃用... ...很久以前。不要使用它。请改用$_GETsuperglobal。

最后,在接受通过$_GET变量传递给脚本的任何输入时要非常小心。

始终清理用户输入。


更新

根据您的评论,将zip文件提取到其所在目录中的最佳方法是确定该文件的硬路径并将其专门提取到该位置。因此,您可以执行以下操作:

// assuming file.zip is in the same directory as the executing script.
$file = 'file.zip';

// get the absolute path to $file
$path = pathinfo(realpath($file), PATHINFO_DIRNAME);

$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
  // extract it to the path we determined above
  $zip->extractTo($path);
  $zip->close();
  echo "WOOT! $file extracted to $path";
} else {
  echo "Doh! I couldn't open $file";
}

谢谢您的指教。我对此并不陌生,只是想尽办法。使用您的代码,如何将其解压缩到压缩文件所在的文件夹中?
BostonBB 2012年

2
好吧,脚本的当前工作目录与zip文件所在的目录之间存在差异。如果zip文件与脚本位于同一目录中$zip->extractTo('./');,则可能不是这种情况。更好的选择是确定zip文件在文件系统中的位置并将其解压缩到其中。我将更新答案以进行演示。
rdlowrey'1

如果没有可用的ZipArchive类怎么办?我正在使用带有垃圾邮件托管的网站,但是遇到了Fatal error: Class 'ZipArchive' not found我尝试使用此脚本的错误:-(那时候有什么选择吗?
CWSpear 2012年

2
@CWSpear您将需要基础zlib库来使用PHP执行几乎所有的压缩/解压缩操作。即使进行系统调用,您也需要具有基础库。但是,这是非常普遍的事情,但没有例外。如果您使用共享主机,他们应该为您安装它。否则,只需搜索诸如“如何为PHP安装Zip函数支持”之类的
字词

是的,据我所知,这是非常便宜的托管。无论如何,感谢您的答复,这是个好东西。
CWSpear 2012年

37

请不要那样做(将GET var传递为系统调用的一部分)。请改用ZipArchive

因此,您的代码应如下所示:

$zipArchive = new ZipArchive();
$result = $zipArchive->open($_GET["master"]);
if ($result === TRUE) {
    $zipArchive ->extractTo("my_dir");
    $zipArchive ->close();
    // Do something else on success
} else {
    // Do something on error
}

要回答您的问题,您的错误是“其他东西$ var”应该是“其他东西$ var”(双引号)。


3
+1,抱歉,五分钟后您回答了基本相同的答案。在那儿没看到你:)
rdlowrey'1

10

使用getcwd()在同一目录提取

<?php
$unzip = new ZipArchive;
$out = $unzip->open('wordpress.zip');
if ($out === TRUE) {
  $unzip->extractTo(getcwd());
  $unzip->close();
  echo 'File unzipped';
} else {
  echo 'Error';
}
?>

5

只需尝试将此yourDestinationDir作为目标即可提取或删除-d yourDestinationDir以便提取至根目录。

$master = 'someDir/zipFileName';
$data = system('unzip -d yourDestinationDir '.$master.'.zip');

1
我用的yourDestinationDirsession_save_path() . DIRECTORY_SEPARATOR . "$name" . DIRECTORY_SEPARATOR 哪里$name是目标文件夹中的文件夹会解压。
Ramratan Gupta

1
处理包含变量的系统或exec函数时要特别小心!它可以从服务器向黑客提供免费的命令行。
maxime

@maxime怎么可能?请解释一下,因为我认为php作为阻止这种情况发生的措施。用事实支持您的主张
Samuel Kwame Antwi

@SamuelKwameAntwi exec和system正在使用php用户调用系统外壳。因此,如果您的用户是www,则可以在命令行上执行unix用户“ www”的所有操作,包括删除文件或目录。如果您的php用户是root用户,那真的很糟糕。您可以在此处找到有关它的更多信息:stackoverflow.com/questions/3115559/exploitable-php-functions
maxime

5

我将@rdlowrey的答案更新为更简洁的代码,这将使用将该文件解压缩到当前目录__DIR__

<?php 
    // config
    // -------------------------------
    // only file name + .zip
    $zip_filename = "YOURFILENAME.zip";
?>

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' >
    <title>Unzip</title>
    <style>
        body{
            font-family: arial, sans-serif;
            word-wrap: break-word;
        }
        .wrapper{
            padding:20px;
            line-height: 1.5;
            font-size: 1rem;
        }
        span{
            font-family: 'Consolas', 'courier new', monospace;
            background: #eee;
            padding:2px;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <?php
        echo "Unzipping <span>" .__DIR__. "/" .$zip_filename. "</span> to <span>" .__DIR__. "</span><br>";
        echo "current dir: <span>" . __DIR__ . "</span><br>";
        $zip = new ZipArchive;
        $res = $zip->open(__DIR__ . '/' .$zip_filename);
        if ($res === TRUE) {
          $zip->extractTo(__DIR__);
          $zip->close();
          echo '<p style="color:#00C324;">Extract was successful! Enjoy ;)</p><br>';
        } else {
          echo '<p style="color:red;">Zip file not found!</p><br>';
        }
        ?>
        End Script.
    </div>
</body>
</html> 

2

PHP具有自己的内置类,可用于解压缩或从zip文件中提取内容。该类是ZipArchive。以下是简单而基本的PHP代码,它将提取一个zip文件并将其放置在特定目录中:

<?php
$zip_obj = new ZipArchive;
$zip_obj->open('dummy.zip');
$zip_obj->extractTo('directory_name/sub_dir');
?>

如果您需要一些高级功能,则下面是经过改进的代码,它将检查zip文件是否存在:

<?php
$zip_obj = new ZipArchive;
if ($zip_obj->open('dummy.zip') === TRUE) {
   $zip_obj->extractTo('directory/sub_dir');
   echo "Zip exists and successfully extracted";
}
else {
   echo "This zip file does not exists";
}
?>

资料来源:如何在PHP中解压缩或解压缩zip文件?


0

我将Morteza Ziaeemehr的答案更新为更干净,更好的代码,这将使用DIR将表单内提供的文件解压缩到当前目录中。

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8' >
  <title>Unzip</title>
  <style>
  body{
    font-family: arial, sans-serif;
    word-wrap: break-word;
  }
  .wrapper{
    padding:20px;
    line-height: 1.5;
    font-size: 1rem;
  }
  span{
    font-family: 'Consolas', 'courier new', monospace;
    background: #eee;
    padding:2px;
  }
  </style>
</head>
<body>
  <div class="wrapper">
    <?php
    if(isset($_GET['page']))
    {
      $type = $_GET['page'];
      global $con;
      switch($type)
        {
            case 'unzip':
            {    
                $zip_filename =$_POST['filename'];
                echo "Unzipping <span>" .__DIR__. "/" .$zip_filename. "</span> to <span>" .__DIR__. "</span><br>";
                echo "current dir: <span>" . __DIR__ . "</span><br>";
                $zip = new ZipArchive;
                $res = $zip->open(__DIR__ . '/' .$zip_filename);
                if ($res === TRUE) 
                {
                    $zip->extractTo(__DIR__);
                    $zip->close();
                    echo '<p style="color:#00C324;">Extract was successful! Enjoy ;)</p><br>';
                } 
                else 
                {
                    echo '<p style="color:red;">Zip file not found!</p><br>';
                }
                break;
            }
        }
    }
?>
End Script.
</div>
    <form name="unzip" id="unzip" role="form">
        <div class="body bg-gray">
            <div class="form-group">
                <input type="text" name="filename" class="form-control" placeholder="File Name (with extension)"/>
            </div>        
        </div>
    </form>

<script type="application/javascript">
$("#unzip").submit(function(event) {
  event.preventDefault();
    var url = "function.php?page=unzip"; // the script where you handle the form input.
    $.ajax({
     type: "POST",
     url: url,
     dataType:"json",
           data: $("#unzip").serialize(), // serializes the form's elements.
           success: function(data)
           {
               alert(data.msg); // show response from the php script.
               document.getElementById("unzip").reset();
             }

           });

    return false; // avoid to execute the actual submit of the form
  });
</script>
</body>
</html> 

0

只是改变

system('unzip $master.zip');

到这个

system('unzip ' . $master . '.zip');

或这个

system("unzip {$master}.zip");


6
尽管这可以解决他遇到的问题,但请查看其他答案,以了解为什么这是个坏建议。
rjdown 2014年

0

您可以使用预包装功能

function unzip_file($file, $destination){
    // create object
    $zip = new ZipArchive() ;
    // open archive
    if ($zip->open($file) !== TRUE) {
        return false;
    }
    // extract contents to destination directory
    $zip->extractTo($destination);
    // close archive
    $zip->close();
        return true;
}

如何使用它。

if(unzip_file($file["name"],'uploads/')){
echo 'zip archive extracted successfully';
}else{
  echo 'zip archive extraction failed';
}

0

在PHP代码下面使用,文件名位于URL参数“名称”中

<?php

$fileName = $_GET['name'];

if (isset($fileName)) {


    $zip = new ZipArchive;
    $res = $zip->open($fileName);
    if ($res === TRUE) {
      $zip->extractTo('./');
      $zip->close();
      echo 'Extracted file "'.$fileName.'"';
    } else {
      echo 'Cannot find the file name "'.$fileName.'" (the file name should include extension (.zip, ...))';
    }
}
else {
    echo 'Please set file name in the "name" param';
}

?>

0

简单的PHP函数即可解压缩。请确保您的服务器上安装了zip扩展名。

/**
 * Unzip
 * @param string $zip_file_path Eg - /tmp/my.zip
 * @param string $extract_path Eg - /tmp/new_dir_name
 * @return boolean
 */
function unzip(string $zip_file_path, string $extract_dir_path) {
    $zip = new \ZipArchive;
    $res = $zip->open($zip_file_path);
    if ($res === TRUE) {
        $zip->extractTo($extract_dir_path);
        $zip->close();
        return TRUE;
    } else {
        return FALSE;
    }
}

-3

只需使用此:

  $master = $_GET["master"];
  system('unzip' $master.'.zip'); 

在您的代码$master中以字符串形式传递时,系统将查找名为$master.zip

  $master = $_GET["master"];
  system('unzip $master.zip'); `enter code here`

5
只是完全错误。 'unzip' $master除非您在解压缩后添加了空格并在单引号之后添加了句点,否则将无法正常工作。system("unzip $master.zip")用双引号或至少一个有效的答案提出建议会容易得多。
Nicholas Blasgen 2015年

1
使用PHP系统功能胜过依赖系统功能。
Sloan Thrasher

正如接受的答案中强调的那样- 清理用户输入,任何人都可以在此$_GET查询字符串中添加任何内容,并将自己的代码注入到system调用中
jg2703
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.