Forum: PC-Programmierung Zip in PHP direkt nach String auspacken?


von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich könnte es auch einfach ausprobieren, aber vlt. weiss das hier jemand 
aus dem Stand und ich spare etwas Zeit?

Folgendes Problem: In einer MySQL-Datenbank befinden sich (als Blob), 
mit "ganz gewöhnlichem" ZIP (deflate Modus) erstellte Dateien.

Ich möchte nun die jeweils eine darin enthaltene Text-Datei, wenn 
möglich, mit PHP on-the-fly direkt in einen String-Puffer entpacken, 
ohne vorher nochmal eine Datei zu schreiben. Nach meiner (kurzen) 
Recherche konnter ich aber nur Beispiele mit Dateien finden.

Idee? Tips? Danke.

von sid (Gast)


Lesenswert?

zip heisst Du benutzt ein externes tool zum packen und entpacken
(entweder systemtool oder third party)
deflate müsste ja Phil Katz sein, richtig?

egal.. jdf kannst Du per Kommandozeile tricksen und Dir den output je 
nach benutztem tool direkt zurückgeben lassen (exec());
den output kannst Du dann in php in eine Variable schreiben.
Ich halte das aber für ein gewagtes unterfangen;
insbesondere wenn der inhalt nicht bekannt ist (oder dessen grösse)
Du könntest sonst ins memory limit rennen oder schlimmer ungewollt 
malicious code ausführen.

Temp-datei halte ich für sinnvoller wenn Du diese dann sorgsam einliesst 
zur Weiterverabeitung.

'sid

von bluppdidupp (Gast)


Lesenswert?

Diese Library könnte was für dich sein:
https://github.com/Ne-Lexa/php-zip

von Philipp K. (philipp_k59)


Lesenswert?

Ich würde mal das MYSQL Statement "DUMP INTO FILE" anschauen.

Dazu über info.php ob schon ein ZIP-Addon als Standard installiert ist.

Kommt natürlich darauf an wie groß die Zip-Dateien sind welchen Weg man 
einschlagen muss.

Nach unten Scrollen, dort sind die Beispiele.

https://www.php.net/manual/de/ziparchive.open.php

EDIT: Was aber auch gehen könnte, man macht 2 PHP-Scripts.. eines stellt 
nur dem eigenen Host das Zip aus dem Mysql bereit. Falls möglich 
versucht man dann mit Zip-Archiv Open die Url des Scriptes zu öffnen 
vorausgesetzt das URLs als Pfad auch erlaubt sind.

: Bearbeitet durch User
von DPA (Gast)


Lesenswert?

Aber Zip Dateien können doch mehrere Dateien beinhalten? Was soll den da 
raus kommen, wenn du das in einen String enzpackst? Bei {b,g,x}zip wäre 
das natürlich was anderes.

von Philipp K. (philipp_k59)


Lesenswert?

DPA schrieb:
> Aber Zip Dateien können doch mehrere Dateien beinhalten?

Ich denke der TO meint er hat ZIP Dateien auf dem server.. in den ZIPs 
ist jeweils unte randeren Dateien eine Textdatei dessen Inhalt er in PHP 
verarbeiten muss.

Er fragte jetzt wie man das am besten umsetzt.

von DPA (Gast)


Lesenswert?

Ach so.

Anscheinend kann man bei PDO lobs als files öffnen: 
https://www.php.net/manual/en/pdo.lobs.php

Aber ZipArchive nimmt ja leider keinen stream, sondern ein file...

