Entpacke eine Datei mit PHP

198

Ich möchte eine Datei entpacken und das funktioniert gut

system('unzip File.zip');

Aber ich muss den Dateinamen über die URL übergeben und kann ihn nicht zum Laufen bringen, das ist was ich habe.

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

Was vermisse ich? Ich weiß, dass es etwas Kleines und Dummes sein muss, das ich übersehen habe.

Danke dir,

BostonBB
quelle
35
Doppelte Anführungszeichen bewerten Variablen; einfache Anführungszeichen nicht. ABER - seien Sie vorsichtig, da es ziemlich gefährlich sein kann, einfach eine Eingabe an einen Systemaufruf zu übergeben.
Wiseguy
25
Ich muss sagen, ich mag den feindlichen Ton einiger Kommentare nicht. Wenn ihr merkt, dass ihr etwas fehlt, dann erzählt ihr / ihm einfach davon. Wir alle vermissen irgendwann etwas.
Sebastian Mach
Der Fehler hier ist einfach. Sie versuchen, die Zeichenfolgeninterpolation mit einfachen Anführungszeichen anstelle von doppelten Anführungszeichen zu verwenden. Die String-Interpolation funktioniert nicht mit einfachen Anführungszeichen, da sie für String-Literale verwendet wird. Das Ändern Ihres Codes in system("unzip $master.zip");sollte also funktionieren.
Asier Paz

Antworten:

500

Ich kann nur annehmen, dass Ihr Code aus einem Online-Tutorial stammt. In diesem Fall gute Arbeit, um es selbst herauszufinden. Andererseits ist die Tatsache, dass dieser Code tatsächlich irgendwo online veröffentlicht werden könnte, um eine Datei korrekt zu entpacken, etwas beängstigend.

PHP verfügt über integrierte Erweiterungen für den Umgang mit komprimierten Dateien. Hierfür sollten keine systemAnrufe erforderlich sein . ZipArchivedocs ist eine Option.

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

Wie andere kommentiert haben, $HTTP_GET_VARSist es seit Version 4.1 veraltet ... was vor sehr langer Zeit war. Benutze es nicht. Verwenden $_GETSie stattdessen das Superglobale.

Seien Sie schließlich sehr vorsichtig, wenn Sie akzeptieren, welche Eingaben über eine $_GETVariable an ein Skript übergeben werden .

BENUTZEN SIE DEN BENUTZEREINGANG IMMER.


AKTUALISIEREN

Gemäß Ihrem Kommentar können Sie die Zip-Datei am besten in dasselbe Verzeichnis extrahieren, in dem sie sich befindet, indem Sie den festen Pfad zur Datei bestimmen und sie speziell an diesen Speicherort extrahieren. Sie könnten also Folgendes tun:

