PHP-FTP upload bei großen Dateien
Hans
- php
Hallo,
Ich habe ein kleines PHP-Uploadscript, welches mit den standartisierten Uploadfunktionen Dateien auf meinen Server übertragen kann.
nach dem schema: $upload = ftp_put($conn_id, "$destination_file", "$source_file", FTP_BINARY);
funktioniert eigentlich auch, nur bei größeren Dateien
bricht der server wegen zeitüberschreitung ab.
Kann ich da irgendwas umbauen, so dass es funktioniert?
Danke!
Hans
Eine Zeitüberschreitung hat doch aber mit dem php-Skript nix zu tun. Anscheinend ist deine Upload-Performance (seitens Provider, DSL oder ServerHost) schlecht. Das solltest du evtl. mal mit Speedmeter.de überprüfen... mfg
Moin erik,
»» Eine Zeitüberschreitung hat doch aber mit dem php-Skript nix zu tun. Anscheinend ist deine Upload-Performance (seitens Provider, DSL
u.U. doch. Es kann einen Script- oder CGI Timeout geben.
Das könnte weiterhelfen set_time_limit(0); und oder den CGI Timeout hoch setzen.
regds
Mike©
u.U. doch. Es kann einen Script- oder CGI Timeout geben.
Das könnte weiterhelfen set_time_limit(0); und oder den CGI Timeout hoch setzen.
Na dann hab ich wenigstens wieder was dazugelernt...
Moin!
Kann ich da irgendwas umbauen, so dass es funktioniert?
Wenn Dein Hoster das zulässt kannst Du die Werte höhersetzen. Das geht zum einen mit ini_set(variable,wert), zum anderen durch Einstellen der Wert-Value-Paare aus der PHP.ini in die .htaccess - Datei.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Hallo,
danke für die Antworten erstmal...
wäre es nicht möglich, den upload sozusagen aufzuspalten und z.B. je 100 kb direkt nacheinander upzuloaden und nicht 1mb auf einmal?
die einzelnen parts könnten so durch eine automatische weiterleitung
geladen werden, so dass die zeit nicht überschritten wird.
Gibt es eine FTP-Spaltungsfkt. bei PHP?
Danke!
Moin!
Gibt es eine FTP-Spaltungsfkt. bei PHP?
Du kannst Dateien nach Belieben splitten. Das geht mit einer ganzen Anzahl von 'text'-Funktionen.
Es gibt aber eine weitere Möglichkeit: system() - Hier die Beschreibung wie in etwas es auf einem UNIX/Linux-System aussehen könnte:
system("shellsript.sh 1> logfile.txt 2> errors.txt &");
... bewirkt, dass das Shellskript von der aktuellen Shell "abgehangen" im Hintergrund ausgeführt wird. Die Rückgaben werden nach logfile geschrieben und stehen so einer künftigen Verwendung zur Verfügung. Zum Bleistift könnte man eine Auswertungs-Seite aller paar Sekunden neu laden und warten, bis in der letzten Zeile vom logfile.txt 'EOT' steht oder Fehler in errors.txt auftauchen.
Die Datei errors.txt sollte beim Laden (so sie existiert: keine Fehler-> keine Datei) also mit ausgewertet werden.
shellscript sh: (Mit Zeilenumbrüchen, aber ohne weitere Leerzeilen am Beginn):
#! /bin/sh
cut ftpskript | ftp server.tld
echo -ne '\nEOT'
ftpskript (Mit Zeilenumbrüchen, aber ohne weitere Leerzeilen am Beginn):
DeinPasswordAufDemServer
cd DeinUploadDir
put Datei
bye
Voraussetzung ist, dass ein FTP-Client existiert und dass Du diesen ausführen darfst.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Hallo,
danke, aber ich darf keinen FTP-Client ausführen.
Ich hab da noch ne Idee: Wie wäre es, wen ich eine Datei öffne, ichren "Code" Zeile für Zeile, bzw. z.B. 10 Zeilen auf einmal auslese, und dann auf dem Server in einer Datei speichere?
Müsste doch gehen?
Bzw, muss man da aufpassen ob die Datei binär etc. übertragen werden muss?
Danke!
Hans
Moin!
danke, aber ich darf keinen FTP-Client ausführen.
Geht es auch anders? Zum Bleistift mit scp? Das Verfahren wäre prinzipiell gleich.
Ich hab da noch ne Idee: Wie wäre es, wen ich eine Datei öffne, ichren "Code" Zeile für Zeile, bzw. z.B. 10 Zeilen auf einmal auslese, und dann auf dem Server in einer Datei speichere?
Müsste doch gehen?
Zeilenweise? Wielange soll das denn dauern?
Bzw, muss man da aufpassen ob die Datei binär etc. übertragen werden muss?
-> http://de3.php.net/manual/de/ref.ftp.php
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
hallo,
muss mal gucken wegen scp, weiß nicht, ob der Hoster das erlaubt.
Man könnte doch anstatt zeilenweisen auch byteweise vorgehen, oder?
z.B. immer 100kb nacheinander...
MfG Hans
echo $begrüßung;
system("shellsript.sh 1> logfile.txt 2> errors.txt &");
... bewirkt, dass das Shellskript von der aktuellen Shell "abgehangen" im Hintergrund ausgeführt
Hast du mal probiert, ob das auch funktioniert/stimmt?
echo "$verabschiedung $name";
Moin!
Hast du mal probiert, ob das auch funktioniert/stimmt?
Extra für Dich habe ich das jetzt gemacht. Ich nehme richtig an, Du hast es nicht hinbekommen?
system("shellsript.sh 1> logfile.txt 2> errors.txt &");
Tut es prinzipiell. Voraussetzungen: shellscript.sh ist auführbar und in das Verzeichnis in $PATH.
Sonst meinetwegen:
system("./shellsript.sh 1> logfile.txt 2> errors.txt &");
Wie man an einer Unix-Shell Skripte aufruft sollte jedem klar sein, der es tut. Darüber hinaus ist auf unterschiedlichen Unix/Linux-Systemen für normale Benutzer das aktuelle Verzeichnis (".") im Pfad oder nicht. Warum es das für den root hoffentlich nicht ist, erkläre ich Dir gerne für viel Geld.
Test unter http://fastix.dyndns.org/shell/
(Absichtlich kein Link! Quelltexte an Ort und Stelle.)
Kommen wir zum Skript und zum ftp.skript:
shellscript sh: (Mit Zeilenumbrüchen, aber ohne weitere Leerzeilen am Beginn):
#! /bin/sh
cut ftpskript | ftp ftp://user:passwort@server.tld
echo -ne '\nEOT'
ftpskript (Mit Zeilenumbrüchen, aber ohne weitere Leerzeilen am Beginn):
cd DeinUploadDir
put Datei
bye
Einige FTP-Clients lassen sich scheinbar nicht das Passwort von hinten durch das Rohr reinblasen- offenbar um das Passwort nicht in der Prozessliste zu kompromittieren- das wird es aber dennoch, wenn man es wie beschrieben aufruft. Mit dem Rest geht es wohl. Hab es grade getestet. Das sind aber jetzt nur marginale Syntax-Fehlerchen. Wenn prinzipilelle Lösungen gesucht werden, dann sollte auch berücksichtigt werden, das nicht wegen jeder kleinen Lösung gleich ein Riesen-Versuchsaufbau gemacht werden kann und das eventuelle kleine Problemchen mit der Syntax selbst zu erkennen sind- oder?
Warum ich im Gegensatz zu manch über Windows und Webserver gar nicht erst nachdenke sollte Dir klar sein. Für diese Art von Webserver gibts doch extra den einzigartigen "24/7-Reebotservice mit 15 Minuten Reaktionszeit".
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Moin!
Test unter http://fastix.dyndns.org/shell/
(Absichtlich kein Link! Quelltexte an Ort und Stelle.)
Test unter http://fastix.dyndns.org/test/shell/
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
echo $begrüßung;
Hast du mal probiert, ob das auch funktioniert/stimmt?
Extra für Dich habe ich das jetzt gemacht. Ich nehme richtig an, Du hast es nicht hinbekommen?
Ja, ich habe es nicht hinbekommen. Jedenfalls nicht so, dass das Shellscript sich von PHP abgekoppelt hat. Es lief zwar los, jedoch blieb dabei auch das PHP-Script stehen und wartete auf die Beendigung des Prozesses. Ein »von der aktuellen Shell "abgehangen" im Hintergrund ausgeführt« konnte ich nicht erkennen.
Test unter http://fastix.dyndns.org/shell/
Das von dir verwendete Shellscript ist ja sofort wieder beendet. Damit sehe ich es als ungeeignet an, eine Ausführung im Hintergrund zu testen bzw. nachzuweisen.
Mein test.sh sah so aus:
#!/bin/bash
cd /tmp
while true
do
date >> test.dat
sleep 2s
done
Der Aufruf erfolgte überein:
echo system('./test.sh 2> /tmp/error &');
Mit einem
tail -f /tmp/test.dat
sah ich, dass es vor sich hin lief. Erst nach der gewaltsamen Beendigung des Endlosschleifen-Scripts mittels
killall test.sh
lief dann auch das PHP-Script weiter.
echo "$verabschiedung $name";
Moin!
fastix@trainer:/www/test/shell2> php < index.php
Content-type: text/html
X-Powered-By: PHP/4.3.3
<p>starte</p><p>fertig</p>fastix@trainer:/www/test/shell2>
fastix@trainer:/www/test/shell2> ps ax | grep test
10922 pts/17 S 0:00 /bin/sh ./test.sh
10968 pts/17 R 0:00 grep test
fastix@trainer:/www/test/shell2>
index.php:
<?php
echo "<p>starte</p>";
$dummy=./test.sh >logfile 2>errors &
;
echo "<p>fertig</p>";
echo $dummy;
?>
test.sh
#!/bin/sh
while true
do
date
sleep 1
done
Der Unterschied ist lediglich, dass stdout sofort umgeleitet wird. Dann wartet Dein Skript nicht auf irgendwas...
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Moin!
Der Unterschied ist lediglich, dass stdout sofort umgeleitet wird. Dann wartet Dein Skript nicht auf irgendwas...
Ganz genau genommen besteht der Unterschied darin, dass Dein Skript brav auf die Beendigung der Rückgaben gewartet hat. Leitest Du stdout um, dann bekommt es sofort ein EOT (End Of Transmission) gesendet und rackert weiter, während der angestoßene Prozess im Hintergrund weiterläuft.
Gut, dass Du mir mal Anlass gabst, die Theorie praktisch zu betätigen: Denn: Soweit zum Thema "Mein Provider bietet mir keine Chronjobs" :)))
Natürlich muss man immer mal überprüfen, ob der Job noch läuft. Das geht aber mit
if (ps ax| grep /verz/verz/plapla.sh | wc-l
< 2) {
$dummy=/verz/verz/plapla.sh > plapla.log 2> plapla.errors
}
Jetzt muss plapla nur noch gut genug programmiert sein um nicht zuviel Systemlast zu fressen und Prozesse in geeigneten Abständen zu starten. 'sleep' und 'date' liefern echt praktische Dinge...
(Den else- Zweig oder wie man zuviele solche Prozesse stoppt liefere ich gegen viel Bargeld :))))
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
echo $begrüßung;
Ganz genau genommen besteht der Unterschied darin, dass Dein Skript brav auf die Beendigung der Rückgaben gewartet hat. Leitest Du stdout um, dann bekommt es sofort ein EOT (End Of Transmission) gesendet und rackert weiter, während der angestoßene Prozess im Hintergrund weiterläuft.
Gut, eine nicht beachtete stdout-Umleitung wird wohl auch meinen Test vor einiger Zeit mit einem negativen Ergebnis beendet haben. Deswegen meine skeptische Nachfrage.
Dieses Problem scheint auch nicht mehr zu existieren (4.3.11 und 5.0.4). Ein mit set_time_limit(5) gestartetes und 99.x% Prozessorlast erzeugendes while true;do true;done wurde bei mir jedenfalls nicht in absehbarer Zeit beendet.
echo "$verabschiedung $name";
Moin!
... bewirkt, dass das Shellskript von der aktuellen Shell "abgehangen" im Hintergrund ausgeführt
Hast du mal probiert, ob das auch funktioniert/stimmt?
Falls Du das "abhängen" meinst:
fastix@trainer:~> firefox &
[1] 9685
fastix@trainer:~>
... firefox startet
... ich schließe die Konsole
... firefox lebt noch
Das gleiche passiert wenn ich mich auf einer echten Konsole einlogge und dann:
fastix@trainer:~> export DISPLAY=localhost:0
fastix@trainer:~> firefox &
[1] 9697
fastix@trainer:~> exit
... Damit ist die login-Shell beendet
Mit [ALT]+[F7] zurück: Er lebt noch.
Merke: Mit einem angehangenem '&' hängt man Prozesse vom aktuellen Prozess (z.B. shell) ab. Der Tot der shell oder des Elternprozesses reisst den Kindprozess nicht mehr in den ekletrektischen Tot.
Ich habe das _nicht_ _einmal sondern etliche Male zwar nicht _probiert_ aber _angewendet_.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®