【问题标题】:Unzip a file with php用php解压一个文件
【发布时间】:2012-02-11 22:13:55
【问题描述】:

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

system('unzip File.zip');

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

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

我错过了什么?我知道它一定是我忽略的一些小而愚蠢的东西。

谢谢你,

【问题讨论】:

  • 双引号评估变量;单引号没有。但是——要小心,因为简单地将一些输入传递给系统调用可能非常危险。
  • 必须说我不喜欢某些cmets的敌意语气。如果你们意识到她/他错过了什么,那么就告诉她/他吧。我们都会在某些时候错过一些东西。
  • 这里的错误很简单。您正在尝试使用带有简单引号而不是双引号的字符串插值。字符串插值不适用于简单引号,因为它用于字符串文字。因此,将您的代码更改为 system("unzip $master.zip"); 应该可以工作。

标签: php unzip


【解决方案1】:

请不要那样做(将 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
}

为了回答您的问题,您的错误是“something $var something else”应该是“something $var something else”(用双引号括起来)。

【讨论】:

    【解决方案2】:

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

    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 版以来已被弃用......这是很久以前的事了。不要使用它。请改用$_GET 超全局。

    最后,在接受通过$_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";
    }
    

    【讨论】:

    • 感谢您的建议。我对此很陌生,只是想弄清楚一切。使用您的代码,如何将其解压缩到压缩文件所在的同一文件夹中?
    • 嗯,脚本的当前工作目录和 zip 文件所在的目录是有区别的。如果 zip 文件与脚本位于同一目录中,您可以执行 $zip->extractTo('./'); 但是,情况可能并非如此。更好的选择是确定 zip 文件在文件系统中的位置并将其解压缩到那里。我将更新我的答案以进行演示。
    • 如果您没有可用的 ZipArchive 类怎么办?我正在一个带有垃圾托管的网站上工作,我收到Fatal error: Class 'ZipArchive' not found 错误,我尝试使用这个脚本:-( 那时有什么选择吗?
    • @CWSpear 你将使用need the underlying zlib 库来执行几乎所有使用 PHP 的压缩/解压缩操作。即使要进行系统调用,您也需要拥有底层库。这是一件非常普遍的事情,没有它是个例外。如果您使用的是共享主机,他们应该为您安装它。否则,只需谷歌搜索“如何为 PHP 安装 Zip 函数支持”
    • 是的,据我所知,这是非常便宜的托管服务。无论如何,谢谢你的回复,这是个好东西。
    【解决方案3】:

    我将 @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> 
    

    【讨论】:

      【解决方案4】:

      只是改变

      system('unzip $master.zip');
      

      给这个

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

      或者这个

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

      【讨论】:

      • 虽然这可能会解决他遇到的问题,但请查看其他答案以了解为什么这是不好的建议。
      【解决方案5】:

      就用这个吧:

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

      在您的代码中$master 作为字符串传递,系统将寻找一个名为$master.zip 的文件

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

      【讨论】:

      • 完全错了。 'unzip' $master 将不起作用,除非您在解压缩后添加一个空格并在单引号后添加一个句点。用双引号建议system("unzip $master.zip") 会更容易,或者至少是一个有效的答案。
      • 使用PHP系统函数比依赖系统函数好。
      • 正如在接受的答案中所强调的那样 - 清理用户输入,任何人都可以将任何内容添加到此$_GET 查询字符串并将自己的代码注入system 调用
      【解决方案6】:

      只需试试这个 yourDestinationDir 是要提取到或删除 -d yourDestinationDir 以提取到根目录的目的地。

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

      【讨论】:

      • 我将yourDestinationDir 用作session_save_path() . DIRECTORY_SEPARATOR . "$name" . DIRECTORY_SEPARATOR,其中$name 是在会话文件夹中解压缩的目标文件夹。
      • 在处理包含变量的系统或执行函数时要非常小心!它可以从您的服务器向黑客提供免费的命令行。
      • @maxime 这怎么可能?请解释一下,因为我认为 php 作为阻止这种情况发生的措施。用事实支持你的主张
      • @SamuelKwameAntwi exec 和 system 正在使用 php 用户调用系统 shell。因此,如果您的用户是 www,您可以在命令行上执行 unix 用户“www”可以执行的所有操作,包括删除文件或目录。如果您的 php 用户是 root,那真的很糟糕。你可以在那里找到更多信息:stackoverflow.com/questions/3115559/exploitable-php-functions
      【解决方案7】:

      我将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> 
      

      【讨论】:

        【解决方案8】:

        你可以使用预打包函数

        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';
        }
        

        【讨论】:

          【解决方案9】:

          使用下面的 PHP 代码,文件名在 URL 参数“name”中

          <?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';
          }
          
          ?>
          

          【讨论】:

            【解决方案10】:

            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";
            }
            ?>
            

            来源:How to unzip or extract zip files in PHP?

            【讨论】:

              【解决方案11】:

              使用getcwd()解压到同目录

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

              【讨论】:

                【解决方案12】:

                简单的 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;
                    }
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-11-12
                  • 2019-01-13
                  • 2018-08-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多