• Aktualisierte Forenregeln

    Eine kleine Änderung hat es im Bereich Forenregeln unter Abschnitt 2 gegeben, wo wir nun explizit darauf verweisen, dass Forenkommentare in unserer Heftrubrik Leserbriefe landen können.

    Forenregeln


    Vielen Dank

PHP-Script - Problem

J

Jonny83

Gast
Ich hab in PHP ein Script geschrieben, dass den gesamten Inhalt eines FTP-Servers (die Dateien mit Größe) ausliest, um später das ganze in eine MySQL Datenbank zu schreiben. Hier mal das Script - ohne Verbindungsaufbau zum FTP/ zu MySQL, nur der Teil, der die Daten ausliest (MySQL wird noch nicht genuzt):

function read($dir) {
set_time_limit(15);
$file_array = ftp_rawlist($GLOBALS[ftp_connection], $dir);
foreach($file_array as $row) {
$row = split_unix($row);
echo $row[0]." ".$row[1]." ".$dir.$row[2]."<br>\n";
$GLOBALS[ i ]++;
if($row[0] == "dir") {
read($dir.$row[2].'/');
}
}
}
read('/');

Die Funktion split_unix($row) dient nur dazu, die ausgabe von ftp_rawlist() brauchbar zu machen. Ergebnis ist ein array, dass den typ (file/ dir), die größe und den dateinamen der aktuellen Zeile enthält.

Jetzt aber zum Problem: Wenn ich das Script ausführe, läuft es erstmal ohne Probleme, aber: bei jeder Verzeichnis-Abfrage wird anscheinend eine neue Verbindung zum FTP aufgebaut, was dazu führt, dass der FTP-Server irgendwann mit der Fehlermeldung "425 Can't open data connection" nicht mehr weiter "kann". Mit "netstat" (in der Win-Konsole) sieht man dann auch, dass ewig viele Verbindung zum ftp-data Port bestehen. Das PHP-Script bricht dann nach 15 sek. mit "Fatal error: Maximum execution time of 15 secounds exceeded in ...." (weils halt nicht mehr weiter geht).

Nur was kann ich dagegen machen? Wie könnte ich des ganze sonst realisieren? Bin für jeden gut gemeinten Rat dankbar.
 
Besorg dir im Netz die FTP-Spezifikationen und sende die Befehle direkt an den Server, statt die PHP-Funktionen dafür zu benutzen. Das erfordert zwar etwas Einarbeitung, aber damit brauchst du die Verbindung dann nur noch einmal aufzubauen.

Siehe auch: http://de.php.net/function.fsockopen
 
Arokh am 16.08.2004 19:42 schrieb:
Besorg dir im Netz die FTP-Spezifikationen und sende die Befehle direkt an den Server, statt die PHP-Funktionen dafür zu benutzen. Das erfordert zwar etwas Einarbeitung, aber damit brauchst du die Verbindung dann nur noch einmal aufzubauen.

Siehe auch: http://de.php.net/function.fsockopen

Eine aktive FTP-Verbindung funktioniert aber mit PHP so nicht, oder täusch ich mich da?

Die Steuerverbindung von PHP zu Port 21 des FTPd und des Login ist ja kein Problem, aber wie mach ich's mit der Datenverbindung? Ich muss dem FTPd über den PORT-Befehl einen Port übergeben, auf den er zu mir eine Daten-Verbindung aufbaut - nur müsste PHP dazu auf dem angegebenen Port "horchen" und die Verbindung annehmen - ich hab aber keinen PHP-Befehl gefunden, der das könnte. fsockopen kann ja nur eine Verbindung herstellen.
Somit müsste ich passives FTP verwenden - wo mir der FTPd jedes mal vor einer Datenanfrage einen Port gibt, auf den ich per PHP verbinden muss - wäre sogesehen wieder am anfang...
 
<?php
$ftp = array("host" => "",
"port" => "21",
"user" => "",
"pwd" => "",
"conn" => "",
"login" => ""
);
$ftp["conn"] = ftp_connect($ftp["host"],$ftp["port"]);
$ftp["login"] = ftp_login($ftp["conn"],$ftp["user"],$ftp["pwd"]);
/* Soweit klar glaube ich - Verbindung nur einmal aufbauen und der Funktion uebergeben */

function read($dir,$conn) {
$list = ftp_rawlist($conn,$dir); // Liste holen
foreach($list as $row) {
$row = array_unique(explode(" ",$row)); /* an Leerzeichen trennen, leere Array Eintraege werden entfernt (manchmal 1, manchmal mehrere Leerzeichen vorher) */
// Hier steht das Array mit den Daten zur Verfuegung
if($row[0] == "dir") {
read($dir.$row[2].'/');
}
}
}

read("/",$ftp["conn"]);
?>

so war das bei mir kein problem
 
marky68 am 17.08.2004 18:22 schrieb:
<?php
$ftp = array("host" => "",
"port" => "21",
"user" => "",
"pwd" => "",
"conn" => "",
"login" => ""
);
$ftp["conn"] = ftp_connect($ftp["host"],$ftp["port"]);
$ftp["login"] = ftp_login($ftp["conn"],$ftp["user"],$ftp["pwd"]);
/* Soweit klar glaube ich - Verbindung nur einmal aufbauen und der Funktion uebergeben */

function read($dir,$conn) {
$list = ftp_rawlist($conn,$dir); // Liste holen
foreach($list as $row) {
$row = array_unique(explode(" ",$row)); /* an Leerzeichen trennen, leere Array Eintraege werden entfernt (manchmal 1, manchmal mehrere Leerzeichen vorher) */
// Hier steht das Array mit den Daten zur Verfuegung
if($row[0] == "dir") {
read($dir.$row[2].'/');
}
}
}

read("/",$ftp["conn"]);
?>

so war das bei mir kein problem

Mit welchen Datenmengen hast du das Skript getestet? Mein Skript funktioniert ja auch - nur nach ca. 50.000 Dateien/ Verzeichnissen bekomm ich vom FTPd die Fehlermeldung "425 Can't open data connection", es geht nichts mehr weiter und das PHP-Skript bricht dann nach der TimeOut Zeit ab.

Das Problem wo ich seh ist, dass PHP vor jedem LIST Befehl den PORT-Befehl ausführt - also der FTPd zu PHP eine neue Datenverbindung aufbaut. Die Steuerverbindung bleibt währendessen weiter bestehen. Irgendwann wirds dann anscheinend mit den Ports knapp...

Nur wie kann ich da was machen? Problem ist eben, dass ich einen sehr großen Datenbestand aufnehmen will.

edit: Was Arokh gemeint hat, könnte evtl. ein Lösungsansatz sein, nur weiß ich noch nicht, ob ich nach dem PORT Befehl mehrere LIST-Befehle auf dem gleichen Daten-Kanal ausführen kann. Außerdem weiß ich noch nicht, wie ich den Datenkanal überhaupt aufbauen kann, weil dazu ja PHP auf einen Port auf eine Verbindung vom FTPd warten müsste.
 
Zurück