// 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
quelle
Vielen Dank für den Rat. Ich bin neu in diesem Bereich und finde einfach alles heraus. Wie kann ich Ihren Code dazu bringen, ihn in demselben Ordner zu entpacken, in dem sich die komprimierte Datei befindet?
BostonBB
2
Nun, es gibt einen Unterschied zwischen dem aktuellen Arbeitsverzeichnis Ihres Skripts und dem Verzeichnis, in dem sich die Zip-Datei befindet. Wenn sich die Zip-Datei im selben Verzeichnis befindet wie das Skript, das Sie ausführen könnten $zip->extractTo('./');, ist dies jedoch wahrscheinlich nicht der Fall. Eine bessere Option besteht darin, den Speicherort der Zip-Datei im Dateisystem zu bestimmen und dort zu extrahieren. Ich werde meine Antwort aktualisieren, um zu demonstrieren.
Rdlowrey
Was ist, wenn Sie die ZipArchive-Klasse nicht zur Verfügung haben? Ich arbeite an einer Site mit Misthosting und erhalte die Fatal error: Class 'ZipArchive' not foundFehlermeldung, dass ich dieses Skript versuche :-( Gibt es zu diesem Zeitpunkt eine Option?
CWSpear
2
@CWSpear Sie benötigen die zugrunde liegendezlib Bibliothek, um so ziemlich alle Komprimierungs- / Dekomprimierungsvorgänge mit PHP auszuführen. Selbst um Systemaufrufe zu tätigen, benötigen Sie die zugrunde liegende Bibliothek. Dies ist jedoch eine sehr allgegenwärtige Sache, und es ist die Ausnahme, sie nicht zu haben. Wenn Sie Shared Hosting verwenden, sollten diese es für Sie installieren. Andernfalls googeln Sie einfach etwas wie "So installieren Sie die Unterstützung für Zip-Funktionen für PHP"
rdlowrey
Ja, es ist ziemlich billiges Hosting, wie mir gesagt wurde. Wie auch immer, danke für die Antwort, es ist gut zu wissen.
CWSpear
37

Bitte machen Sie es nicht so (übergeben Sie GET var, um Teil eines Systemaufrufs zu sein). Verwenden Sie stattdessen ZipArchive .

Ihr Code sollte also folgendermaßen aussehen:

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

Und um Ihre Frage zu beantworten, lautet Ihr Fehler "etwas $ var etwas anderes" "etwas $ var etwas anderes" (in doppelten Anführungszeichen).

Aleksandar Vucetic
quelle
3
+1 Ups, tut mir leid, dass ich fünf Minuten später im Grunde die gleiche Antwort angepackt habe.
Ich habe
10

Verwenden Sie getcwd()zum Extrahieren im selben Verzeichnis

<?php
$unzip = new ZipArchive;
$out = $unzip->open('wordpress.zip');
if ($out === TRUE) {
  $unzip->extractTo(getcwd());
  $unzip->close();
  echo 'File unzipped';
} else {
  echo 'Error';
}
?>
Rubyx
quelle
5

Versuchen Sie einfach, dass yourDestinationDir das Ziel ist, in das -d yourDestinationDir extrahiert oder entfernt werden soll , um es in das Stammverzeichnis zu extrahieren.

$master = 'someDir/zipFileName';
$data = system('unzip -d yourDestinationDir '.$master.'.zip');
Samuel Kwame Antwi
quelle
1
Ich habe yourDestinationDirals session_save_path() . DIRECTORY_SEPARATOR . "$name" . DIRECTORY_SEPARATOR wo $nameist Zielordner zum Entpacken in Sitzungsordner verwendet.
Ramratan Gupta
1
Seien Sie sehr vorsichtig beim Umgang mit System- oder Exec-Funktionen, die Variablen enthalten! Es kann einem Hacker eine kostenlose Befehlszeile von Ihrem Server geben.
Maxime
@maxime Wie ist das möglich? Bitte erklären Sie, weil ich PHP als Maßnahme denke, um dies zu verhindern. Unterstützen Sie Ihre Behauptungen mit Fakten
Samuel Kwame Antwi
@SamuelKwameAntwi exec und system rufen die System-Shell mit dem PHP-Benutzer auf. Wenn Ihr Benutzer www ist, können Sie alles tun, was der Unix-Benutzer "www" in der Befehlszeile tun kann, einschließlich des Entfernens von Dateien oder Verzeichnissen. Es ist wirklich schlimm, wenn Ihr PHP-Benutzer root ist. Weitere Informationen dazu finden Sie dort: stackoverflow.com/questions/3115559/exploitable-php-functions
maxime
5

Ich habe die Antwort von @rdlowrey auf einen saubereren und besseren Code aktualisiert. Dadurch wird eine Datei mit in das aktuelle Verzeichnis entpackt __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> 
Morteza Ziyae
quelle
2

PHP verfügt über eine eigene integrierte Klasse, mit der Inhalte aus einer Zip-Datei entpackt oder extrahiert werden können. Die Klasse ist ZipArchive. Unten finden Sie den einfachen und grundlegenden PHP-Code, mit dem eine Zip-Datei extrahiert und in einem bestimmten Verzeichnis abgelegt wird:

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

Wenn Sie einige erweiterte Funktionen wünschen, finden Sie unten den verbesserten Code, mit dem überprüft wird, ob die Zip-Datei vorhanden ist oder nicht:

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

Quelle: Wie entpacke oder extrahiere ich Zip-Dateien in PHP?

Faruque Ahamed Mollick
quelle
0

Ich habe die Antwort von Morteza Ziaeemehr auf einen saubereren und besseren Code aktualisiert. Dadurch wird eine im Formular bereitgestellte Datei mit DIR in das aktuelle Verzeichnis entpackt .

<!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> 
Varun Naharia
quelle
0

Nur ändern

system('unzip $master.zip');

Zu diesem

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

oder dieses

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

sh4nn0nb1t
quelle
6
Dies kann zwar das Problem beheben, das er hatte, aber schauen Sie sich die anderen Antworten an, um herauszufinden, warum dies ein schlechter Rat ist.
rjdown
0

Sie können die vorgefertigte Funktion verwenden

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

Wie man es benutzt.

if(unzip_file($file["name"],'uploads/')){
echo 'zip archive extracted successfully';
}else{
  echo 'zip archive extraction failed';
}
user889030
quelle
0

Verwenden Sie den folgenden PHP-Code mit dem Dateinamen im URL-Parameter "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';
}

?>
huync
quelle
0

Einfache PHP-Funktion zum Entpacken. Bitte stellen Sie sicher, dass auf Ihrem Server eine Zip-Erweiterung installiert ist.

/**
 * 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
quelle
-3

Verwenden Sie einfach dies:

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

Wenn Ihr Code $masterals Zeichenfolge übergeben wird, sucht das System nach einer Datei mit dem Namen$master.zip

  $master = $_GET["master"];
  system('unzip $master.zip'); `enter code here`
Dennis Kiptugen
quelle
5
Einfach völlig falsch. 'unzip' $masterwürde nur funktionieren, wenn Sie nach dem Entpacken ein Leerzeichen und nach dem einfachen Anführungszeichen einen Punkt hinzugefügt haben. Wäre system("unzip $master.zip")mit doppelten Anführungszeichen oder zumindest einer gültigen Antwort viel einfacher vorzuschlagen gewesen .
Nicholas Blasgen
1
Es ist besser, die PHP-Systemfunktionen zu verwenden, als sich auf Systemfunktionen zu verlassen.
Sloan Thrasher
Wie in der akzeptierten Antwort betont - bitte bereinigen Sie die Benutzereingaben, kann jeder dieser $_GETsystem
Abfragezeichenfolge