PHP로 파일 압축 해제


198

파일의 압축을 풀고 싶습니다.

system('unzip File.zip');

그러나 URL을 통해 파일 이름을 전달해야하며 작동하지 못합니다. 이것이 내가 가진 것입니다.

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

내가 무엇을 놓치고 있습니까? 나는 그것이 간과하고있는 어리 석고 어리석은 것이되어야한다는 것을 안다.

감사합니다,


35
큰 따옴표는 변수를 평가합니다. 작은 따옴표는 그렇지 않습니다. 그러나 시스템 호출에 일부 입력을 전달하는 것은 매우 위험 할 수 있으므로주의하십시오.
Wiseguy

25
내가 언급 한 적대적인 말이 마음에 들지 않는다고 말해야합니다. 당신이 그녀가 그녀가 빠진 것을 알고 있다면, 그 / 그녀에게 그것에 대해 이야기하십시오. 우리는 어느 시점에서 무언가를 놓칩니다.
Sebastian Mach

여기서 오류는 간단합니다. 큰 따옴표 대신 간단한 따옴표로 문자열 보간을 사용하려고합니다. 문자열 보간은 문자열 리터럴에 사용되므로 간단한 따옴표로 작동하지 않습니다. 따라서 코드를 변경 system("unzip $master.zip");하면 작동합니다.
Asier Paz

답변:


500

코드가 온라인 어딘가의 자습서에서 온 것으로 가정 할 수 있습니까? 이 경우, 좋은 직업은 스스로 알아내는 것입니다. 다른 한편으로, 파일을 압축 해제하는 올바른 방법으로이 코드를 실제로 온라인 어딘가에 게시 할 수 있다는 사실은 약간 두렵습니다.

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변수 를 통해 스크립트에 전달 된 입력을 받아 들일 때 매우주의 하십시오.

항상 SANITIZE 사용자 입력.


최신 정보

귀하의 의견에 따라 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
@CWSpear PHP로 압축 / 압축 해제 작업을 수행 하려면 기본zlib 라이브러리 가 필요합니다 . 시스템 호출을하려면 기본 라이브러리가 있어야합니다. 그러나 이것은 매우 보편적 인 것이며 예외가 아닙니다. 공유 호스팅을 사용하는 경우 설치해야합니다. 그렇지 않으면, "PHP를위한 Zip 함수 지원을 설치하는 방법"과 같은 구글
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 죄송합니다. 기본적으로 5 분 후에 같은 답변을해서 죄송합니다. 거기에서 당신을 보지 못했습니다 :)
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
Ramratan Gupta

1
변수가 포함 된 시스템 또는 exec 함수를 다룰 때 실제로주의하십시오! 서버에서 해커에게 무료 명령 줄을 제공 할 수 있습니다.
maxime

@maxime 어떻게 가능합니까? PHP가 그 일을 막는 척도로 생각하기 때문에 설명하십시오. 사실 당신의 주장을 백업
사무엘 콰미 Antwi에게

@SamuelKwameAntwi exec와 시스템은 PHP 사용자와 함께 시스템 쉘을 호출합니다. 따라서 사용자가 www 인 경우 파일 또는 디렉토리 제거를 포함하여 명령 행에서 UNIX 사용자 "www"가 수행 할 수있는 모든 것을 수행 할 수 있습니다. PHP 사용자가 루트 인 경우 정말 최악입니다. 여기에 대한 자세한 정보를 찾을 수 있습니다. 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입니다. 다음은 zip 파일을 추출하여 특정 디렉토리에 저장하는 단순하고 기본적인 PHP 코드입니다.

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

출처 : PHP에서 zip 파일의 압축을 풀거나 추출하는 방법은 무엇입니까?


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

URL 매개 변수 "name"에 파일 이름과 함께 아래 PHP 코드를 사용하십시오.

<?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")큰 따옴표 또는 최소한 유효한 답변 으로 제안하는 것이 훨씬 쉬웠을 것입니다.
Nicholas Blasgen 1

1
시스템 기능에 의존하는 것보다 PHP 시스템 기능을 사용하는 것이 좋습니다.
슬론 스레 셔

허용 된 답변에서 강조한 것처럼- 사용자 입력을 삭제 하십시오.$_GETsystem
누구나이
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.