Tutorials
Einige nützliche Hilfen und Code-Schnipsel, die ich immer wieder benötige und deshalb hier für alle sammle.
Zurück zur Übersicht
Ordner rekursiv mit Php zu einer Zip-Datei packen
#Tutorials#PHP
Hat man auf einem Webspace keinen SSH-Zugriff, kommt man schnell an die Grenzen des Machbaren. So lassen sich leider nicht so leicht Backups erstellen.
Aber Php bietet auch eine Möglichkeit ganze Ordner zu einer Zip-Datei zu packen. Das Ganze geht wie folgt:
<?
// die maximale Ausführzeit erhöhen
ini_set("max_execution_time", 300);
// Objekt erstellen und schauen, ob der Server zippen kann
$zip = new ZipArchive();
if ($zip->open("backup.zip", ZIPARCHIVE::CREATE) !== TRUE) {
die ("Could not open archive");
}
// Gehe durch die Ordner und füge alles dem Archiv hinzu
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("folder/"));
foreach ($iterator as $key=>$value) {
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
// speicher die Zip-Datei
$zip->close();
echo "Archive erfolgreich erstellt.";
?>
Ich hoffe ich konnte euch damit weiterhelfen ;)
Jon aus den Kommentaren hier, hat die Funktion genommen und verbessert. Hier ist sein Code zu finden:
Kommentare
Jemand eine Idee?
Der Code ist Top.
Jetzt bräuchte ich noch eine Erweiterung das die Zip-Datei vom Web-Server auf einen Localen QNAP-Server übertragen wird. (zum Beispiel:Jeden Tag um 03:00 Uhr)
Hast Du vielleicht eine Idee.
Gruß Gerold
bei mir haut leider was nicht hin. Ich habe am Ende des Skripts (vor $zip->close();) mal ein var_dump($zip); eingefügt und die Ausgabe sieht vielversprechend aus:
object(ZipArchive)#1 (5) { ["status"]=> int(0) ["statusSys"]=> int(0) ["numFiles"]=> int(9520) ["filename"]=> string(45) "/var/www/user/html/domain/backup.zip" ["comment"]=> string(0) "" } Archive erfolgreich erstellt.
Ich sehe 9520 Dateien und den korrekten Pfadnamen. Das Problem ist nur, die Datei backup.zip existiert nicht. Sie wird nicht erstellt. Sollte das Skript in dem Fall aber nicht vorher schon abbrechen?
Grüße
Jon
Auf meinem Webhoster leider nicht mehr. Damit es das tut, müssen, wie auch so ähnlich schon oben beschrieben, die Ordner ".." und "." explizit ausgeschlossen werden.
Die obigen Lösungen funktionieren bei mir nicht unmittelbar, da es hier leider keine Code Umgebung im Kommentar gibt und damit die Hochkommas nicht funktionieren.
Meine Lösung sieht derzeit so aus:
foreach ($iterator as $key=>$value) {
// ordner ".." und "." ignorieren
if(substr($key, -2)!=".." && substr($key, -1)!=".")
{
$zip->addFile(realpath($key), $key) or die ("ERROR: Kann Datei nicht anfuegen: $key");
}
}
Was leider noch nicht klappt, sind leere Ordner. Die werden bisher ausgelassen und rekursives Blacklisting von Ordnern. Eine einzelne Datei lässt sich wie oben beschrieben mit einem Array blacklisten. Bei einem Ordner mit Unterordern klappt es so noch nicht.
Wenn ich Ordner "foo/bar" blackliste und den in_array() Vergleich durchführe, dann würde eine Datei "foo/bar/goo.css" nicht matchen und ins ZIP übernommen.
Nach meinen Tests wird damit alles ins Archiv übernommen. Auch leere Dateien und Ordner. Auch so "verrückte" Namen wie foo.. oder A. Die Ordner . und .. werden dagegen ausgelassen.
[code]
foreach ($iterator as $key=>$value) {
// ist es ein ordner?
if(!is_dir($key)) { // nein
$zip->addFile(realpath($key), $key) or die ("ERROR: Kann Datei nicht anfuegen: $key");
}
// ist der ordner leer?
elseif (count(scandir($key)) addEmptyDir(substr($key, -1*strlen($key),strlen($key)-1));
}
}
[/code]
Vielen Dank für die Inspiration. :)
Hier noch ein mal.
(Leider müssen alle Hochkommas manuell korrigiert werden, weil das hier irgendwie automatisch ersetzt wird.)
[code]
foreach ($iterator as $key=>$value) {
// ist es ein ordner?
if(!is_dir($key)) { // nein
$zip->addFile(realpath($key), $key) or die („ERROR: Kann Datei nicht anfuegen: $key“);
}
// ist der ordner leer?
elseif (count(scandir($key)) addEmptyDir(substr($key, -1*strlen($key),strlen($key)-1));
}
}
[/code]
http://pastebin.com/YbUbebBK
Btw.:
Wäre vielleicht keine schlechte Idee auf einer Seite, die sich auch mit Softwareentwicklung befasst, einen BBCode für [code] in den Kommentaren zu erlauben.
Cheers jd ;-)
Danke!
Grüße
André
Ich hatte zum ersten mal Pastbin benutzt und hatte es als Gast gepostet, was nicht veränderbar ist. Deswegen habe ich mir da einen Account gemacht und kann so Verbesserungen einpflegen.
Wegen den Kommentaren. Ich kenne mich nicht aus mit Wordpress, aber ne Suche nach "wordpress kommentar mit syntax highlighting" führte mich direkt zu: https://de.wordpress.org/plugins/syntax-highlighter-for-wp-editor/
Das sieht schon vielversprechend aus. Bzw. einfach mal in den Plugins dort nach Syntax Highlighting suchen. Da gibt's bestimmt noch mehr.
Aber ich weiß nicht, ob es das Problem löst, dass die Validierungsfunktionen dieses Textfeldes bestimmte Codesequenzen filtert. Müsste man probieren.
Ich hab mich jetzt erneut angemeldet ;-) und mal meine persönliche Endversion gepostet:
http://pastebin.com/1qmUyWYc
Getestet habe ich es neben einem Testordner an ca. 10.000 Dateien/Ordnern einer Joomla Installation. Dauerte ca. 40s auf dem Server und ist einwandfrei geworden. Wirklich ne super Sache für Backups, wenn man keinen Shell Zugang beim Hoster hat.
Vielen Dank noch mal für die Vorlage. Ich habe dich da auch erwähnt. ;)
danke für den tollen Ansatz. Das Script läuft ohne Fehlermeldung durch, meldet Vollzug - ABER: Ich kann kein fertiges zip auf dem Server finden?!
Ich fange den string $key ab und prüfe, ob ein Punkt am Ende steht...
foreach ($iterator as $key=>$value) {
if(substr($key,-1) != ".")
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
Gruß
ja auch ich habe das gleiche Problem. In der gezippten Datei sind zwar alle Dateien drin, die ich haben wollte, ABER es sind ganz oben in der Liste zwei weitere Verzeichnisse zu sehen. Das eine mit einem Punkt, das zweite mit zwei Punkten.
Beim Entzippen kommt es sodann zu einem Fehler.
Gruß
Ich habe jedoch ein anderes Problem. Die erstellte ZIP-Datei kann nach dem Download unter Win7 nicht geöffnet werden (das Fenster erschein leer) obwohl die ZIP-Datei 66,6MB groß ist. Unter MacOS bekomme ich die Datei mit einem Zusatzprogramm geöffnet, welches mir mitteilt, dass Ordern, die auf . oder .. enden nicht entpackt werden können. Okay, also Filter eingebaut und $key per echo ausgegeben. In der Anzeige erscheinen keine Ordner mehr mi . oder .. .... AAABER wenn ich nun wieder entzogen möchte, habe ich das gleiche Drama wie zuvor, plötzlich sind die . und .. Ordner doch in der ZIP-Datei drin...
// die maximale Ausführzeit erhöhen
ini_set("max_execution_time", 500);
// Objekt erstellen und schauen, ob der Server zippen kann
$zip = new ZipArchive();
if ($zip->open("backup/moodledata.zip", ZIPARCHIVE::CREATE) !== TRUE) {
die ("Kann Archiv nicht oeffnen");
}
// Gehe durch die Ordner und füge alles dem Archiv hinzu
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("/home/www/xyz/files/moodledata/"));
foreach ($iterator as $key=>$value)
{
if(substr($key, -2)!="..")
{
if(substr($key, -1)!=".")
{
echo $key."";
$zip->addFile(realpath($key), $key) or die ("ERROR: Kann Datei nicht anfuegen: $key");
}
}
}
// speichert die Zip-Datei
$zip->close();
Hast Du evtl. einen Tipp für mich, was der Grund sein könnte?
Grüße Julian
Aber vielleicht kommt auch nach dieser Zeit noch jemand auf diese Seite (so wie ich), den die Lösung interessiert.
Wie auch immer: Ich hatte das gleiche Problem wie Julian.
Die Ursache war bei mir, dass ich die erstellte ZIP-Datei als ASCII heruntergeladen habe. Diese Datei ließ sich dann nicht entpacken.
Wenn man im FTP-Programm als Übertragungstyp binär oder automatisch wählt, klappt anschließend das Entpacken der ZIP-Datei.
Grüße und danke für das Script!
$blacklist = array('index.php,.htaccess,zip.php');
...
if(!in_array($key,$blacklist)) {
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
habe ich da etwas übersehen oder falsch geschrieben?
Grüße
$blacklist = array(‘index.php,.htaccess,zip.php’);
$blacklist = array(‘index.php', '.htaccess,zip.php’);
Grüße
André
http://www.jacobbates.com/blog/2012/04/24/corrupt-zip-files-in-windows-from-phps-ziparchive/
Grüße
nur möchte ich einen Ordner mit .xls Files zippen und wenn ich den Ordnerpfad direkt einbinde , klappts nicht.
(ordner realtiv ../../excelFiles/ )
Weiterhin zeigt er mir bei Windows ein korruptes Verzeichnis an, woran könnte das liegen ?
Grüße
Ich habe dazu noch eine Frage. Ist es möglich, das Archiv auf der selben Ebene zu beginnen zu lassen. Dein Script liegt bei mir in httpdocs, weil ich es nur so aufrufen kann. Ich würde gern den gesamten httpdocs-Ordner sichern. Es müssten also sozusagen die Dateien gesichert werden, die parallel zur Scriptdateien liegen und alle Unterordner.
Grüße
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("folder/"));
das "folder/" durch ein "./" zu ersetzen. Das heißt ja das jetzige Directory. Vielleicht geht das.
Grüße
Die Varianten * und . und ../ habe ich auch schon probiert.
Grüße
André
Grüße
kann ich auch Ordner ausschließen und wenn ja wie?
Gruß und Danke
ich würde hierfür ein Array machen mit Ordnern oder Dateinamen, die auf der Blacklist sind. Also
$blacklist = array('Order1, index2.html,...');
Dann müsste es eigentlich reichen, wenn du in Zeile 14 dann guckst, ob das was gerade an der Reihe in der Blacklist ist und wenn nicht dann wird es zum Zip hinzugefügt.
Also ca so:
if(!in_array($key,blacklist) { ...}
Grüße
André
Grüße
Hier der Link: http://home.mborm.net/mbblog/zip.php
$zip = new ZipArchive;
var_dump($zip);
Wenn das leer ist, oder einen Fehler wirft, dann kann dein Server womöglich gar keine Zips erstellen.
Grüße
Die Ausgabe lautet:
object(ZipArchive)#1 (5) { ["status"]=> int(0) ["statusSys"]=> int(0) ["numFiles"]=> int(0) ["filename"]=> string(0) "" ["comment"]=> string(0) "" }
Grüße
Hinterlasse einen Kommentar