Распакуйте файл с помощью php


199

Я хочу, чтобы распаковать файл, и это прекрасно работает

system('unzip File.zip');

Но мне нужно передать имя файла через URL и не могу заставить его работать, это то, что у меня есть.

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

Чего мне не хватает? Я знаю, что это должно быть что-то маленькое и глупое, которое я пропускаю.

Спасибо,


35
Двойные кавычки оценивают переменные; одинарных кавычек нет. НО - будьте осторожны, так как простая передача некоторого ввода системному вызову может быть довольно опасной.
Wiseguy

25
Должен сказать, что мне не нравится враждебный тон некоторых комментариев. Если вы, ребята, понимаете, что она / он чего-то не хватает, просто скажите ей / ему об этом. Мы все что-то упускаем в какой-то момент.
Себастьян Мах

Ошибка здесь проста. Вы пытаетесь использовать строковую интерполяцию с простыми кавычками вместо двойных кавычек. Строковая интерполяция не работает с простыми кавычками, потому что она используется для строковых литералов. Таким образом, изменение вашего кода system("unzip $master.zip");должно работать.
Асьер Пас

Ответы:


500

Я могу только предположить, что ваш код взят из учебника где-то в Интернете? В таком случае, хорошая работа, пытаясь понять это самостоятельно. С другой стороны, тот факт, что этот код может быть опубликован где-то в Интернете как правильный способ распаковать файл, немного пугающий.

PHP имеет встроенные расширения для работы со сжатыми файлами. Для этого не нужно использовать systemзвонки. ZipArchiveдокументы это один из вариантов.

$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-файл?
BostonBB

2
Ну, есть разница между текущим рабочим каталогом вашего скрипта и каталогом, в котором находится zip-файл. Если zip-файл находится в том же каталоге, что и скрипт, который вы могли бы сделать. $zip->extractTo('./');Однако, это, вероятно, не тот случай. Лучший вариант - определить местоположение zip-файла в файловой системе и извлечь его там. Я обновлю свой ответ, чтобы продемонстрировать.
rdlowrey

Что если у вас нет класса ZipArchive? Я работаю над сайтом с дерьмовым хостингом и получаю сообщение об Fatal error: Class 'ZipArchive' not foundошибке, которое я пробую с помощью этого сценария :-( Есть ли какая-либо опция в этот момент?
CWSpear

2
@CWSpear Вам понадобится базоваяzlib библиотека для выполнения практически любых операций сжатия / распаковки с помощью PHP. Даже для системных вызовов вам понадобится базовая библиотека. Это очень распространенная вещь, и не исключение. Если вы используете виртуальный хостинг, они должны установить его для вас. В противном случае, просто Google что-то вроде «Как установить поддержку функций Zip для PHP»
rdlowrey

Да, это довольно дешевый хостинг, как мне сказали. В любом случае, спасибо за ответ, это полезно знать.
CWSpear

38

Пожалуйста, не делайте так (передавая 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

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
Я использовал yourDestinationDirкак, session_save_path() . DIRECTORY_SEPARATOR . "$name" . DIRECTORY_SEPARATOR где $nameнаходится целевая папка, чтобы разархивировать в папке сеанса.
Рамратан Гупта

1
Будьте очень осторожны при работе с системными или exec-функциями, которые содержат переменные! Это может дать хакеру бесплатную командную строку с вашего сервера.
Максим

@maxime Как это возможно? пожалуйста, объясните, потому что я думаю, что php как мера, чтобы предотвратить это.
Подтвердите

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

Источник: Как распаковать или распаковать zip-файлы в PHP?


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

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")двойные кавычки или хотя бы правильный ответ.
Николас Блазген

1
Лучше использовать системные функции PHP, чем полагаться на системные функции.
Слоан Трэшер

Как подчеркивается в принятом ответе - пожалуйста, очистите вводимые пользователем данные, любой может добавить что угодно в эту $_GETстроку запроса и ввести свой собственный код в systemвызов
jg2703
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.