Mein erster Gedanke waren die php:// fake files 
(https://www.php.net/manual/en/wrappers.php.php), insbesondere, aus dem 
stream einen "php://fd/X" Pfad zu konstruieren.
Aber einerseits wüsste ich nicht, wie man an einen file descriptor von 
einem lob stream kommt, und andererseits sind die glaub ich nicht 
seekable, also würde das vermutlich nicht funktionieren.

Dazu, dass die lob non-seekable sind, kommt dann noch dazu, dass der 
index der Zip Dateien am Ende steht, was eine sehr ungünstige 
Kombination ist. Einige Programme können aber anscheinend auch ohne den 
Index mit ner Pipe an die Dateien ran kommen: 
https://stackoverflow.com/questions/7132514/bash-how-to-unzip-a-piped-zip-file-from-wget-qo

Dem stackoverflow thread zufolge können bsdtar und neuere Versionen von 
"busybox unzip" sowas, das normale unzip in debian scheint nicht zu 
gehen, es gäbe auch noch funzip aber das kann nur die erste Datei.

Mit proc_open und stream_get_contents könnte das also sogar gehen: 
https://www.php.net/manual/en/function.proc-open.php

Gelesen würde eventuell aber trotzdem etwas mehr als nötig, wenn auch 
nicht unbedingt die ganze Zip datei.

Wobei, eventuell wäre es doch einfacher, in ein tmpfile zu schreiben, 
und sich den ganzen Aufwand zu sparen, oder das Konzept selbst nochmal 
zu überdenken...

von sid (Gast)


Lesenswert?

ich versteh das zip-konzept auch nicht..
n gzip blob macht von Haus aus was TO will und man spart sich das ganze 
drumrum.

aber nunja

'sid

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich erklär nochmal die Problematik:

1. Ein Zip-Archiv (bzw. viele davon) wurde als Datei-Container erstellt 
und enthält jeweils genau eine TXT-Datei. Das wurde jeweils per FTP auf 
einen Webserver hochgeladen und dort per PHP komplett in einer 
MySQL-Datenbank abgelegt.

2. Dieses ZIP-Archiv (bzw. viele dieser Art) befinden sich nun vom 
ersten bis zum letzten Bit als BLOB in der Mysql-Datenbank

Die Frage ist nun: Gelingt mir der Zugriff auf den Inhalt der Datei in 
dem ZIP-Archiv, nachem ich es mir mit einem SQL-Statement komplett in 
eine String-Variable geladen habe, ohne den Umweg über eine (temporäre) 
Datei? Die ZIP-Archive sind ca. 200 ... 300 kB, ausgepackt max. 1MB.

: Bearbeitet durch User
von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Du könntest probieren, das Archiv mit PHP zu parsen, den komprimierten 
Inhalt der Datei in einen String zu laden und diesen dann zu 
dekomprimieren, z.B. mit gzinflate() oder gzuncompress() passend zum 
Archivinhalt.

Das komplette Archiv in einen String wird nicht gehen, da alle diese 
Funktionen darauf aus sind, daß ein Archiv mehrere Dateien enthalten 
kann.

von Philipp K. (philipp_k59)


Lesenswert?

Ich finde die Idee Interessant, ich denke es könnte mit einem DB Wrapper 
funktionieren den man mit "fopen("zip://")" als Zip öffnen kann.

Kenne die möglichkeiten der Wrapper Funktionen nicht genau.

: Bearbeitet durch User
von Philipp K. (philipp_k59)


Lesenswert?

Ach das klappt nicht..

Entweder als Temp-Datei auspacken oder eine PHP-Zip Extension mit Memory 
Möglichkeit installieren.

von DPA (Gast)


Lesenswert?

Frank E. schrieb:
> nachem ich es mir mit einem SQL-Statement komplett in eine String-Variable 
geladen habe

Warum willst du dass denn tun? Dann müsste ja die ganze ZIP Datei in den 
Speicher? Das macht doch den ganzen Nutzen von (B)LOBs zunichte?

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

DPA schrieb:
> Frank E. schrieb:
>> nachem ich es mir mit einem SQL-Statement komplett in eine String-Variable
> geladen habe
>
> Warum willst du dass denn tun? Dann müsste ja die ganze ZIP Datei in den
> Speicher? Das macht doch den ganzen Nutzen von (B)LOBs zunichte?

Ich wüsste keinen anderen Weg, an die Daten in einer Datenbank 
heranzukommen, als diese mit einem Select anzufordern. Und dann landen 
die in einer Recordset-Struktur im Speicher, die ich wie eine Variable 
benutzen kann ... Ich lass mir gerne was anderes vorschlagen. An der 
Tatsache, dass die ZIPs in der Datenbak stecken, ist allerdings nicht zu 
rütteln.

: Bearbeitet durch User
von DPA (Gast)


Lesenswert?

Frank E. schrieb:
> Ich wüsste keinen anderen Weg, an die Daten in einer Datenbank
> heranzukommen, als diese mit einem Select anzufordern. Und dann landen
> die in einer Recordset-Struktur im Speicher, die ich wie eine Variable
> benutzen kann

Sorry, ich habe wohl fälschlicherweise einige nicht zutreffende Annahmen 
gemacht. Ich dachte aufgrund der Dokumentation, das würde gehen, wenn 
man mit PDO darauf zugreift: https://www.php.net/manual/en/pdo.lobs.php

Aber anscheinend gibt es da seit 11 Jahren einen alten Bug: 
https://bugs.php.net/bug.php?id=40913

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Hmmmmm kannst Du mir bitte sagen ob es irgend eine Notwendigkeit gibt, 
komplette ZIP-Archive in der Datenbank zu speichern? Oder könnte man das 
ggf. auch ändern und die Daten "anders komprimiert" in der Datenbank 
ablegen, z.B. als gzdeflate-Ausgabe ohne den ZIP-Container drum herum?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.