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

199

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

system('unzip File.zip');

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

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

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

Спасибо,

BostonBB
источник
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";
}
rdlowrey
источник
Спасибо за совет. Я новичок в этом и просто выясняю все. С вашим кодом, как я могу разархивировать его в ту же папку, в которой находится 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';
}
?>
Rubyx
источник
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");

sh4nn0nb1t
источник
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';
}
user889030
источник
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';
}

?>
huync
источник
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;
    }
}
M_R_K
источник
-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