Розпакуйте файл із php


198

Я хочу розпакувати файл, і це добре працює

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

Дякую за пораду. Я новачок у цьому і просто все з'ясовую. Як з допомогою вашого коду я можу змусити його розпаковувати в тій же папці, в якій знаходиться заархівований файл?
BostonBB

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

Що робити, якщо у вас немає класу ZipArchive? Я працюю над сайтом з дерьмовим хостингом, і я отримую Fatal error: Class 'ZipArchive' not foundпомилку, яку я пробую в цьому сценарії :-( Чи є в цьому місці варіант?
CWSpear

2
@CWЗверніть, що вам знадобитьсяzlib бібліотека, що виконується в основному, для виконання будь-яких операцій стиснення / декомпресії з PHP Навіть для здійснення системних дзвінків вам потрібно мати базову бібліотеку. Це дуже всюдисуща річ, і виняток не має. Якщо ви перебуваєте на спільному хостингу, вони повинні встановити його для вас. В іншому випадку просто google щось на кшталт "Як встановити підтримку функцій Zip для PHP"
rdlowrey

Так, мені досить дешево хостинг. У будь-якому випадку, дякую за відповідь, це добре знати.
CWSпошукайте

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
}

А щоб відповісти на ваше запитання, ваша помилка «щось $ вар щось інше» має бути «щось $ вар щось інше» (у подвійних лапках).


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 для вилучення з root dir.

$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 і система викликають системну оболонку з користувачем php. Отже, якщо ваш користувач www, ви можете зробити все те, що може зробити Unix користувач "www" у командному рядку, включаючи видалення файлів чи каталогів. Це справді найгірше, якщо ваш користувач php root. Ви можете знайти більше інформації про це там: stackoverflow.com/questions/3115559/exploitable-php-functions
максимум

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

Якщо ви хочете отримати деякі додаткові функції, то нижче наведений вдосконалений код, який перевірить, чи існує поштовий файл чи ні:

<?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?


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, ніж покладатися на системні функції.
Sloan Thrasher

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