Unzip a file with php
Asked Answered
D

12

245

I want to unzip a file and this works fine

system('unzip File.zip');

But I need to pass in the file name through the URL and can not get it to work, this is what I have.

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

What am I missing? I know it has to be something small and stupid I am overlooking.

Thank you,

Degrading answered 17/1, 2012 at 2:38 Comment(3)
Double quotes evaluate variables; single quotes do not. BUT -- be careful, as simply passing some input to a system call could be quite dangerous.Woodshed
Must say I don't like the hostile tone of some comments. If you guys realise she's/he's missing soemthing, then just tell her/him about it. We all miss something at some point.Despondent
The error here is simple. You are trying to use string interpolation with simple quotes instead of double quotes. String interpolation does not work with simple quotes because it is used for string literals. So, changing your code to system("unzip $master.zip"); should work.Pleurodynia
A
593

I can only assume your code came from a tutorial somewhere online? In that case, good job trying to figure it out by yourself. On the other hand, the fact that this code could actually be published online somewhere as the correct way to unzip a file is a bit frightening.

PHP has built-in extensions for dealing with compressed files. There should be no need to use system calls for this. ZipArchivedocs is one option.

$zip = new ZipArchive;
$res = $zip->open('file.zip');
if ($res === TRUE) {
  $zip->extractTo('/myzips/extract_path/');
  $zip->close();
  echo 'woot!';
} else {
  echo 'doh!';
}

Also, as others have commented, $HTTP_GET_VARS has been deprecated since version 4.1 ... which was a reeeeeally long time ago. Don't use it. Use the $_GET superglobal instead.

Finally, be very careful about accepting whatever input is passed to a script via a $_GET variable.

ALWAYS SANITIZE USER INPUT.


UPDATE

As per your comment, the best way to extract the zip file into the same directory in which it resides is to determine the hard path to the file and extract it specifically to that location. So, you could do:

// 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";
}
Allyson answered 17/1, 2012 at 2:54 Comment(6)
Thank you for the advise. I am new to this and just figuring everything out. With your code, how can I get it to unzip in the same folder the zipped file is in?Degrading
Well, there is a difference between the current working directory of your script and the directory where the zip file resides. If the zip file is in the same directory as the script you could do $zip->extractTo('./'); However, this is likely not the case. A better option is to determine the zip file's location in the filesystem and extract it there. I'll update my answer to demonstrate.Allyson
What if you don't have the ZipArchive class available? I'm working on a site with crap hosting and I get the Fatal error: Class 'ZipArchive' not found error which I try this script :-( Is there any option at that point?Lyckman
@Lyckman you are going to need the underlying zlib library to perform pretty much any compress/decompress operations with PHP. Even to make system calls you'd need to have the underlying library. This is a very ubiquitous thing though, and not having it is the exception. If you're on shared hosting, they should install it for you. Otherwise, just google something like "How to Install Zip Functions Support For PHP"Allyson
Yeah, it's pretty cheap hosting as I've been told. Anyway, thanks for the reply, it's good stuff to know.Lyckman
Very nice! I used this to upload a website since I was missing the FTP password, but had access to the browser based file manager (zip, upload, create index.php to unzip and remove index.php).Berserker
A
44

Please, don't do it like that (passing GET var to be a part of a system call). Use ZipArchive instead.

So, your code should look like:

$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
}

And to answer your question, your error is 'something $var something else' should be "something $var something else" (in double quotes).

Amperehour answered 17/1, 2012 at 2:45 Comment(0)
P
17

Using getcwd() to extract in the same directory

<?php
$unzip = new ZipArchive;
$out = $unzip->open('wordpress.zip');
if ($out === TRUE) {
  $unzip->extractTo(getcwd());
  $unzip->close();
  echo 'File unzipped';
} else {
  echo 'Error';
}
?>
Pu answered 13/2, 2018 at 22:41 Comment(0)
S
9

I updated answer of @rdlowrey to a cleaner and better code, This will unzip a file into current directory using __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> 
Shepp answered 3/9, 2014 at 5:43 Comment(0)
A
6

Simply try this yourDestinationDir is the destination to extract to or remove -d yourDestinationDir to extract to root dir.

$master = 'someDir/zipFileName';
$data = system('unzip -d yourDestinationDir '.$master.'.zip');
Argentous answered 21/11, 2015 at 14:46 Comment(4)
I used yourDestinationDir as session_save_path() . DIRECTORY_SEPARATOR . "$name" . DIRECTORY_SEPARATOR where $name is target folder to unzip in session folder.Infidel
Be really careful when dealing with system or exec functions which contains variables ! It can litteraly give a free command line from your server to a hacker.Cautionary
@Cautionary How is that possible? please explain because i think php as measure to stop that from happening. Back your claims with factsArgentous
@SamuelKwameAntwi exec and system are calling the system shell, with the php user. So, if your user is www, you can do all what unix user "www" can do on the command line, including the removing of files or directories. It's really worst if your php user is root. You can find more info about it there: https://mcmap.net/q/108090/-exploitable-php-functionsCautionary
D
5

PHP has its own inbuilt class that can be used to unzip or extracts contents from a zip file. The class is ZipArchive. Below is the simple and basic PHP code that will extract a zip file and place it in a specific directory:

<?php
$zip_obj = new ZipArchive;
$zip_obj->open('dummy.zip');
$zip_obj->extractTo('directory_name/sub_dir');
?>

If you want some advance features then below is the improved code that will check if the zip file exists or not:

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

Source: How to unzip or extract zip files in PHP?

Dated answered 14/10, 2017 at 17:33 Comment(0)
P
3

Simple PHP function to unzip. Please make sure you have zip extension installed on your server.

/**
 * 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;
    }
}
Perak answered 7/9, 2019 at 13:1 Comment(0)
L
1

Just change

system('unzip $master.zip');

To this one

system('unzip ' . $master . '.zip');

or this one

system("unzip {$master}.zip");

Landslide answered 22/10, 2014 at 22:10 Comment(1)
While this may fix the issue he was having, have a look at the other answers to see why this is bad advice.Conscription
L
1

I updated answer of Morteza Ziaeemehr to a cleaner and better code, This will unzip a file provided within form into current directory using 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> 
Lyris answered 2/4, 2016 at 6:3 Comment(0)
C
1

you can use prepacked function

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

How to use it.

if(unzip_file($file["name"],'uploads/')){
echo 'zip archive extracted successfully';
}else{
  echo 'zip archive extraction failed';
}
Commentative answered 17/10, 2016 at 10:15 Comment(0)
O
1

Use below PHP code, with file name in the URL param "name"

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

?>
Ovotestis answered 1/4, 2017 at 14:41 Comment(0)
R
-3

Just use this:

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

in your code $master is passed as a string, system will be looking for a file called $master.zip

  $master = $_GET["master"];
  system('unzip $master.zip'); `enter code here`
Rakel answered 16/3, 2015 at 13:5 Comment(3)
Just completely wrong. 'unzip' $master wouldn't work unless you added a space after unzip and added a period after the single quote. Would have been just much easier to suggest system("unzip $master.zip") with double quotes, or at least a valid answer.Ymir
It's better to use the PHP system functions than to rely on system functions.Mou
As stressed in the accepted answer - please sanitize user input, anyone can add anything to this $_GET query string and inject their own code to the system callPrelacy

© 2022 - 2024 — McMap. All rights reserved.