Распакуйте файл с помощью 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.